diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-07-12 23:01:43 +0200 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-07-12 23:01:43 +0200 |
commit | 052073c36d33089d3a99992840c88c6245461813 (patch) | |
tree | 1689458244df3e4671343112cfbd71aad558aad8 /libssh | |
parent | 60c778ad7fa198ad0bf6f5a718a69623134c825c (diff) | |
download | libssh-052073c36d33089d3a99992840c88c6245461813.tar.gz libssh-052073c36d33089d3a99992840c88c6245461813.tar.xz libssh-052073c36d33089d3a99992840c88c6245461813.zip |
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
Diffstat (limited to 'libssh')
-rw-r--r-- | libssh/connect.c | 56 | ||||
-rw-r--r-- | libssh/init.c | 3 |
2 files changed, 55 insertions, 4 deletions
diff --git a/libssh/connect.c b/libssh/connect.c index f7843238..4720b9fd 100644 --- a/libssh/connect.c +++ b/libssh/connect.c @@ -56,6 +56,13 @@ #error "Your system must have getaddrinfo()" #endif +/* don't declare gnu extended regexp's */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE +#endif +#include <regex.h> + + #ifdef _WIN32 static void sock_set_nonblocking(socket_t sock) { u_long nonblocking = 1; @@ -87,7 +94,43 @@ static void sock_set_blocking(socket_t sock) { } #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; struct addrinfo hints; char s_port[10]; @@ -103,8 +146,13 @@ static int getai(const char *host, int port, struct addrinfo **ai) { } else { snprintf(s_port, sizeof(s_port), "%hu", 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); } @@ -183,7 +231,7 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host, enter_function(); - rc = getai(host, port, &ai); + rc = getai(session,host, port, &ai); if (rc != 0) { ssh_set_error(session, SSH_FATAL, "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); - rc = getai(host, 0, &bind_ai); + rc = getai(session,host, 0, &bind_ai); if (rc != 0) { ssh_set_error(session, SSH_FATAL, "Failed to resolve bind address %s (%s)", diff --git a/libssh/init.c b/libssh/init.c index 8d2ae032..1969d45e 100644 --- a/libssh/init.c +++ b/libssh/init.c @@ -43,6 +43,8 @@ int ssh_init(void) { return -1; if(ssh_socket_init()) return -1; + if(ssh_regex_init()) + return -1; return 0; } @@ -56,6 +58,7 @@ int ssh_init(void) { @returns 0 otherwise */ int ssh_finalize(void) { + ssh_regex_finalize(); ssh_crypto_finalize(); #ifdef HAVE_LIBGCRYPT gcry_control(GCRYCTL_TERM_SECMEM); |