5bdfc6c8e0abe6002c82a67dd068740eaa466b39
[openssl.git] / apps / s_socket.c
1 /*
2  * apps/s_socket.c - socket-related functions used by s_client and s_server
3  */
4 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5  * All rights reserved.
6  *
7  * This package is an SSL implementation written
8  * by Eric Young (eay@cryptsoft.com).
9  * The implementation was written so as to conform with Netscapes SSL.
10  *
11  * This library is free for commercial and non-commercial use as long as
12  * the following conditions are aheared to.  The following conditions
13  * apply to all code found in this distribution, be it the RC4, RSA,
14  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
15  * included with this distribution is covered by the same copyright terms
16  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17  *
18  * Copyright remains Eric Young's, and as such any Copyright notices in
19  * the code are not to be removed.
20  * If this package is used in a product, Eric Young should be given attribution
21  * as the author of the parts of the library used.
22  * This can be in the form of a textual message at program startup or
23  * in documentation (online or textual) provided with the package.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. All advertising materials mentioning features or use of this software
34  *    must display the following acknowledgement:
35  *    "This product includes cryptographic software written by
36  *     Eric Young (eay@cryptsoft.com)"
37  *    The word 'cryptographic' can be left out if the rouines from the library
38  *    being used are not cryptographic related :-).
39  * 4. If you include any Windows specific code (or a derivative thereof) from
40  *    the apps directory (application code) you must include an acknowledgement:
41  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
42  *
43  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  *
55  * The licence and distribution terms for any publically available version or
56  * derivative of this code cannot be changed.  i.e. this code cannot simply be
57  * copied and put under another distribution licence
58  * [including the GNU Public Licence.]
59  */
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <errno.h>
65 #include <signal.h>
66
67 /*
68  * With IPv6, it looks like Digital has mixed up the proper order of
69  * recursive header file inclusion, resulting in the compiler complaining
70  * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
71  * needed to have fileno() declared correctly...  So let's define u_int
72  */
73 #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
74 # define __U_INT
75 typedef unsigned int u_int;
76 #endif
77
78 #define USE_SOCKETS
79 #define NON_MAIN
80 #include "apps.h"
81 #undef USE_SOCKETS
82 #undef NON_MAIN
83 #include "s_apps.h"
84 #include <openssl/ssl.h>
85
86 #ifdef FLAT_INC
87 # include "e_os.h"
88 #else
89 # include "../e_os.h"
90 #endif
91
92 #ifndef OPENSSL_NO_SOCK
93
94 # if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
95 #  include "netdb.h"
96 # endif
97
98 static struct hostent *GetHostByName(const char *name);
99 # if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
100 static void ssl_sock_cleanup(void);
101 # endif
102 static int ssl_sock_init(void);
103 static int init_client_ip(int *sock, const unsigned char ip[4], int port,
104                           int type);
105 static int init_server(int *sock, int port, int type);
106 static int init_server_long(int *sock, int port, char *ip, int type);
107 static int do_accept(int acc_sock, int *sock, char **host);
108 static int host_ip(const char *str, unsigned char ip[4]);
109 # ifndef NO_SYS_UN_H
110 static int init_server_unix(int *sock, const char *path);
111 static int do_accept_unix(int acc_sock, int *sock);
112 # endif
113
114 # if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
115 static int wsa_init_done = 0;
116 # endif
117
118 # ifdef OPENSSL_SYS_WINDOWS
119 static struct WSAData wsa_state;
120 static int wsa_init_done = 0;
121
122 # endif                         /* OPENSSL_SYS_WINDOWS */
123
124 # ifdef OPENSSL_SYS_WINDOWS
125 static void ssl_sock_cleanup(void)
126 {
127     if (wsa_init_done) {
128         wsa_init_done = 0;
129 #  ifndef OPENSSL_SYS_WINCE
130         WSACancelBlockingCall();
131 #  endif
132         WSACleanup();
133     }
134 }
135 # elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
136 static void sock_cleanup(void)
137 {
138     if (wsa_init_done) {
139         wsa_init_done = 0;
140         WSACleanup();
141     }
142 }
143 # endif
144
145 static int ssl_sock_init(void)
146 {
147 # ifdef WATT32
148     extern int _watt_do_exit;
149     _watt_do_exit = 0;
150     if (sock_init())
151         return (0);
152 # elif defined(OPENSSL_SYS_WINDOWS)
153     if (!wsa_init_done) {
154         int err;
155
156 #  ifdef SIGINT
157         signal(SIGINT, (void (*)(int))ssl_sock_cleanup);
158 #  endif
159         wsa_init_done = 1;
160         memset(&wsa_state, 0, sizeof(wsa_state));
161         if (WSAStartup(0x0101, &wsa_state) != 0) {
162             err = WSAGetLastError();
163             BIO_printf(bio_err, "unable to start WINSOCK, error code=%d\n",
164                        err);
165             return (0);
166         }
167     }
168 # elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
169     WORD wVerReq;
170     WSADATA wsaData;
171     int err;
172
173     if (!wsa_init_done) {
174
175 #  ifdef SIGINT
176         signal(SIGINT, (void (*)(int))sock_cleanup);
177 #  endif
178
179         wsa_init_done = 1;
180         wVerReq = MAKEWORD(2, 0);
181         err = WSAStartup(wVerReq, &wsaData);
182         if (err != 0) {
183             BIO_printf(bio_err, "unable to start WINSOCK2, error code=%d\n",
184                        err);
185             return (0);
186         }
187     }
188 # endif                         /* OPENSSL_SYS_WINDOWS */
189     return (1);
190 }
191
192 int init_client(int *sock, const char *host, int port, int type)
193 {
194     unsigned char ip[4];
195
196     ip[0] = ip[1] = ip[2] = ip[3] = 0;
197     if (!host_ip(host, &(ip[0])))
198         return 0;
199     return init_client_ip(sock, ip, port, type);
200 }
201
202 static int init_client_ip(int *sock, const unsigned char ip[4], int port,
203                           int type)
204 {
205     unsigned long addr;
206     struct sockaddr_in them;
207     int s, i;
208
209     if (!ssl_sock_init())
210         return (0);
211
212     memset((char *)&them, 0, sizeof(them));
213     them.sin_family = AF_INET;
214     them.sin_port = htons((unsigned short)port);
215     addr = (unsigned long)
216         ((unsigned long)ip[0] << 24L) |
217         ((unsigned long)ip[1] << 16L) |
218         ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
219     them.sin_addr.s_addr = htonl(addr);
220
221     if (type == SOCK_STREAM)
222         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
223     else                        /* ( type == SOCK_DGRAM) */
224         s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
225
226     if (s == INVALID_SOCKET) {
227         perror("socket");
228         return (0);
229     }
230 # if defined(SO_KEEPALIVE)
231     if (type == SOCK_STREAM) {
232         i = 0;
233         i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i));
234         if (i < 0) {
235             closesocket(s);
236             perror("keepalive");
237             return (0);
238         }
239     }
240 # endif
241
242     if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) {
243         closesocket(s);
244         perror("connect");
245         return (0);
246     }
247     *sock = s;
248     return (1);
249 }
250
251 # ifndef NO_SYS_UN_H
252 int init_client_unix(int *sock, const char *server)
253 {
254     struct sockaddr_un them;
255     int s;
256
257     if (strlen(server) > (UNIX_PATH_MAX + 1))
258         return (0);
259     if (!ssl_sock_init())
260         return (0);
261
262     s = socket(AF_UNIX, SOCK_STREAM, 0);
263     if (s == INVALID_SOCKET) {
264         perror("socket");
265         return (0);
266     }
267
268     memset((char *)&them, 0, sizeof(them));
269     them.sun_family = AF_UNIX;
270     strcpy(them.sun_path, server);
271
272     if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) {
273         closesocket(s);
274         perror("connect");
275         return (0);
276     }
277     *sock = s;
278     return (1);
279 }
280 # endif
281
282 int do_server(int port, int type, int *ret,
283               int (*cb) (char *hostname, int s, int stype,
284                          unsigned char *context), unsigned char *context,
285               int naccept)
286 {
287     int sock;
288     char *name = NULL;
289     int accept_socket = 0;
290     int i;
291
292     if (!init_server(&accept_socket, port, type))
293         return (0);
294
295     if (ret != NULL) {
296         *ret = accept_socket;
297         /* return(1); */
298     }
299     for (;;) {
300         if (type == SOCK_STREAM) {
301 # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
302             if (do_accept(accept_socket, &sock, NULL) == 0)
303 # else
304             if (do_accept(accept_socket, &sock, &name) == 0)
305 # endif
306             {
307                 SHUTDOWN(accept_socket);
308                 return (0);
309             }
310         } else
311             sock = accept_socket;
312         i = (*cb) (name, sock, type, context);
313         if (name != NULL)
314             OPENSSL_free(name);
315         if (type == SOCK_STREAM)
316             SHUTDOWN2(sock);
317         if (naccept != -1)
318             naccept--;
319         if (i < 0 || naccept == 0) {
320             SHUTDOWN2(accept_socket);
321             return (i);
322         }
323     }
324 }
325
326 # ifndef NO_SYS_UN_H
327 int do_server_unix(const char *path, int *ret,
328                    int (*cb) (char *hostname, int s, int stype,
329                               unsigned char *context), unsigned char *context,
330                    int naccept)
331 {
332     int sock;
333     int accept_socket = 0;
334     int i;
335
336     if (!init_server_unix(&accept_socket, path))
337         return (0);
338
339     if (ret != NULL)
340         *ret = accept_socket;
341     for (;;) {
342         if (do_accept_unix(accept_socket, &sock) == 0) {
343             SHUTDOWN(accept_socket);
344             i = 0;
345             goto out;
346         }
347         i = (*cb) (NULL, sock, 0, context);
348         SHUTDOWN2(sock);
349         if (naccept != -1)
350             naccept--;
351         if (i < 0 || naccept == 0) {
352             SHUTDOWN2(accept_socket);
353             goto out;
354         }
355     }
356  out:
357     unlink(path);
358     return (i);
359 }
360 # endif
361
362 static int init_server_long(int *sock, int port, char *ip, int type)
363 {
364     int ret = 0;
365     struct sockaddr_in server;
366     int s = -1;
367
368     if (!ssl_sock_init())
369         return (0);
370
371     memset((char *)&server, 0, sizeof(server));
372     server.sin_family = AF_INET;
373     server.sin_port = htons((unsigned short)port);
374     if (ip == NULL)
375         server.sin_addr.s_addr = INADDR_ANY;
376     else
377 /* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
378 # ifndef BIT_FIELD_LIMITS
379         memcpy(&server.sin_addr.s_addr, ip, 4);
380 # else
381         memcpy(&server.sin_addr, ip, 4);
382 # endif
383
384     if (type == SOCK_STREAM)
385         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
386     else                        /* type == SOCK_DGRAM */
387         s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
388
389     if (s == INVALID_SOCKET)
390         goto err;
391 # if defined SOL_SOCKET && defined SO_REUSEADDR
392     {
393         int j = 1;
394         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j);
395     }
396 # endif
397     if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) {
398 # ifndef OPENSSL_SYS_WINDOWS
399         perror("bind");
400 # endif
401         goto err;
402     }
403     /* Make it 128 for linux */
404     if (type == SOCK_STREAM && listen(s, 128) == -1)
405         goto err;
406     *sock = s;
407     ret = 1;
408  err:
409     if ((ret == 0) && (s != -1)) {
410         SHUTDOWN(s);
411     }
412     return (ret);
413 }
414
415 static int init_server(int *sock, int port, int type)
416 {
417     return (init_server_long(sock, port, NULL, type));
418 }
419
420 # ifndef NO_SYS_UN_H
421 static int init_server_unix(int *sock, const char *path)
422 {
423     int ret = 0;
424     struct sockaddr_un server;
425     int s = -1;
426
427     if (strlen(path) > (UNIX_PATH_MAX + 1))
428         return (0);
429     if (!ssl_sock_init())
430         return (0);
431
432     s = socket(AF_UNIX, SOCK_STREAM, 0);
433     if (s == INVALID_SOCKET)
434         goto err;
435
436     memset((char *)&server, 0, sizeof(server));
437     server.sun_family = AF_UNIX;
438     strcpy(server.sun_path, path);
439
440     if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) {
441 #  ifndef OPENSSL_SYS_WINDOWS
442         perror("bind");
443 #  endif
444         goto err;
445     }
446     /* Make it 128 for linux */
447     if (listen(s, 128) == -1) {
448 #  ifndef OPENSSL_SYS_WINDOWS
449         perror("listen");
450 #  endif
451         unlink(path);
452         goto err;
453     }
454     *sock = s;
455     ret = 1;
456  err:
457     if ((ret == 0) && (s != -1)) {
458         SHUTDOWN(s);
459     }
460     return (ret);
461 }
462 # endif
463
464 static int do_accept(int acc_sock, int *sock, char **host)
465 {
466     int ret;
467     struct hostent *h1, *h2;
468     static struct sockaddr_in from;
469     int len;
470 /*      struct linger ling; */
471
472     if (!ssl_sock_init())
473         return (0);
474
475 # ifndef OPENSSL_SYS_WINDOWS
476  redoit:
477 # endif
478
479     memset((char *)&from, 0, sizeof(from));
480     len = sizeof(from);
481     /*
482      * Note: under VMS with SOCKETSHR the fourth parameter is currently of
483      * type (int *) whereas under other systems it is (void *) if you don't
484      * have a cast it will choke the compiler: if you do have a cast then you
485      * can either go for (int *) or (void *).
486      */
487     ret = accept(acc_sock, (struct sockaddr *)&from, (void *)&len);
488     if (ret == INVALID_SOCKET) {
489 # if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
490         int i;
491         i = WSAGetLastError();
492         BIO_printf(bio_err, "accept error %d\n", i);
493 # else
494         if (errno == EINTR) {
495             /*
496              * check_timeout();
497              */
498             goto redoit;
499         }
500         fprintf(stderr, "errno=%d ", errno);
501         perror("accept");
502 # endif
503         return (0);
504     }
505
506 /*-
507     ling.l_onoff=1;
508     ling.l_linger=0;
509     i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
510     if (i < 0) { perror("linger"); return(0); }
511     i=0;
512     i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
513     if (i < 0) { perror("keepalive"); return(0); }
514 */
515
516     if (host == NULL)
517         goto end;
518 # ifndef BIT_FIELD_LIMITS
519     /* I should use WSAAsyncGetHostByName() under windows */
520     h1 = gethostbyaddr((char *)&from.sin_addr.s_addr,
521                        sizeof(from.sin_addr.s_addr), AF_INET);
522 # else
523     h1 = gethostbyaddr((char *)&from.sin_addr,
524                        sizeof(struct in_addr), AF_INET);
525 # endif
526     if (h1 == NULL) {
527         BIO_printf(bio_err, "bad gethostbyaddr\n");
528         *host = NULL;
529         /* return(0); */
530     } else {
531         if ((*host = (char *)OPENSSL_malloc(strlen(h1->h_name) + 1)) == NULL) {
532             perror("OPENSSL_malloc");
533             closesocket(ret);
534             return (0);
535         }
536         BUF_strlcpy(*host, h1->h_name, strlen(h1->h_name) + 1);
537
538         h2 = GetHostByName(*host);
539         if (h2 == NULL) {
540             BIO_printf(bio_err, "gethostbyname failure\n");
541             closesocket(ret);
542             return (0);
543         }
544         if (h2->h_addrtype != AF_INET) {
545             BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
546             closesocket(ret);
547             return (0);
548         }
549     }
550  end:
551     *sock = ret;
552     return (1);
553 }
554
555 # ifndef NO_SYS_UN_H
556 static int do_accept_unix(int acc_sock, int *sock)
557 {
558     int ret;
559
560     if (!ssl_sock_init())
561         return (0);
562
563  redoit:
564     ret = accept(acc_sock, NULL, NULL);
565     if (ret == INVALID_SOCKET) {
566         if (errno == EINTR) {
567             /*
568              * check_timeout();
569              */
570             goto redoit;
571         }
572         fprintf(stderr, "errno=%d ", errno);
573         perror("accept");
574         return (0);
575     }
576
577     *sock = ret;
578     return (1);
579 }
580 # endif
581
582 int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
583                       short *port_ptr)
584 {
585     char *h, *p;
586
587     h = str;
588     p = strchr(str, ':');
589     if (p == NULL) {
590         BIO_printf(bio_err, "no port defined\n");
591         return (0);
592     }
593     *(p++) = '\0';
594
595     if ((ip != NULL) && !host_ip(str, ip))
596         goto err;
597     if (host_ptr != NULL)
598         *host_ptr = h;
599
600     if (!extract_port(p, port_ptr))
601         goto err;
602     return (1);
603  err:
604     return (0);
605 }
606
607 static int host_ip(const char *str, unsigned char ip[4])
608 {
609     unsigned int in[4];
610     int i;
611
612     if (sscanf(str, "%u.%u.%u.%u", &(in[0]), &(in[1]), &(in[2]), &(in[3])) ==
613         4) {
614         for (i = 0; i < 4; i++)
615             if (in[i] > 255) {
616                 BIO_printf(bio_err, "invalid IP address\n");
617                 goto err;
618             }
619         ip[0] = in[0];
620         ip[1] = in[1];
621         ip[2] = in[2];
622         ip[3] = in[3];
623     } else {                    /* do a gethostbyname */
624         struct hostent *he;
625
626         if (!ssl_sock_init())
627             return (0);
628
629         he = GetHostByName(str);
630         if (he == NULL) {
631             BIO_printf(bio_err, "gethostbyname failure\n");
632             goto err;
633         }
634         if (he->h_addrtype != AF_INET) {
635             BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
636             return (0);
637         }
638         ip[0] = he->h_addr_list[0][0];
639         ip[1] = he->h_addr_list[0][1];
640         ip[2] = he->h_addr_list[0][2];
641         ip[3] = he->h_addr_list[0][3];
642     }
643     return (1);
644  err:
645     return (0);
646 }
647
648 int extract_port(const char *str, short *port_ptr)
649 {
650     int i;
651     struct servent *s;
652
653     i = atoi(str);
654     if (i != 0)
655         *port_ptr = (unsigned short)i;
656     else {
657         s = getservbyname(str, "tcp");
658         if (s == NULL) {
659             BIO_printf(bio_err, "getservbyname failure for %s\n", str);
660             return (0);
661         }
662         *port_ptr = ntohs((unsigned short)s->s_port);
663     }
664     return (1);
665 }
666
667 # define GHBN_NUM        4
668 static struct ghbn_cache_st {
669     char name[128];
670     struct hostent ent;
671     unsigned long order;
672 } ghbn_cache[GHBN_NUM];
673
674 static unsigned long ghbn_hits = 0L;
675 static unsigned long ghbn_miss = 0L;
676
677 static struct hostent *GetHostByName(const char *name)
678 {
679     struct hostent *ret;
680     int i, lowi = 0;
681     unsigned long low = (unsigned long)-1;
682
683     for (i = 0; i < GHBN_NUM; i++) {
684         if (low > ghbn_cache[i].order) {
685             low = ghbn_cache[i].order;
686             lowi = i;
687         }
688         if (ghbn_cache[i].order > 0) {
689             if (strncmp(name, ghbn_cache[i].name, 128) == 0)
690                 break;
691         }
692     }
693     if (i == GHBN_NUM) {        /* no hit */
694         ghbn_miss++;
695         ret = gethostbyname(name);
696         if (ret == NULL)
697             return (NULL);
698         /* else add to cache */
699         if (strlen(name) < sizeof ghbn_cache[0].name) {
700             strcpy(ghbn_cache[lowi].name, name);
701             memcpy((char *)&(ghbn_cache[lowi].ent), ret,
702                    sizeof(struct hostent));
703             ghbn_cache[lowi].order = ghbn_miss + ghbn_hits;
704         }
705         return (ret);
706     } else {
707         ghbn_hits++;
708         ret = &(ghbn_cache[i].ent);
709         ghbn_cache[i].order = ghbn_miss + ghbn_hits;
710         return (ret);
711     }
712 }
713
714 #endif