summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <>2004-03-31 23:17:08 +0000
committerdjm <>2004-03-31 23:17:08 +0000
commite41f47e1fd54f7708fcf4d55a7b58281016203c1 (patch)
treeafcd45ff2204f031a2c76bca1b3877a98313a3e3
parentc051a3c4a24fa90cc755059f99d5c2e7131d5ca7 (diff)
downloadopenbsd-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.h4
-rw-r--r--src/lib/libssl/src/apps/s_client.c16
-rw-r--r--src/lib/libssl/src/apps/s_socket.c121
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
155int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); 155int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
156#endif 156#endif
157int init_client(int *sock, char *server, int port); 157int init_client(int *sock, char *server, char *port, int af);
158int should_retry(int i); 158int should_retry(int i);
159int extract_port(char *str, short *port_ptr); 159int extract_port(char *str, short *port_ptr);
160int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); 160int extract_host_port(char *str,char **host_ptr,unsigned char *ip,char **p);
161 161
162long MS_CALLBACK bio_dump_cb(BIO *bio, int cmd, const char *argp, 162long 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
525re_start: 531re_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);
86static void ssl_sock_cleanup(void); 86static void ssl_sock_cleanup(void);
87#endif 87#endif
88static int ssl_sock_init(void); 88static int ssl_sock_init(void);
89static int init_client_ip(int *sock,unsigned char ip[4], int port);
90static int init_server(int *sock, int port); 89static int init_server(int *sock, int port);
91static int init_server_long(int *sock, int port,char *ip); 90static int init_server_long(int *sock, int port,char *ip);
92static int do_accept(int acc_sock, int *sock, char **host); 91static int do_accept(int acc_sock, int *sock, char **host);
93static 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
188int init_client(int *sock, char *host, int port) 186int 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
201static 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
234int do_server(int port, int *ret, int (*cb)(), char *context) 223int do_server(int port, int *ret, int (*cb)(), char *context)
@@ -410,12 +399,13 @@ end:
410 } 399 }
411 400
412int extract_host_port(char *str, char **host_ptr, unsigned char *ip, 401int 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);
433err:
434 return(0);
435 }
436 420
437static 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);
479err: 422err:
480 return(0); 423 return(0);