diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_apps.h openssl-0.9.8b/apps/s_apps.h --- openssl-0.9.8b.orig/apps/s_apps.h 2006-07-11 16:14:29.000000000 +0200 +++ openssl-0.9.8b/apps/s_apps.h 2006-07-13 08:44:29.000000000 +0200 @@ -148,7 +148,7 @@ #define PORT_STR "4433" #define PROTOCOL "tcp" -int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); +int do_server(char *port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); #ifdef HEADER_X509_H int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); #endif @@ -156,10 +156,9 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); #endif -int init_client(int *sock, char *server, int port, int type); +int init_client(int *sock, char *server, char *port, int type); int should_retry(int i); -int extract_port(char *str, short *port_ptr); -int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); +int extract_host_port(char *str,char **host_ptr,char **port_ptr); long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret); diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_client.c openssl-0.9.8b/apps/s_client.c --- openssl-0.9.8b.orig/apps/s_client.c 2005-11-25 14:46:41.000000000 +0100 +++ openssl-0.9.8b/apps/s_client.c 2006-07-13 08:44:29.000000000 +0200 @@ -246,7 +246,7 @@ int cbuf_len,cbuf_off; int sbuf_len,sbuf_off; fd_set readfds,writefds; - short port=PORT; + char *port_str = PORT_STR; int full_log=1; char *host=SSL_HOST_NAME; char *cert_file=NULL,*key_file=NULL; @@ -330,13 +330,12 @@ else if (strcmp(*argv,"-port") == 0) { if (--argc < 1) goto bad; - port=atoi(*(++argv)); - if (port == 0) goto bad; + port_str= *(++argv); } else if (strcmp(*argv,"-connect") == 0) { if (--argc < 1) goto bad; - if (!extract_host_port(*(++argv),&host,NULL,&port)) + if (!extract_host_port(*(++argv),&host,&port_str)) goto bad; } else if (strcmp(*argv,"-verify") == 0) @@ -619,7 +618,7 @@ re_start: - if (init_client(&s,host,port,sock_type) == 0) + if (init_client(&s,host,port_str,sock_type) == 0) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); SHUTDOWN(s); diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_server.c openssl-0.9.8b/apps/s_server.c --- openssl-0.9.8b.orig/apps/s_server.c 2005-09-02 14:27:02.000000000 +0200 +++ openssl-0.9.8b/apps/s_server.c 2006-07-13 08:44:29.000000000 +0200 @@ -532,7 +532,7 @@ { X509_STORE *store = NULL; int vflags = 0; - short port=PORT; + char *port_str = PORT_STR; char *CApath=NULL,*CAfile=NULL; unsigned char *context = NULL; char *dhfile = NULL; @@ -597,8 +597,7 @@ (strcmp(*argv,"-accept") == 0)) { if (--argc < 1) goto bad; - if (!extract_port(*(++argv),&port)) - goto bad; + port_str= *(++argv); } else if (strcmp(*argv,"-verify") == 0) { @@ -1086,9 +1085,9 @@ BIO_printf(bio_s_out,"ACCEPT\n"); if (www) - do_server(port,sock_type,&accept_socket,www_body, context); + do_server(port_str,sock_type,&accept_socket,www_body, context); else - do_server(port,sock_type,&accept_socket,sv_body, context); + do_server(port_str,sock_type,&accept_socket,sv_body, context); print_stats(bio_s_out,ctx); ret=0; end: diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_socket.c openssl-0.9.8b/apps/s_socket.c --- openssl-0.9.8b.orig/apps/s_socket.c 2005-06-13 05:21:00.000000000 +0200 +++ openssl-0.9.8b/apps/s_socket.c 2006-07-13 08:44:29.000000000 +0200 @@ -96,9 +96,7 @@ static void ssl_sock_cleanup(void); #endif static int ssl_sock_init(void); -static int init_client_ip(int *sock,unsigned char ip[4], int port, 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 init_server(int *sock, char *port, int type); static int do_accept(int acc_sock, int *sock, char **host); static int host_ip(char *str, unsigned char ip[4]); @@ -228,60 +226,69 @@ return(1); } -int init_client(int *sock, char *host, int port, int type) +int init_client(int *sock, char *host, char *port, int type) { - unsigned char ip[4]; - short p=0; - - if (!host_ip(host,&(ip[0]))) - { - return(0); - } - if (p != 0) port=p; - return(init_client_ip(sock,ip,port,type)); - } - -static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) - { - unsigned long addr; - struct sockaddr_in them; - int s,i; + struct addrinfo *res, *res0, hints; + char * failed_call = NULL; + int s; + int e; if (!ssl_sock_init()) return(0); - memset((char *)&them,0,sizeof(them)); - 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]); - them.sin_addr.s_addr=htonl(addr); - - if (type == SOCK_STREAM) - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); - else /* ( type == SOCK_DGRAM) */ - s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); - - if (s == INVALID_SOCKET) { perror("socket"); return(0); } + memset(&hints, '\0', sizeof(hints)); + hints.ai_socktype = type; + hints.ai_flags = AI_ADDRCONFIG; + + e = getaddrinfo(host, port, &hints, &res); + if (e) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); + if (e == EAI_SYSTEM) + perror("getaddrinfo"); + return (0); + } + res0 = res; + while (res) + { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == INVALID_SOCKET) + { + failed_call = "socket"; + goto nextres; + } #ifndef OPENSSL_SYS_MPE if (type == SOCK_STREAM) { - i=0; - i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); - if (i < 0) { perror("keepalive"); return(0); } + int i=0; + i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE, + (char *)&i,sizeof(i)); + if (i < 0) { + failed_call = "keepalive"; + goto nextres; + } } #endif - - if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) - { close(s); perror("connect"); return(0); } + if (connect(s,(struct sockaddr *)res->ai_addr, + res->ai_addrlen) == 0) + { + freeaddrinfo(res0); *sock=s; return(1); } + failed_call = "socket"; +nextres: + if (s != INVALID_SOCKET) + close(s); + res = res->ai_next; + } + freeaddrinfo(res0); + + perror(failed_call); + return(0); + } -int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) +int do_server(char *port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) { int sock; char *name = NULL; @@ -319,33 +326,38 @@ } } -static int init_server_long(int *sock, int port, char *ip, int type) +static int init_server(int *sock, char *port, int type) { - int ret=0; - struct sockaddr_in server; - int s= -1,i; + struct addrinfo *res, *res0, hints; + char * failed_call = NULL; + char port_name[8]; + int s; + int e; if (!ssl_sock_init()) return(0); - memset((char *)&server,0,sizeof(server)); - server.sin_family=AF_INET; - server.sin_port=htons((unsigned short)port); - if (ip == NULL) - server.sin_addr.s_addr=INADDR_ANY; - else -/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ -#ifndef BIT_FIELD_LIMITS - memcpy(&server.sin_addr.s_addr,ip,4); -#else - memcpy(&server.sin_addr,ip,4); -#endif - - if (type == SOCK_STREAM) - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); - else /* type == SOCK_DGRAM */ - s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP); + memset(&hints, '\0', sizeof(hints)); + hints.ai_socktype = type; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + + e = getaddrinfo(NULL, port, &hints, &res); + if (e) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); + if (e == EAI_SYSTEM) + perror("getaddrinfo"); + return (0); + } - if (s == INVALID_SOCKET) goto err; + res0 = res; + while (res) + { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == INVALID_SOCKET) + { + failed_call = "socket"; + goto nextres; + } #if defined SOL_SOCKET && defined SO_REUSEADDR { int j = 1; @@ -353,36 +365,39 @@ (void *) &j, sizeof j); } #endif - if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) + + if (bind(s,(struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) { -#ifndef OPENSSL_SYS_WINDOWS - perror("bind"); -#endif - goto err; + failed_call = "bind"; + goto nextres; } - /* Make it 128 for linux */ - if (type==SOCK_STREAM && listen(s,128) == -1) goto err; - i=0; - *sock=s; - ret=1; -err: - if ((ret == 0) && (s != -1)) + if (type==SOCK_STREAM && listen(s,128) == -1) { - SHUTDOWN(s); + failed_call = "listen"; + goto nextres; } - return(ret); + + *sock=s; + return(1); + +nextres: + if (s != INVALID_SOCKET) + close(s); + res = res->ai_next; } + freeaddrinfo(res0); -static int init_server(int *sock, int port, int type) - { - return(init_server_long(sock, port, NULL, type)); + if (s == INVALID_SOCKET) { perror("socket"); return(0); } + + perror(failed_call); + return(0); } static int do_accept(int acc_sock, int *sock, char **host) { - int ret,i; - struct hostent *h1,*h2; - static struct sockaddr_in from; + static struct sockaddr_storage from; + char buffer[NI_MAXHOST]; + int ret; int len; /* struct linger ling; */ @@ -427,137 +442,62 @@ if (i < 0) { perror("keepalive"); return(0); } */ - if (host == NULL) goto end; -#ifndef BIT_FIELD_LIMITS - /* I should use WSAAsyncGetHostByName() under windows */ - h1=gethostbyaddr((char *)&from.sin_addr.s_addr, - sizeof(from.sin_addr.s_addr),AF_INET); -#else - h1=gethostbyaddr((char *)&from.sin_addr, - sizeof(struct in_addr),AF_INET); -#endif - if (h1 == NULL) + if (host == NULL) { - BIO_printf(bio_err,"bad gethostbyaddr\n"); - *host=NULL; - /* return(0); */ - } - else - { - if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL) - { - perror("OPENSSL_malloc"); + *sock=ret; return(0); } - BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1); - h2=GetHostByName(*host); - if (h2 == NULL) + if (getnameinfo((struct sockaddr *)&from, sizeof(from), + buffer, sizeof(buffer), + NULL, 0, 0)) { - BIO_printf(bio_err,"gethostbyname failure\n"); + BIO_printf(bio_err,"getnameinfo failed\n"); + *host=NULL; return(0); } - i=0; - if (h2->h_addrtype != AF_INET) + else { - BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); + if ((*host=(char *)OPENSSL_malloc(strlen(buffer)+1)) == NULL) + { + perror("OPENSSL_malloc"); return(0); } - } -end: + strcpy(*host, buffer); *sock=ret; return(1); } + } -int extract_host_port(char *str, char **host_ptr, unsigned char *ip, - short *port_ptr) +int extract_host_port(char *str, char **host_ptr, + char **port_ptr) { - char *h,*p; + char *h,*p,*x; - h=str; - p=strchr(str,':'); + x=h=str; + if (*h == '[') + { + h++; + p=strchr(h,']'); if (p == NULL) { - BIO_printf(bio_err,"no port defined\n"); + BIO_printf(bio_err,"no ending bracket for IPv6 address\n"); return(0); } *(p++)='\0'; - - if ((ip != NULL) && !host_ip(str,ip)) - goto err; - if (host_ptr != NULL) *host_ptr=h; - - if (!extract_port(p,port_ptr)) - goto err; - return(1); -err: - return(0); + x = p; } - -static int host_ip(char *str, unsigned char ip[4]) - { - unsigned int in[4]; - int i; - - if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4) - { - for (i=0; i<4; i++) - if (in[i] > 255) - { - BIO_printf(bio_err,"invalid IP address\n"); - goto err; - } - ip[0]=in[0]; - ip[1]=in[1]; - ip[2]=in[2]; - ip[3]=in[3]; - } - else - { /* do a gethostbyname */ - struct hostent *he; - - if (!ssl_sock_init()) return(0); - - he=GetHostByName(str); - if (he == NULL) - { - BIO_printf(bio_err,"gethostbyname failure\n"); - goto err; - } - /* cast to short because of win16 winsock definition */ - if ((short)he->h_addrtype != AF_INET) + p=strchr(x,':'); + if (p == NULL) { - BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); - return(0); - } - ip[0]=he->h_addr_list[0][0]; - ip[1]=he->h_addr_list[0][1]; - ip[2]=he->h_addr_list[0][2]; - ip[3]=he->h_addr_list[0][3]; - } - return(1); -err: + BIO_printf(bio_err,"no port defined\n"); return(0); } + *(p++)='\0'; -int extract_port(char *str, short *port_ptr) - { - int i; - struct servent *s; + if (host_ptr != NULL) *host_ptr=h; + if (port_ptr != NULL) *port_ptr=p; - i=atoi(str); - if (i != 0) - *port_ptr=(unsigned short)i; - else - { - s=getservbyname(str,"tcp"); - if (s == NULL) - { - BIO_printf(bio_err,"getservbyname failure for %s\n",str); - return(0); - } - *port_ptr=ntohs((unsigned short)s->s_port); - } return(1); }