Hello, This patch implements request for ticket 2578. I've also created pull request in github that you can find here: https://github.com/openssl/openssl/pull/108
Kris
>From 853496476dd838958f438bd66df5725d3075de8e Mon Sep 17 00:00:00 2001 From: flowher <krzys...@leeds.pl> Date: Wed, 14 May 2014 22:25:39 +0200 Subject: [PATCH 1/3] Possibility to bind to specific local IP in s_client --- apps/s_apps.h | 2 +- apps/s_client.c | 9 ++++++++- apps/s_socket.c | 23 ++++++++++++++++++++--- crypto/objects/obj_xref.h | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/apps/s_apps.h b/apps/s_apps.h index 9d16e45..55225fa 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -168,7 +168,7 @@ int ssl_print_point_formats(BIO *out, SSL *s); int ssl_print_curves(BIO *out, SSL *s, int noshared); #endif int ssl_print_tmp_key(BIO *out, SSL *s); -int init_client(int *sock, const char *server, int port, int type); +int init_client(int *sock, char *server, int port, int type, char* localip); #ifndef NO_SYS_UN_H int init_client_unix(int *sock, const char *server); #endif diff --git a/apps/s_client.c b/apps/s_client.c index eee0e2e..da41854 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -324,6 +324,7 @@ static void sc_usage(void) BIO_printf(bio_err," -host host - use -connect instead\n"); BIO_printf(bio_err," -port port - use -connect instead\n"); BIO_printf(bio_err," -connect host:port - connect over TCP/IP (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); + BIO_printf(bio_err," -localip arg - specify local address to use\n"); BIO_printf(bio_err," -unix path - connect over unix domain sockets\n"); BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); @@ -628,6 +629,7 @@ int MAIN(int argc, char **argv) short port=PORT; int full_log=1; char *host=SSL_HOST_NAME; + char *localip=NULL; const char *unix_path = NULL; char *xmpphost = NULL; char *cert_file=NULL,*key_file=NULL,*chain_file=NULL; @@ -762,6 +764,11 @@ static char *jpake_secret = NULL; if (!extract_host_port(*(++argv),&host,NULL,&port)) goto bad; } + else if (strcmp(*argv,"-localip") == 0) + { + if (--argc < 1) goto bad; + localip=*(++argv); + } else if (strcmp(*argv,"-unix") == 0) { if (--argc < 1) goto bad; @@ -1511,7 +1518,7 @@ bad: re_start: - if ((!unix_path && (init_client(&s,host,port,socket_type) == 0)) || + if ((!unix_path && (init_client(&s,host,port,socket_type,localip) == 0)) || (unix_path && (init_client_unix(&s,unix_path) == 0))) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); diff --git a/apps/s_socket.c b/apps/s_socket.c index e83baf4..8fe6967 100644 --- a/apps/s_socket.c +++ b/apps/s_socket.c @@ -97,7 +97,7 @@ static void ssl_sock_cleanup(void); #endif static int ssl_sock_init(void); static int init_client_ip(int *sock, const unsigned char ip[4], int port, - int type); + int type, char* localip); static int init_server(int *sock, int port, int type); static int init_server_long(int *sock, int port,char *ip, int type); static int do_accept(int acc_sock, int *sock, char **host); @@ -233,14 +233,14 @@ static int ssl_sock_init(void) return(1); } -int init_client(int *sock, const char *host, int port, int type) +int init_client(int *sock, const char *host, int port, int type, char *localip) { unsigned char ip[4]; ip[0] = ip[1] = ip[2] = ip[3] = 0; if (!host_ip(host,&(ip[0]))) return 0; - return init_client_ip(sock,ip,port,type); + return init_client_ip(sock,ip,port,type,localip); } static int init_client_ip(int *sock, const unsigned char ip[4], int port, @@ -277,7 +277,24 @@ static int init_client_ip(int *sock, const unsigned char ip[4], int port, if (i < 0) { closesocket(s); perror("keepalive"); return(0); } } #endif + if(NULL!=localip) + { + struct sockaddr_in me; + memset((char*)&me,0,sizeof(me)); + me.sin_family = AF_INET; + /* inet_addr because it seems to be more portable than inet_aton */ + me.sin_addr.s_addr = inet_addr(localip); + if( me.sin_addr.s_addr == INADDR_NONE ) + { + BIO_printf(bio_err,"Wrong format of local IP address: %s\n",localip); + closesocket(s); + perror("inet_addr"); + return(0); + } + if( bind(s,(struct sockaddr *)&me,sizeof(me)) == -1 ) + { closesocket(s); perror("bind"); return(0); } + } if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) { closesocket(s); perror("connect"); return(0); } *sock=s; diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h index cfd628a..2b3dc6d 100644 --- a/crypto/objects/obj_xref.h +++ b/crypto/objects/obj_xref.h @@ -54,8 +54,8 @@ static const nid_triple sigoid_srt[] = static const nid_triple * const sigoid_srt_xref[] = { &sigoid_srt[29], - &sigoid_srt[17], &sigoid_srt[18], + &sigoid_srt[17], &sigoid_srt[0], &sigoid_srt[1], &sigoid_srt[7], -- 1.8.3.1 >From a06d75a27fcfa6549f887fe0017662749abc23ca Mon Sep 17 00:00:00 2001 From: Krzysztof Kwiatkowski <krzys...@leeds.pl> Date: Sun, 18 May 2014 12:28:42 +0200 Subject: [PATCH 2/3] Possibility to bind to local IP in s_client: don't use inet_addr --- apps/s_apps.h | 2 +- apps/s_client.c | 2 +- apps/s_socket.c | 51 +++++++++++++++++++++++++---------------------- crypto/objects/obj_xref.h | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/apps/s_apps.h b/apps/s_apps.h index 55225fa..1edbed8 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -168,7 +168,7 @@ int ssl_print_point_formats(BIO *out, SSL *s); int ssl_print_curves(BIO *out, SSL *s, int noshared); #endif int ssl_print_tmp_key(BIO *out, SSL *s); -int init_client(int *sock, char *server, int port, int type, char* localip); +int init_client(int *sock, const char *remote_host, int port, const char* local_host, int type); #ifndef NO_SYS_UN_H int init_client_unix(int *sock, const char *server); #endif diff --git a/apps/s_client.c b/apps/s_client.c index da41854..0e06343 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1518,7 +1518,7 @@ bad: re_start: - if ((!unix_path && (init_client(&s,host,port,socket_type,localip) == 0)) || + if ((!unix_path && (init_client(&s,host,port,localip,socket_type) == 0)) || (unix_path && (init_client_unix(&s,unix_path) == 0))) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); diff --git a/apps/s_socket.c b/apps/s_socket.c index 8fe6967..dc09e3d 100644 --- a/apps/s_socket.c +++ b/apps/s_socket.c @@ -96,8 +96,8 @@ static struct hostent *GetHostByName(const char *name); static void ssl_sock_cleanup(void); #endif static int ssl_sock_init(void); -static int init_client_ip(int *sock, const unsigned char ip[4], int port, - int type, char* localip); +static int init_client_ip(int *sock, const unsigned char remote_ip[4], int port, + const unsigned char local_ip[4], int type); static int init_server(int *sock, int port, int type); static int init_server_long(int *sock, int port,char *ip, int type); static int do_accept(int acc_sock, int *sock, char **host); @@ -233,18 +233,24 @@ static int ssl_sock_init(void) return(1); } -int init_client(int *sock, const char *host, int port, int type, char *localip) +int init_client(int *sock, const char *remote_host, int port, const char *local_host, int type) { - unsigned char ip[4]; + unsigned char remote_ip[4]; + unsigned char local_ip[4]; - ip[0] = ip[1] = ip[2] = ip[3] = 0; - if (!host_ip(host,&(ip[0]))) + remote_ip[0] = remote_ip[1] = remote_ip[2] = remote_ip[3] = 0; + if (!host_ip(remote_host,&(remote_ip[0]))) return 0; - return init_client_ip(sock,ip,port,type,localip); + + local_ip[0] = local_ip[1] = local_ip[2] = local_ip[3] = 0; + if (local_host!=NULL && !host_ip(local_host,&(local_ip[0]))) + return 0; + + return init_client_ip(sock,remote_ip,port,local_ip,type); } -static int init_client_ip(int *sock, const unsigned char ip[4], int port, - int type) +static int init_client_ip(int *sock, const unsigned char remote_ip[4], int port, + const unsigned char local_ip[4], int type) { unsigned long addr; struct sockaddr_in them; @@ -256,10 +262,10 @@ static int init_client_ip(int *sock, const unsigned char ip[4], int port, them.sin_family=AF_INET; them.sin_port=htons((unsigned short)port); addr=(unsigned long) - ((unsigned long)ip[0]<<24L)| - ((unsigned long)ip[1]<<16L)| - ((unsigned long)ip[2]<< 8L)| - ((unsigned long)ip[3]); + ((unsigned long)remote_ip[0]<<24L)| + ((unsigned long)remote_ip[1]<<16L)| + ((unsigned long)remote_ip[2]<< 8L)| + ((unsigned long)remote_ip[3]); them.sin_addr.s_addr=htonl(addr); if (type == SOCK_STREAM) @@ -277,20 +283,17 @@ static int init_client_ip(int *sock, const unsigned char ip[4], int port, if (i < 0) { closesocket(s); perror("keepalive"); return(0); } } #endif - if(NULL!=localip) + if(0!=local_ip[0]) { struct sockaddr_in me; memset((char*)&me,0,sizeof(me)); me.sin_family = AF_INET; - /* inet_addr because it seems to be more portable than inet_aton */ - me.sin_addr.s_addr = inet_addr(localip); - if( me.sin_addr.s_addr == INADDR_NONE ) - { - BIO_printf(bio_err,"Wrong format of local IP address: %s\n",localip); - closesocket(s); - perror("inet_addr"); - return(0); - } + addr=(unsigned long) + ((unsigned long)local_ip[0]<<24L)| + ((unsigned long)local_ip[1]<<16L)| + ((unsigned long)local_ip[2]<< 8L)| + ((unsigned long)local_ip[3]); + me.sin_addr.s_addr = htonl(addr); if( bind(s,(struct sockaddr *)&me,sizeof(me)) == -1 ) { closesocket(s); perror("bind"); return(0); } @@ -673,7 +676,7 @@ static int host_ip(const char *str, unsigned char ip[4]) ip[3]=in[3]; } else - { /* do a gethostbyname */ + {/* do a gethostbyname */ struct hostent *he; if (!ssl_sock_init()) return(0); diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h index 2b3dc6d..cfd628a 100644 --- a/crypto/objects/obj_xref.h +++ b/crypto/objects/obj_xref.h @@ -54,8 +54,8 @@ static const nid_triple sigoid_srt[] = static const nid_triple * const sigoid_srt_xref[] = { &sigoid_srt[29], - &sigoid_srt[18], &sigoid_srt[17], + &sigoid_srt[18], &sigoid_srt[0], &sigoid_srt[1], &sigoid_srt[7], -- 1.8.3.1 >From df9f7d9675dde6f198260c285c509f509ab63cad Mon Sep 17 00:00:00 2001 From: Krzysztof Kwiatkowski <krzys...@leeds.pl> Date: Sun, 18 May 2014 12:38:57 +0200 Subject: [PATCH 3/3] Possibility to bind to local IP in s_client: align names of variables --- apps/s_client.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/s_client.c b/apps/s_client.c index 0e06343..fee9d11 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -628,8 +628,8 @@ int MAIN(int argc, char **argv) fd_set readfds,writefds; short port=PORT; int full_log=1; - char *host=SSL_HOST_NAME; - char *localip=NULL; + char *remote_host=SSL_HOST_NAME; + char *local_ip=NULL; const char *unix_path = NULL; char *xmpphost = NULL; char *cert_file=NULL,*key_file=NULL,*chain_file=NULL; @@ -750,7 +750,7 @@ static char *jpake_secret = NULL; if (strcmp(*argv,"-host") == 0) { if (--argc < 1) goto bad; - host= *(++argv); + remote_host= *(++argv); } else if (strcmp(*argv,"-port") == 0) { @@ -761,13 +761,13 @@ static char *jpake_secret = NULL; else if (strcmp(*argv,"-connect") == 0) { if (--argc < 1) goto bad; - if (!extract_host_port(*(++argv),&host,NULL,&port)) + if (!extract_host_port(*(++argv),&remote_host,NULL,&port)) goto bad; } else if (strcmp(*argv,"-localip") == 0) { if (--argc < 1) goto bad; - localip=*(++argv); + local_ip=*(++argv); } else if (strcmp(*argv,"-unix") == 0) { @@ -1506,7 +1506,7 @@ bad: if (con && (kctx = kssl_ctx_new()) != NULL) { SSL_set0_kssl_ctx(con, kctx); - kssl_ctx_setstring(kctx, KSSL_SERVER, host); + kssl_ctx_setstring(kctx, KSSL_SERVER, remote_host); } #endif /* OPENSSL_NO_KRB5 */ /* SSL_set_cipher_list(con,"RC4-MD5"); */ @@ -1518,7 +1518,7 @@ bad: re_start: - if ((!unix_path && (init_client(&s,host,port,localip,socket_type) == 0)) || + if ((!unix_path && (init_client(&s,remote_host,port,local_ip,socket_type) == 0)) || (unix_path && (init_client_unix(&s,unix_path) == 0))) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); @@ -1742,7 +1742,7 @@ SSL_set_tlsext_status_ids(con, ids); BIO_printf(sbio,"<stream:stream " "xmlns:stream='http://etherx.jabber.org/streams' " "xmlns='jabber:client' to='%s' version='1.0'>", xmpphost ? - xmpphost : host); + xmpphost : remote_host); seen = BIO_read(sbio,mbuf,BUFSIZZ); mbuf[seen] = 0; while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") && -- 1.8.3.1