1
1

Set correct hint when connecting to an IP address

libssh now uses a regular expression against destination
hostnames to match numerical IP addresses and set the
appropriate hint.

Patches also add init and finalize code to compile the regexp
Этот коммит содержится в:
Aris Adamantiadis 2009-07-12 23:01:43 +02:00
родитель 60c778ad7f
Коммит 052073c36d
3 изменённых файлов: 58 добавлений и 4 удалений

Просмотреть файл

@ -625,7 +625,10 @@ int packet_read(SSH_SESSION *session);
int packet_translate(SSH_SESSION *session); int packet_translate(SSH_SESSION *session);
int packet_wait(SSH_SESSION *session,int type,int blocking); int packet_wait(SSH_SESSION *session,int type,int blocking);
int packet_flush(SSH_SESSION *session, int enforce_blocking); int packet_flush(SSH_SESSION *session, int enforce_blocking);
/* connect.c */ /* connect.c */
int ssh_regex_init(void);
void ssh_regex_finalize(void);
SSH_SESSION *ssh_session_new(); SSH_SESSION *ssh_session_new();
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char
*bind_addr, int port, long timeout, long usec); *bind_addr, int port, long timeout, long usec);

Просмотреть файл

@ -56,6 +56,13 @@
#error "Your system must have getaddrinfo()" #error "Your system must have getaddrinfo()"
#endif #endif
/* don't declare gnu extended regexp's */
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE
#endif
#include <regex.h>
#ifdef _WIN32 #ifdef _WIN32
static void sock_set_nonblocking(socket_t sock) { static void sock_set_nonblocking(socket_t sock) {
u_long nonblocking = 1; u_long nonblocking = 1;
@ -87,7 +94,43 @@ static void sock_set_blocking(socket_t sock) {
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
static int getai(const char *host, int port, struct addrinfo **ai) {
static regex_t *ip_regex = NULL;
/** @internal
* @brief initializes and compile the regexp to be used for IP matching
* @returns -1 on error (and error message is set)
* @returns 0 on success
*/
int ssh_regex_init(){
if(ip_regex==NULL){
int err;
regex_t *regex=malloc(sizeof (regex_t));
ZERO_STRUCTP(regex);
err=regcomp(regex,"^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$",REG_EXTENDED | REG_NOSUB);
if(err != 0){
char buffer[128];
regerror(err,regex,buffer,sizeof(buffer));
fprintf(stderr,"Error while compiling regular expression : %s\n",buffer);
SAFE_FREE(regex);
return -1;
}
ip_regex=regex;
}
return 0;
}
/** @internal
* @brief clean up the IP regexp
*/
void ssh_regex_finalize(){
if(ip_regex){
regfree(ip_regex);
SAFE_FREE(ip_regex);
}
}
static int getai(SSH_SESSION *session, const char *host, int port, struct addrinfo **ai) {
const char *service = NULL; const char *service = NULL;
struct addrinfo hints; struct addrinfo hints;
char s_port[10]; char s_port[10];
@ -103,8 +146,13 @@ static int getai(const char *host, int port, struct addrinfo **ai) {
} else { } else {
snprintf(s_port, sizeof(s_port), "%hu", port); snprintf(s_port, sizeof(s_port), "%hu", port);
service = s_port; service = s_port;
hints.ai_flags=AI_NUMERICSERV;
}
if(regexec(ip_regex,host,0,NULL,0) == 0){
/* this is an IP address */
ssh_log(session,SSH_LOG_PACKET,"host %s matches an IP address",host);
hints.ai_flags |= AI_NUMERICHOST;
} }
return getaddrinfo(host, service, &hints, ai); return getaddrinfo(host, service, &hints, ai);
} }
@ -183,7 +231,7 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host,
enter_function(); enter_function();
rc = getai(host, port, &ai); rc = getai(session,host, port, &ai);
if (rc != 0) { if (rc != 0) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc)); "Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
@ -206,7 +254,7 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host,
ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr); ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr);
rc = getai(host, 0, &bind_ai); rc = getai(session,host, 0, &bind_ai);
if (rc != 0) { if (rc != 0) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Failed to resolve bind address %s (%s)", "Failed to resolve bind address %s (%s)",

Просмотреть файл

@ -43,6 +43,8 @@ int ssh_init(void) {
return -1; return -1;
if(ssh_socket_init()) if(ssh_socket_init())
return -1; return -1;
if(ssh_regex_init())
return -1;
return 0; return 0;
} }
@ -56,6 +58,7 @@ int ssh_init(void) {
@returns 0 otherwise @returns 0 otherwise
*/ */
int ssh_finalize(void) { int ssh_finalize(void) {
ssh_regex_finalize();
ssh_crypto_finalize(); ssh_crypto_finalize();
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
gcry_control(GCRYCTL_TERM_SECMEM); gcry_control(GCRYCTL_TERM_SECMEM);