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@
Diffstat (limited to '')
| -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); |
