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

Reply via email to