diff options
author | djm <> | 2004-03-31 23:17:08 +0000 |
---|---|---|
committer | djm <> | 2004-03-31 23:17:08 +0000 |
commit | e41f47e1fd54f7708fcf4d55a7b58281016203c1 (patch) | |
tree | afcd45ff2204f031a2c76bca1b3877a98313a3e3 | |
parent | c051a3c4a24fa90cc755059f99d5c2e7131d5ca7 (diff) | |
download | openbsd-e41f47e1fd54f7708fcf4d55a7b58281016203c1.tar.gz openbsd-e41f47e1fd54f7708fcf4d55a7b58281016203c1.tar.bz2 openbsd-e41f47e1fd54f7708fcf4d55a7b58281016203c1.zip |
support IPv6 connections in "openssl s_client", adding -4 and -6 options to
force protocol; ok itojun@
-rw-r--r-- | src/lib/libssl/src/apps/s_apps.h | 4 | ||||
-rw-r--r-- | src/lib/libssl/src/apps/s_client.c | 16 | ||||
-rw-r--r-- | src/lib/libssl/src/apps/s_socket.c | 121 |
3 files changed, 45 insertions, 96 deletions
diff --git a/src/lib/libssl/src/apps/s_apps.h b/src/lib/libssl/src/apps/s_apps.h index 66b6edd442..48e7dbaddc 100644 --- a/src/lib/libssl/src/apps/s_apps.h +++ b/src/lib/libssl/src/apps/s_apps.h | |||
@@ -154,10 +154,10 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); | |||
154 | #ifdef HEADER_SSL_H | 154 | #ifdef HEADER_SSL_H |
155 | int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); | 155 | int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); |
156 | #endif | 156 | #endif |
157 | int init_client(int *sock, char *server, int port); | 157 | int init_client(int *sock, char *server, char *port, int af); |
158 | int should_retry(int i); | 158 | int should_retry(int i); |
159 | int extract_port(char *str, short *port_ptr); | 159 | int extract_port(char *str, short *port_ptr); |
160 | int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); | 160 | int extract_host_port(char *str,char **host_ptr,unsigned char *ip,char **p); |
161 | 161 | ||
162 | long MS_CALLBACK bio_dump_cb(BIO *bio, int cmd, const char *argp, | 162 | long MS_CALLBACK bio_dump_cb(BIO *bio, int cmd, const char *argp, |
163 | int argi, long argl, long ret); | 163 | int argi, long argl, long ret); |
diff --git a/src/lib/libssl/src/apps/s_client.c b/src/lib/libssl/src/apps/s_client.c index 1128735d49..ae7c9f9ede 100644 --- a/src/lib/libssl/src/apps/s_client.c +++ b/src/lib/libssl/src/apps/s_client.c | |||
@@ -109,6 +109,8 @@ | |||
109 | * | 109 | * |
110 | */ | 110 | */ |
111 | 111 | ||
112 | #include <sys/types.h> | ||
113 | #include <netinet/in.h> | ||
112 | #include <assert.h> | 114 | #include <assert.h> |
113 | #include <stdio.h> | 115 | #include <stdio.h> |
114 | #include <stdlib.h> | 116 | #include <stdlib.h> |
@@ -183,6 +185,8 @@ static void sc_usage(void) | |||
183 | { | 185 | { |
184 | BIO_printf(bio_err,"usage: s_client args\n"); | 186 | BIO_printf(bio_err,"usage: s_client args\n"); |
185 | BIO_printf(bio_err,"\n"); | 187 | BIO_printf(bio_err,"\n"); |
188 | BIO_printf(bio_err," -4 - Force IPv4\n"); | ||
189 | BIO_printf(bio_err," -6 - Force IPv6\n"); | ||
186 | BIO_printf(bio_err," -host host - use -connect instead\n"); | 190 | BIO_printf(bio_err," -host host - use -connect instead\n"); |
187 | BIO_printf(bio_err," -port port - use -connect instead\n"); | 191 | BIO_printf(bio_err," -port port - use -connect instead\n"); |
188 | BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); | 192 | BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); |
@@ -232,12 +236,12 @@ int MAIN(int argc, char **argv) | |||
232 | int off=0; | 236 | int off=0; |
233 | SSL *con=NULL,*con2=NULL; | 237 | SSL *con=NULL,*con2=NULL; |
234 | X509_STORE *store = NULL; | 238 | X509_STORE *store = NULL; |
235 | int s,k,width,state=0; | 239 | int s,k,width,state=0, af=AF_UNSPEC; |
236 | char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; | 240 | char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; |
237 | int cbuf_len,cbuf_off; | 241 | int cbuf_len,cbuf_off; |
238 | int sbuf_len,sbuf_off; | 242 | int sbuf_len,sbuf_off; |
239 | fd_set readfds,writefds; | 243 | fd_set readfds,writefds; |
240 | short port=PORT; | 244 | char *port=PORT_STR; |
241 | int full_log=1; | 245 | int full_log=1; |
242 | char *host=SSL_HOST_NAME; | 246 | char *host=SSL_HOST_NAME; |
243 | char *cert_file=NULL,*key_file=NULL; | 247 | char *cert_file=NULL,*key_file=NULL; |
@@ -308,8 +312,8 @@ int MAIN(int argc, char **argv) | |||
308 | else if (strcmp(*argv,"-port") == 0) | 312 | else if (strcmp(*argv,"-port") == 0) |
309 | { | 313 | { |
310 | if (--argc < 1) goto bad; | 314 | if (--argc < 1) goto bad; |
311 | port=atoi(*(++argv)); | 315 | port= *(++argv); |
312 | if (port == 0) goto bad; | 316 | if (port == NULL || *port == '\0') goto bad; |
313 | } | 317 | } |
314 | else if (strcmp(*argv,"-connect") == 0) | 318 | else if (strcmp(*argv,"-connect") == 0) |
315 | { | 319 | { |
@@ -429,6 +433,8 @@ int MAIN(int argc, char **argv) | |||
429 | if (--argc < 1) goto bad; | 433 | if (--argc < 1) goto bad; |
430 | inrand= *(++argv); | 434 | inrand= *(++argv); |
431 | } | 435 | } |
436 | else if (strcmp(*argv,"-4") == 0) { af = AF_INET;} | ||
437 | else if (strcmp(*argv,"-6") == 0) { af = AF_INET6;} | ||
432 | else | 438 | else |
433 | { | 439 | { |
434 | BIO_printf(bio_err,"unknown option %s\n",*argv); | 440 | BIO_printf(bio_err,"unknown option %s\n",*argv); |
@@ -524,7 +530,7 @@ bad: | |||
524 | 530 | ||
525 | re_start: | 531 | re_start: |
526 | 532 | ||
527 | if (init_client(&s,host,port) == 0) | 533 | if (init_client(&s,host,port,af) == 0) |
528 | { | 534 | { |
529 | BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); | 535 | BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); |
530 | SHUTDOWN(s); | 536 | SHUTDOWN(s); |
diff --git a/src/lib/libssl/src/apps/s_socket.c b/src/lib/libssl/src/apps/s_socket.c index 02c3f640cf..3b36d2dff8 100644 --- a/src/lib/libssl/src/apps/s_socket.c +++ b/src/lib/libssl/src/apps/s_socket.c | |||
@@ -86,11 +86,9 @@ static struct hostent *GetHostByName(char *name); | |||
86 | static void ssl_sock_cleanup(void); | 86 | static void ssl_sock_cleanup(void); |
87 | #endif | 87 | #endif |
88 | static int ssl_sock_init(void); | 88 | static int ssl_sock_init(void); |
89 | static int init_client_ip(int *sock,unsigned char ip[4], int port); | ||
90 | static int init_server(int *sock, int port); | 89 | static int init_server(int *sock, int port); |
91 | static int init_server_long(int *sock, int port,char *ip); | 90 | static int init_server_long(int *sock, int port,char *ip); |
92 | static int do_accept(int acc_sock, int *sock, char **host); | 91 | static int do_accept(int acc_sock, int *sock, char **host); |
93 | static int host_ip(char *str, unsigned char ip[4]); | ||
94 | 92 | ||
95 | #ifdef OPENSSL_SYS_WIN16 | 93 | #ifdef OPENSSL_SYS_WIN16 |
96 | #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ | 94 | #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ |
@@ -185,50 +183,41 @@ static int ssl_sock_init(void) | |||
185 | return(1); | 183 | return(1); |
186 | } | 184 | } |
187 | 185 | ||
188 | int init_client(int *sock, char *host, int port) | 186 | int init_client(int *sock, char *host, char *port, int af) |
189 | { | 187 | { |
190 | unsigned char ip[4]; | 188 | struct addrinfo hints, *ai_top, *ai; |
191 | short p=0; | 189 | int i, s; |
192 | 190 | ||
193 | if (!host_ip(host,&(ip[0]))) | 191 | memset(&hints, '\0', sizeof(hints)); |
192 | hints.ai_family = af; | ||
193 | hints.ai_socktype = SOCK_STREAM; | ||
194 | |||
195 | if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0 || | ||
196 | ai_top == NULL || ai_top->ai_addr == NULL) | ||
194 | { | 197 | { |
195 | return(0); | 198 | BIO_printf(bio_err,"getaddrinfo: %s\n", gai_strerror(i)); |
199 | return (0); | ||
196 | } | 200 | } |
197 | if (p != 0) port=p; | ||
198 | return(init_client_ip(sock,ip,port)); | ||
199 | } | ||
200 | |||
201 | static int init_client_ip(int *sock, unsigned char ip[4], int port) | ||
202 | { | ||
203 | unsigned long addr; | ||
204 | struct sockaddr_in them; | ||
205 | int s,i; | ||
206 | |||
207 | if (!ssl_sock_init()) return(0); | ||
208 | |||
209 | memset((char *)&them,0,sizeof(them)); | ||
210 | them.sin_family=AF_INET; | ||
211 | them.sin_port=htons((unsigned short)port); | ||
212 | addr=(unsigned long) | ||
213 | ((unsigned long)ip[0]<<24L)| | ||
214 | ((unsigned long)ip[1]<<16L)| | ||
215 | ((unsigned long)ip[2]<< 8L)| | ||
216 | ((unsigned long)ip[3]); | ||
217 | them.sin_addr.s_addr=htonl(addr); | ||
218 | |||
219 | s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); | ||
220 | if (s == INVALID_SOCKET) { perror("socket"); return(0); } | ||
221 | 201 | ||
202 | for (ai = ai_top; ai != NULL; ai = ai->ai_next) | ||
203 | { | ||
204 | s=socket(ai->ai_addr->sa_family, SOCK_STREAM, SOCKET_PROTOCOL); | ||
205 | if (s == INVALID_SOCKET) { continue; } | ||
222 | #ifndef OPENSSL_SYS_MPE | 206 | #ifndef OPENSSL_SYS_MPE |
223 | i=0; | 207 | i=0; |
224 | i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); | 208 | i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); |
225 | if (i < 0) { perror("keepalive"); return(0); } | 209 | if (i == -1) { close(s); continue; } |
226 | #endif | 210 | #endif |
211 | if ((i = connect(s, ai->ai_addr, ai->ai_addr->sa_len)) == 0) | ||
212 | { *sock=s; freeaddrinfo(ai_top); return (1);} | ||
227 | 213 | ||
228 | if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) | 214 | close(s); |
229 | { close(s); perror("connect"); return(0); } | 215 | } |
230 | *sock=s; | 216 | |
231 | return(1); | 217 | perror("connect"); |
218 | close(s); | ||
219 | freeaddrinfo(ai_top); | ||
220 | return(0); | ||
232 | } | 221 | } |
233 | 222 | ||
234 | int do_server(int port, int *ret, int (*cb)(), char *context) | 223 | int do_server(int port, int *ret, int (*cb)(), char *context) |
@@ -410,12 +399,13 @@ end: | |||
410 | } | 399 | } |
411 | 400 | ||
412 | int extract_host_port(char *str, char **host_ptr, unsigned char *ip, | 401 | int extract_host_port(char *str, char **host_ptr, unsigned char *ip, |
413 | short *port_ptr) | 402 | char **port_ptr) |
414 | { | 403 | { |
415 | char *h,*p; | 404 | char *h,*p; |
416 | 405 | ||
417 | h=str; | 406 | h=str; |
418 | p=strchr(str,':'); | 407 | p=strrchr(str,'/'); /* IPv6 host/port */ |
408 | if (p == NULL) { p=strrchr(str,':'); } | ||
419 | if (p == NULL) | 409 | if (p == NULL) |
420 | { | 410 | { |
421 | BIO_printf(bio_err,"no port defined\n"); | 411 | BIO_printf(bio_err,"no port defined\n"); |
@@ -423,58 +413,11 @@ int extract_host_port(char *str, char **host_ptr, unsigned char *ip, | |||
423 | } | 413 | } |
424 | *(p++)='\0'; | 414 | *(p++)='\0'; |
425 | 415 | ||
426 | if ((ip != NULL) && !host_ip(str,ip)) | ||
427 | goto err; | ||
428 | if (host_ptr != NULL) *host_ptr=h; | 416 | if (host_ptr != NULL) *host_ptr=h; |
429 | 417 | ||
430 | if (!extract_port(p,port_ptr)) | 418 | if (port_ptr != NULL && p != NULL && *p != '\0') |
431 | goto err; | 419 | *port_ptr = p; |
432 | return(1); | ||
433 | err: | ||
434 | return(0); | ||
435 | } | ||
436 | 420 | ||
437 | static int host_ip(char *str, unsigned char ip[4]) | ||
438 | { | ||
439 | unsigned int in[4]; | ||
440 | int i; | ||
441 | |||
442 | if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4) | ||
443 | { | ||
444 | for (i=0; i<4; i++) | ||
445 | if (in[i] > 255) | ||
446 | { | ||
447 | BIO_printf(bio_err,"invalid IP address\n"); | ||
448 | goto err; | ||
449 | } | ||
450 | ip[0]=in[0]; | ||
451 | ip[1]=in[1]; | ||
452 | ip[2]=in[2]; | ||
453 | ip[3]=in[3]; | ||
454 | } | ||
455 | else | ||
456 | { /* do a gethostbyname */ | ||
457 | struct hostent *he; | ||
458 | |||
459 | if (!ssl_sock_init()) return(0); | ||
460 | |||
461 | he=GetHostByName(str); | ||
462 | if (he == NULL) | ||
463 | { | ||
464 | BIO_printf(bio_err,"gethostbyname failure\n"); | ||
465 | goto err; | ||
466 | } | ||
467 | /* cast to short because of win16 winsock definition */ | ||
468 | if ((short)he->h_addrtype != AF_INET) | ||
469 | { | ||
470 | BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); | ||
471 | return(0); | ||
472 | } | ||
473 | ip[0]=he->h_addr_list[0][0]; | ||
474 | ip[1]=he->h_addr_list[0][1]; | ||
475 | ip[2]=he->h_addr_list[0][2]; | ||
476 | ip[3]=he->h_addr_list[0][3]; | ||
477 | } | ||
478 | return(1); | 421 | return(1); |
479 | err: | 422 | err: |
480 | return(0); | 423 | return(0); |