aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-07-12 23:01:43 +0200
committerAris Adamantiadis <aris@0xbadc0de.be>2009-07-12 23:01:43 +0200
commit052073c36d33089d3a99992840c88c6245461813 (patch)
tree1689458244df3e4671343112cfbd71aad558aad8 /libssh
parent60c778ad7fa198ad0bf6f5a718a69623134c825c (diff)
downloadlibssh-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.c56
-rw-r--r--libssh/init.c3
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);