00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <string.h>
00062 #include <errno.h>
00063 #include <signal.h>
00064
00065
00066
00067
00068
00069 #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
00070 #define __U_INT
00071 typedef unsigned int u_int;
00072 #endif
00073
00074 #define USE_SOCKETS
00075 #define NON_MAIN
00076 #include "apps.h"
00077 #undef USE_SOCKETS
00078 #undef NON_MAIN
00079 #include "s_apps.h"
00080 #include <openssl/ssl.h>
00081
00082 #ifdef FLAT_INC
00083 #include "e_os.h"
00084 #else
00085 #include "../e_os.h"
00086 #endif
00087
00088 #ifndef OPENSSL_NO_SOCK
00089
00090 #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
00091 #include "netdb.h"
00092 #endif
00093
00094 static struct hostent *GetHostByName(char *name);
00095 #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
00096 static void ssl_sock_cleanup(void);
00097 #endif
00098 static int ssl_sock_init(void);
00099 static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
00100 static int init_server(int *sock, int port, int type);
00101 static int init_server_long(int *sock, int port,char *ip, int type);
00102 static int do_accept(int acc_sock, int *sock, char **host);
00103 static int host_ip(char *str, unsigned char ip[4]);
00104
00105 #ifdef OPENSSL_SYS_WIN16
00106 #define SOCKET_PROTOCOL 0
00107 #else
00108 #define SOCKET_PROTOCOL IPPROTO_TCP
00109 #endif
00110
00111 #if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
00112 static int wsa_init_done=0;
00113 #endif
00114
00115 #ifdef OPENSSL_SYS_WINDOWS
00116 static struct WSAData wsa_state;
00117 static int wsa_init_done=0;
00118
00119 #ifdef OPENSSL_SYS_WIN16
00120 static HWND topWnd=0;
00121 static FARPROC lpTopWndProc=NULL;
00122 static FARPROC lpTopHookProc=NULL;
00123 extern HINSTANCE _hInstance;
00124
00125 static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam,
00126 LPARAM lParam)
00127 {
00128 if (hwnd == topWnd)
00129 {
00130 switch(message)
00131 {
00132 case WM_DESTROY:
00133 case WM_CLOSE:
00134 SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc);
00135 ssl_sock_cleanup();
00136 break;
00137 }
00138 }
00139 return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam);
00140 }
00141
00142 static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam)
00143 {
00144 topWnd=hwnd;
00145 return(FALSE);
00146 }
00147
00148 #endif
00149 #endif
00150
00151 #ifdef OPENSSL_SYS_WINDOWS
00152 static void ssl_sock_cleanup(void)
00153 {
00154 if (wsa_init_done)
00155 {
00156 wsa_init_done=0;
00157 #ifndef OPENSSL_SYS_WINCE
00158 WSACancelBlockingCall();
00159 #endif
00160 WSACleanup();
00161 }
00162 }
00163 #elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
00164 static void sock_cleanup(void)
00165 {
00166 if (wsa_init_done)
00167 {
00168 wsa_init_done=0;
00169 WSACleanup();
00170 }
00171 }
00172 #endif
00173
00174 static int ssl_sock_init(void)
00175 {
00176 #ifdef WATT32
00177 extern int _watt_do_exit;
00178 _watt_do_exit = 0;
00179 if (sock_init())
00180 return (0);
00181 #elif defined(OPENSSL_SYS_WINDOWS)
00182 if (!wsa_init_done)
00183 {
00184 int err;
00185
00186 #ifdef SIGINT
00187 signal(SIGINT,(void (*)(int))ssl_sock_cleanup);
00188 #endif
00189 wsa_init_done=1;
00190 memset(&wsa_state,0,sizeof(wsa_state));
00191 if (WSAStartup(0x0101,&wsa_state)!=0)
00192 {
00193 err=WSAGetLastError();
00194 BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err);
00195 return(0);
00196 }
00197
00198 #ifdef OPENSSL_SYS_WIN16
00199 EnumTaskWindows(GetCurrentTask(),enumproc,0L);
00200 lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC);
00201 lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance);
00202
00203 SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc);
00204 #endif
00205 }
00206 #elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
00207 WORD wVerReq;
00208 WSADATA wsaData;
00209 int err;
00210
00211 if (!wsa_init_done)
00212 {
00213
00214 # ifdef SIGINT
00215 signal(SIGINT,(void (*)(int))sock_cleanup);
00216 # endif
00217
00218 wsa_init_done=1;
00219 wVerReq = MAKEWORD( 2, 0 );
00220 err = WSAStartup(wVerReq,&wsaData);
00221 if (err != 0)
00222 {
00223 BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err);
00224 return(0);
00225 }
00226 }
00227 #endif
00228 return(1);
00229 }
00230
00231 int init_client(int *sock, char *host, int port, int type)
00232 {
00233 unsigned char ip[4];
00234 short p=0;
00235
00236 if (!host_ip(host,&(ip[0])))
00237 {
00238 return(0);
00239 }
00240 if (p != 0) port=p;
00241 return(init_client_ip(sock,ip,port,type));
00242 }
00243
00244 static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
00245 {
00246 unsigned long addr;
00247 struct sockaddr_in them;
00248 int s,i;
00249
00250 if (!ssl_sock_init()) return(0);
00251
00252 memset((char *)&them,0,sizeof(them));
00253 them.sin_family=AF_INET;
00254 them.sin_port=htons((unsigned short)port);
00255 addr=(unsigned long)
00256 ((unsigned long)ip[0]<<24L)|
00257 ((unsigned long)ip[1]<<16L)|
00258 ((unsigned long)ip[2]<< 8L)|
00259 ((unsigned long)ip[3]);
00260 them.sin_addr.s_addr=htonl(addr);
00261
00262 if (type == SOCK_STREAM)
00263 s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
00264 else
00265 s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
00266
00267 if (s == INVALID_SOCKET) { perror("socket"); return(0); }
00268
00269 #ifndef OPENSSL_SYS_MPE
00270 if (type == SOCK_STREAM)
00271 {
00272 i=0;
00273 i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
00274 if (i < 0) { perror("keepalive"); return(0); }
00275 }
00276 #endif
00277
00278 if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
00279 { close(s); perror("connect"); return(0); }
00280 *sock=s;
00281 return(1);
00282 }
00283
00284 int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
00285 {
00286 int sock;
00287 char *name = NULL;
00288 int accept_socket;
00289 int i;
00290
00291 if (!init_server(&accept_socket,port,type)) return(0);
00292
00293 if (ret != NULL)
00294 {
00295 *ret=accept_socket;
00296
00297 }
00298 for (;;)
00299 {
00300 if (type==SOCK_STREAM)
00301 {
00302 if (do_accept(accept_socket,&sock,&name) == 0)
00303 {
00304 SHUTDOWN(accept_socket);
00305 return(0);
00306 }
00307 }
00308 else
00309 sock = accept_socket;
00310 i=(*cb)(name,sock, context);
00311 if (name != NULL) OPENSSL_free(name);
00312 if (type==SOCK_STREAM)
00313 SHUTDOWN2(sock);
00314 if (i < 0)
00315 {
00316 SHUTDOWN2(accept_socket);
00317 return(i);
00318 }
00319 }
00320 }
00321
00322 static int init_server_long(int *sock, int port, char *ip, int type)
00323 {
00324 int ret=0;
00325 struct sockaddr_in server;
00326 int s= -1,i;
00327
00328 if (!ssl_sock_init()) return(0);
00329
00330 memset((char *)&server,0,sizeof(server));
00331 server.sin_family=AF_INET;
00332 server.sin_port=htons((unsigned short)port);
00333 if (ip == NULL)
00334 server.sin_addr.s_addr=INADDR_ANY;
00335 else
00336
00337 #ifndef BIT_FIELD_LIMITS
00338 memcpy(&server.sin_addr.s_addr,ip,4);
00339 #else
00340 memcpy(&server.sin_addr,ip,4);
00341 #endif
00342
00343 if (type == SOCK_STREAM)
00344 s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
00345 else
00346 s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
00347
00348 if (s == INVALID_SOCKET) goto err;
00349 #if defined SOL_SOCKET && defined SO_REUSEADDR
00350 {
00351 int j = 1;
00352 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
00353 (void *) &j, sizeof j);
00354 }
00355 #endif
00356 if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
00357 {
00358 #ifndef OPENSSL_SYS_WINDOWS
00359 perror("bind");
00360 #endif
00361 goto err;
00362 }
00363
00364 if (type==SOCK_STREAM && listen(s,128) == -1) goto err;
00365 i=0;
00366 *sock=s;
00367 ret=1;
00368 err:
00369 if ((ret == 0) && (s != -1))
00370 {
00371 SHUTDOWN(s);
00372 }
00373 return(ret);
00374 }
00375
00376 static int init_server(int *sock, int port, int type)
00377 {
00378 return(init_server_long(sock, port, NULL, type));
00379 }
00380
00381 static int do_accept(int acc_sock, int *sock, char **host)
00382 {
00383 int ret,i;
00384 struct hostent *h1,*h2;
00385 static struct sockaddr_in from;
00386 int len;
00387
00388
00389 if (!ssl_sock_init()) return(0);
00390
00391 #ifndef OPENSSL_SYS_WINDOWS
00392 redoit:
00393 #endif
00394
00395 memset((char *)&from,0,sizeof(from));
00396 len=sizeof(from);
00397
00398
00399
00400
00401
00402 ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len);
00403 if (ret == INVALID_SOCKET)
00404 {
00405 #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
00406 i=WSAGetLastError();
00407 BIO_printf(bio_err,"accept error %d\n",i);
00408 #else
00409 if (errno == EINTR)
00410 {
00411
00412 goto redoit;
00413 }
00414 fprintf(stderr,"errno=%d ",errno);
00415 perror("accept");
00416 #endif
00417 return(0);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 if (host == NULL) goto end;
00431 #ifndef BIT_FIELD_LIMITS
00432
00433 h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
00434 sizeof(from.sin_addr.s_addr),AF_INET);
00435 #else
00436 h1=gethostbyaddr((char *)&from.sin_addr,
00437 sizeof(struct in_addr),AF_INET);
00438 #endif
00439 if (h1 == NULL)
00440 {
00441 BIO_printf(bio_err,"bad gethostbyaddr\n");
00442 *host=NULL;
00443
00444 }
00445 else
00446 {
00447 if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
00448 {
00449 perror("OPENSSL_malloc");
00450 return(0);
00451 }
00452 BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
00453
00454 h2=GetHostByName(*host);
00455 if (h2 == NULL)
00456 {
00457 BIO_printf(bio_err,"gethostbyname failure\n");
00458 return(0);
00459 }
00460 i=0;
00461 if (h2->h_addrtype != AF_INET)
00462 {
00463 BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
00464 return(0);
00465 }
00466 }
00467 end:
00468 *sock=ret;
00469 return(1);
00470 }
00471
00472 int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
00473 short *port_ptr)
00474 {
00475 char *h,*p;
00476
00477 h=str;
00478 p=strchr(str,':');
00479 if (p == NULL)
00480 {
00481 BIO_printf(bio_err,"no port defined\n");
00482 return(0);
00483 }
00484 *(p++)='\0';
00485
00486 if ((ip != NULL) && !host_ip(str,ip))
00487 goto err;
00488 if (host_ptr != NULL) *host_ptr=h;
00489
00490 if (!extract_port(p,port_ptr))
00491 goto err;
00492 return(1);
00493 err:
00494 return(0);
00495 }
00496
00497 static int host_ip(char *str, unsigned char ip[4])
00498 {
00499 unsigned int in[4];
00500 int i;
00501
00502 if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
00503 {
00504 for (i=0; i<4; i++)
00505 if (in[i] > 255)
00506 {
00507 BIO_printf(bio_err,"invalid IP address\n");
00508 goto err;
00509 }
00510 ip[0]=in[0];
00511 ip[1]=in[1];
00512 ip[2]=in[2];
00513 ip[3]=in[3];
00514 }
00515 else
00516 {
00517 struct hostent *he;
00518
00519 if (!ssl_sock_init()) return(0);
00520
00521 he=GetHostByName(str);
00522 if (he == NULL)
00523 {
00524 BIO_printf(bio_err,"gethostbyname failure\n");
00525 goto err;
00526 }
00527
00528 if ((short)he->h_addrtype != AF_INET)
00529 {
00530 BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
00531 return(0);
00532 }
00533 ip[0]=he->h_addr_list[0][0];
00534 ip[1]=he->h_addr_list[0][1];
00535 ip[2]=he->h_addr_list[0][2];
00536 ip[3]=he->h_addr_list[0][3];
00537 }
00538 return(1);
00539 err:
00540 return(0);
00541 }
00542
00543 int extract_port(char *str, short *port_ptr)
00544 {
00545 int i;
00546 struct servent *s;
00547
00548 i=atoi(str);
00549 if (i != 0)
00550 *port_ptr=(unsigned short)i;
00551 else
00552 {
00553 s=getservbyname(str,"tcp");
00554 if (s == NULL)
00555 {
00556 BIO_printf(bio_err,"getservbyname failure for %s\n",str);
00557 return(0);
00558 }
00559 *port_ptr=ntohs((unsigned short)s->s_port);
00560 }
00561 return(1);
00562 }
00563
00564 #define GHBN_NUM 4
00565 static struct ghbn_cache_st
00566 {
00567 char name[128];
00568 struct hostent ent;
00569 unsigned long order;
00570 } ghbn_cache[GHBN_NUM];
00571
00572 static unsigned long ghbn_hits=0L;
00573 static unsigned long ghbn_miss=0L;
00574
00575 static struct hostent *GetHostByName(char *name)
00576 {
00577 struct hostent *ret;
00578 int i,lowi=0;
00579 unsigned long low= (unsigned long)-1;
00580
00581 for (i=0; i<GHBN_NUM; i++)
00582 {
00583 if (low > ghbn_cache[i].order)
00584 {
00585 low=ghbn_cache[i].order;
00586 lowi=i;
00587 }
00588 if (ghbn_cache[i].order > 0)
00589 {
00590 if (strncmp(name,ghbn_cache[i].name,128) == 0)
00591 break;
00592 }
00593 }
00594 if (i == GHBN_NUM)
00595 {
00596 ghbn_miss++;
00597 ret=gethostbyname(name);
00598 if (ret == NULL) return(NULL);
00599
00600 if(strlen(name) < sizeof ghbn_cache[0].name)
00601 {
00602 strcpy(ghbn_cache[lowi].name,name);
00603 memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent));
00604 ghbn_cache[lowi].order=ghbn_miss+ghbn_hits;
00605 }
00606 return(ret);
00607 }
00608 else
00609 {
00610 ghbn_hits++;
00611 ret= &(ghbn_cache[i].ent);
00612 ghbn_cache[i].order=ghbn_miss+ghbn_hits;
00613 return(ret);
00614 }
00615 }
00616
00617 #endif