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