diff options
Diffstat (limited to 'src/lib/libssl/src/apps/s_server.c')
-rw-r--r-- | src/lib/libssl/src/apps/s_server.c | 1225 |
1 files changed, 1225 insertions, 0 deletions
diff --git a/src/lib/libssl/src/apps/s_server.c b/src/lib/libssl/src/apps/s_server.c new file mode 100644 index 0000000000..5012ef254d --- /dev/null +++ b/src/lib/libssl/src/apps/s_server.c | |||
@@ -0,0 +1,1225 @@ | |||
1 | /* apps/s_server.c */ | ||
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 <sys/types.h> | ||
63 | #include <sys/stat.h> | ||
64 | #ifdef NO_STDIO | ||
65 | #define APPS_WIN16 | ||
66 | #endif | ||
67 | #include "lhash.h" | ||
68 | #include "bn.h" | ||
69 | #define USE_SOCKETS | ||
70 | #include "apps.h" | ||
71 | #include "err.h" | ||
72 | #include "pem.h" | ||
73 | #include "x509.h" | ||
74 | #include "ssl.h" | ||
75 | #include "s_apps.h" | ||
76 | |||
77 | #ifndef NOPROTO | ||
78 | static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int export); | ||
79 | static int sv_body(char *hostname, int s); | ||
80 | static int www_body(char *hostname, int s); | ||
81 | static void close_accept_socket(void ); | ||
82 | static void sv_usage(void); | ||
83 | static int init_ssl_connection(SSL *s); | ||
84 | static void print_stats(BIO *bp,SSL_CTX *ctx); | ||
85 | #ifndef NO_DH | ||
86 | static DH *load_dh_param(void ); | ||
87 | static DH *get_dh512(void); | ||
88 | #endif | ||
89 | /* static void s_server_init(void);*/ | ||
90 | #else | ||
91 | static RSA MS_CALLBACK *tmp_rsa_cb(); | ||
92 | static int sv_body(); | ||
93 | static int www_body(); | ||
94 | static void close_accept_socket(); | ||
95 | static void sv_usage(); | ||
96 | static int init_ssl_connection(); | ||
97 | static void print_stats(); | ||
98 | #ifndef NO_DH | ||
99 | static DH *load_dh_param(); | ||
100 | static DH *get_dh512(); | ||
101 | #endif | ||
102 | /* static void s_server_init(); */ | ||
103 | #endif | ||
104 | |||
105 | |||
106 | #ifndef S_ISDIR | ||
107 | #define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) | ||
108 | #endif | ||
109 | |||
110 | #ifndef NO_DH | ||
111 | static unsigned char dh512_p[]={ | ||
112 | 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, | ||
113 | 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, | ||
114 | 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, | ||
115 | 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, | ||
116 | 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, | ||
117 | 0x47,0x74,0xE8,0x33, | ||
118 | }; | ||
119 | static unsigned char dh512_g[]={ | ||
120 | 0x02, | ||
121 | }; | ||
122 | |||
123 | static DH *get_dh512() | ||
124 | { | ||
125 | DH *dh=NULL; | ||
126 | |||
127 | if ((dh=DH_new()) == NULL) return(NULL); | ||
128 | dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); | ||
129 | dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); | ||
130 | if ((dh->p == NULL) || (dh->g == NULL)) | ||
131 | return(NULL); | ||
132 | return(dh); | ||
133 | } | ||
134 | #endif | ||
135 | |||
136 | /* static int load_CA(SSL_CTX *ctx, char *file);*/ | ||
137 | |||
138 | #undef BUFSIZZ | ||
139 | #define BUFSIZZ 8*1024 | ||
140 | static int accept_socket= -1; | ||
141 | |||
142 | #define TEST_CERT "server.pem" | ||
143 | #undef PROG | ||
144 | #define PROG s_server_main | ||
145 | |||
146 | #define DH_PARAM "server.pem" | ||
147 | |||
148 | extern int verify_depth; | ||
149 | |||
150 | static char *cipher=NULL; | ||
151 | static int s_server_verify=SSL_VERIFY_NONE; | ||
152 | static char *s_cert_file=TEST_CERT,*s_key_file=NULL; | ||
153 | static char *s_dcert_file=NULL,*s_dkey_file=NULL; | ||
154 | #ifdef FIONBIO | ||
155 | static int s_nbio=0; | ||
156 | #endif | ||
157 | static int s_nbio_test=0; | ||
158 | static SSL_CTX *ctx=NULL; | ||
159 | static int www=0; | ||
160 | |||
161 | static BIO *bio_s_out=NULL; | ||
162 | static int s_debug=0; | ||
163 | static int s_quiet=0; | ||
164 | |||
165 | #if 0 | ||
166 | static void s_server_init() | ||
167 | { | ||
168 | cipher=NULL; | ||
169 | s_server_verify=SSL_VERIFY_NONE; | ||
170 | s_dcert_file=NULL; | ||
171 | s_dkey_file=NULL; | ||
172 | s_cert_file=TEST_CERT; | ||
173 | s_key_file=NULL; | ||
174 | #ifdef FIONBIO | ||
175 | s_nbio=0; | ||
176 | #endif | ||
177 | s_nbio_test=0; | ||
178 | ctx=NULL; | ||
179 | www=0; | ||
180 | |||
181 | bio_s_out=NULL; | ||
182 | s_debug=0; | ||
183 | s_quiet=0; | ||
184 | } | ||
185 | #endif | ||
186 | |||
187 | static void sv_usage() | ||
188 | { | ||
189 | BIO_printf(bio_err,"usage: s_server [args ...]\n"); | ||
190 | BIO_printf(bio_err,"\n"); | ||
191 | BIO_printf(bio_err," -accept arg - port to accept on (default is %d\n",PORT); | ||
192 | BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); | ||
193 | BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); | ||
194 | BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); | ||
195 | BIO_printf(bio_err," (default is %s)\n",TEST_CERT); | ||
196 | BIO_printf(bio_err," -key arg - RSA file to use, PEM format assumed, in cert file if\n"); | ||
197 | BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT); | ||
198 | #ifdef FIONBIO | ||
199 | BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); | ||
200 | #endif | ||
201 | BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n"); | ||
202 | BIO_printf(bio_err," -debug - Print more output\n"); | ||
203 | BIO_printf(bio_err," -state - Print the SSL states\n"); | ||
204 | BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n"); | ||
205 | BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n"); | ||
206 | BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n"); | ||
207 | BIO_printf(bio_err," -cipher arg - play with 'ssleay ciphers' to see what goes here\n"); | ||
208 | BIO_printf(bio_err," -quiet - No server output\n"); | ||
209 | BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n"); | ||
210 | BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); | ||
211 | BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); | ||
212 | BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); | ||
213 | BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n"); | ||
214 | BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n"); | ||
215 | BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n"); | ||
216 | BIO_printf(bio_err," -bugs - Turn on SSL bug compatability\n"); | ||
217 | BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n"); | ||
218 | BIO_printf(bio_err," -WWW - Returns requested page from to a 'GET <path> HTTP/1.0'\n"); | ||
219 | } | ||
220 | |||
221 | static int local_argc=0; | ||
222 | static char **local_argv; | ||
223 | static int hack=0; | ||
224 | |||
225 | int MAIN(argc, argv) | ||
226 | int argc; | ||
227 | char *argv[]; | ||
228 | { | ||
229 | short port=PORT; | ||
230 | char *CApath=NULL,*CAfile=NULL; | ||
231 | int badop=0,bugs=0; | ||
232 | int ret=1; | ||
233 | int off=0; | ||
234 | int no_tmp_rsa=0,nocert=0; | ||
235 | int state=0; | ||
236 | SSL_METHOD *meth=NULL; | ||
237 | #ifndef NO_DH | ||
238 | DH *dh=NULL; | ||
239 | #endif | ||
240 | |||
241 | #if !defined(NO_SSL2) && !defined(NO_SSL3) | ||
242 | meth=SSLv23_server_method(); | ||
243 | #elif !defined(NO_SSL3) | ||
244 | meth=SSLv3_server_method(); | ||
245 | #elif !defined(NO_SSL2) | ||
246 | meth=SSLv2_server_method(); | ||
247 | #endif | ||
248 | |||
249 | local_argc=argc; | ||
250 | local_argv=argv; | ||
251 | |||
252 | apps_startup(); | ||
253 | s_quiet=0; | ||
254 | s_debug=0; | ||
255 | |||
256 | if (bio_err == NULL) | ||
257 | bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); | ||
258 | |||
259 | verify_depth=0; | ||
260 | #ifdef FIONBIO | ||
261 | s_nbio=0; | ||
262 | #endif | ||
263 | s_nbio_test=0; | ||
264 | |||
265 | argc--; | ||
266 | argv++; | ||
267 | |||
268 | while (argc >= 1) | ||
269 | { | ||
270 | if ((strcmp(*argv,"-port") == 0) || | ||
271 | (strcmp(*argv,"-accept") == 0)) | ||
272 | { | ||
273 | if (--argc < 1) goto bad; | ||
274 | if (!extract_port(*(++argv),&port)) | ||
275 | goto bad; | ||
276 | } | ||
277 | else if (strcmp(*argv,"-verify") == 0) | ||
278 | { | ||
279 | s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE; | ||
280 | if (--argc < 1) goto bad; | ||
281 | verify_depth=atoi(*(++argv)); | ||
282 | BIO_printf(bio_err,"verify depth is %d\n",verify_depth); | ||
283 | } | ||
284 | else if (strcmp(*argv,"-Verify") == 0) | ||
285 | { | ||
286 | s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| | ||
287 | SSL_VERIFY_CLIENT_ONCE; | ||
288 | if (--argc < 1) goto bad; | ||
289 | verify_depth=atoi(*(++argv)); | ||
290 | BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth); | ||
291 | } | ||
292 | else if (strcmp(*argv,"-cert") == 0) | ||
293 | { | ||
294 | if (--argc < 1) goto bad; | ||
295 | s_cert_file= *(++argv); | ||
296 | } | ||
297 | else if (strcmp(*argv,"-key") == 0) | ||
298 | { | ||
299 | if (--argc < 1) goto bad; | ||
300 | s_key_file= *(++argv); | ||
301 | } | ||
302 | else if (strcmp(*argv,"-dcert") == 0) | ||
303 | { | ||
304 | if (--argc < 1) goto bad; | ||
305 | s_dcert_file= *(++argv); | ||
306 | } | ||
307 | else if (strcmp(*argv,"-dkey") == 0) | ||
308 | { | ||
309 | if (--argc < 1) goto bad; | ||
310 | s_dkey_file= *(++argv); | ||
311 | } | ||
312 | else if (strcmp(*argv,"-nocert") == 0) | ||
313 | { | ||
314 | nocert=1; | ||
315 | } | ||
316 | else if (strcmp(*argv,"-CApath") == 0) | ||
317 | { | ||
318 | if (--argc < 1) goto bad; | ||
319 | CApath= *(++argv); | ||
320 | } | ||
321 | else if (strcmp(*argv,"-cipher") == 0) | ||
322 | { | ||
323 | if (--argc < 1) goto bad; | ||
324 | cipher= *(++argv); | ||
325 | } | ||
326 | else if (strcmp(*argv,"-CAfile") == 0) | ||
327 | { | ||
328 | if (--argc < 1) goto bad; | ||
329 | CAfile= *(++argv); | ||
330 | } | ||
331 | #ifdef FIONBIO | ||
332 | else if (strcmp(*argv,"-nbio") == 0) | ||
333 | { s_nbio=1; } | ||
334 | #endif | ||
335 | else if (strcmp(*argv,"-nbio_test") == 0) | ||
336 | { | ||
337 | #ifdef FIONBIO | ||
338 | s_nbio=1; | ||
339 | #endif | ||
340 | s_nbio_test=1; | ||
341 | } | ||
342 | else if (strcmp(*argv,"-debug") == 0) | ||
343 | { s_debug=1; } | ||
344 | else if (strcmp(*argv,"-hack") == 0) | ||
345 | { hack=1; } | ||
346 | else if (strcmp(*argv,"-state") == 0) | ||
347 | { state=1; } | ||
348 | else if (strcmp(*argv,"-quiet") == 0) | ||
349 | { s_quiet=1; } | ||
350 | else if (strcmp(*argv,"-bugs") == 0) | ||
351 | { bugs=1; } | ||
352 | else if (strcmp(*argv,"-no_tmp_rsa") == 0) | ||
353 | { no_tmp_rsa=1; } | ||
354 | else if (strcmp(*argv,"-www") == 0) | ||
355 | { www=1; } | ||
356 | else if (strcmp(*argv,"-WWW") == 0) | ||
357 | { www=2; } | ||
358 | else if (strcmp(*argv,"-no_ssl2") == 0) | ||
359 | { off|=SSL_OP_NO_SSLv2; } | ||
360 | else if (strcmp(*argv,"-no_ssl3") == 0) | ||
361 | { off|=SSL_OP_NO_SSLv3; } | ||
362 | else if (strcmp(*argv,"-no_tls1") == 0) | ||
363 | { off|=SSL_OP_NO_TLSv1; } | ||
364 | #ifndef NO_SSL2 | ||
365 | else if (strcmp(*argv,"-ssl2") == 0) | ||
366 | { meth=SSLv2_server_method(); } | ||
367 | #endif | ||
368 | #ifndef NO_SSL3 | ||
369 | else if (strcmp(*argv,"-ssl3") == 0) | ||
370 | { meth=SSLv3_server_method(); } | ||
371 | #endif | ||
372 | #ifndef NO_TLS1 | ||
373 | else if (strcmp(*argv,"-tls1") == 0) | ||
374 | { meth=TLSv1_server_method(); } | ||
375 | #endif | ||
376 | else | ||
377 | { | ||
378 | BIO_printf(bio_err,"unknown option %s\n",*argv); | ||
379 | badop=1; | ||
380 | break; | ||
381 | } | ||
382 | argc--; | ||
383 | argv++; | ||
384 | } | ||
385 | if (badop) | ||
386 | { | ||
387 | bad: | ||
388 | sv_usage(); | ||
389 | goto end; | ||
390 | } | ||
391 | |||
392 | if (bio_s_out == NULL) | ||
393 | { | ||
394 | if (s_quiet && !s_debug) | ||
395 | { | ||
396 | bio_s_out=BIO_new(BIO_s_null()); | ||
397 | } | ||
398 | else | ||
399 | { | ||
400 | if (bio_s_out == NULL) | ||
401 | bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | #if !defined(NO_RSA) || !defined(NO_DSA) | ||
406 | if (nocert) | ||
407 | #endif | ||
408 | { | ||
409 | s_cert_file=NULL; | ||
410 | s_key_file=NULL; | ||
411 | s_dcert_file=NULL; | ||
412 | s_dkey_file=NULL; | ||
413 | } | ||
414 | |||
415 | SSL_load_error_strings(); | ||
416 | SSLeay_add_ssl_algorithms(); | ||
417 | |||
418 | ctx=SSL_CTX_new(meth); | ||
419 | if (ctx == NULL) | ||
420 | { | ||
421 | ERR_print_errors(bio_err); | ||
422 | goto end; | ||
423 | } | ||
424 | |||
425 | SSL_CTX_set_quiet_shutdown(ctx,1); | ||
426 | if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL); | ||
427 | if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); | ||
428 | SSL_CTX_set_options(ctx,off); | ||
429 | if (hack) SSL_CTX_set_options(ctx,SSL_OP_NON_EXPORT_FIRST); | ||
430 | |||
431 | if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); | ||
432 | |||
433 | SSL_CTX_sess_set_cache_size(ctx,128); | ||
434 | |||
435 | #if 0 | ||
436 | if (cipher == NULL) cipher=getenv("SSL_CIPHER"); | ||
437 | #endif | ||
438 | |||
439 | #if 0 | ||
440 | if (s_cert_file == NULL) | ||
441 | { | ||
442 | BIO_printf(bio_err,"You must specify a certificate file for the server to use\n"); | ||
443 | goto end; | ||
444 | } | ||
445 | #endif | ||
446 | |||
447 | if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || | ||
448 | (!SSL_CTX_set_default_verify_paths(ctx))) | ||
449 | { | ||
450 | /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ | ||
451 | ERR_print_errors(bio_err); | ||
452 | /* goto end; */ | ||
453 | } | ||
454 | |||
455 | #ifndef NO_DH | ||
456 | /* EAY EAY EAY evil hack */ | ||
457 | dh=load_dh_param(); | ||
458 | if (dh != NULL) | ||
459 | { | ||
460 | BIO_printf(bio_s_out,"Setting temp DH parameters\n"); | ||
461 | } | ||
462 | else | ||
463 | { | ||
464 | BIO_printf(bio_s_out,"Using default temp DH parameters\n"); | ||
465 | dh=get_dh512(); | ||
466 | } | ||
467 | BIO_flush(bio_s_out); | ||
468 | |||
469 | SSL_CTX_set_tmp_dh(ctx,dh); | ||
470 | DH_free(dh); | ||
471 | #endif | ||
472 | |||
473 | if (!set_cert_stuff(ctx,s_cert_file,s_key_file)) | ||
474 | goto end; | ||
475 | if (s_dcert_file != NULL) | ||
476 | { | ||
477 | if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file)) | ||
478 | goto end; | ||
479 | } | ||
480 | |||
481 | #if 1 | ||
482 | SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); | ||
483 | #else | ||
484 | if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) | ||
485 | { | ||
486 | RSA *rsa; | ||
487 | |||
488 | BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key..."); | ||
489 | BIO_flush(bio_s_out); | ||
490 | |||
491 | rsa=RSA_generate_key(512,RSA_F4,NULL); | ||
492 | |||
493 | if (!SSL_CTX_set_tmp_rsa(ctx,rsa)) | ||
494 | { | ||
495 | ERR_print_errors(bio_err); | ||
496 | goto end; | ||
497 | } | ||
498 | RSA_free(rsa); | ||
499 | BIO_printf(bio_s_out,"\n"); | ||
500 | } | ||
501 | #endif | ||
502 | |||
503 | if (cipher != NULL) | ||
504 | SSL_CTX_set_cipher_list(ctx,cipher); | ||
505 | SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); | ||
506 | |||
507 | SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(s_cert_file)); | ||
508 | |||
509 | BIO_printf(bio_s_out,"ACCEPT\n"); | ||
510 | if (www) | ||
511 | do_server(port,&accept_socket,www_body); | ||
512 | else | ||
513 | do_server(port,&accept_socket,sv_body); | ||
514 | print_stats(bio_s_out,ctx); | ||
515 | ret=0; | ||
516 | end: | ||
517 | if (ctx != NULL) SSL_CTX_free(ctx); | ||
518 | if (bio_s_out != NULL) | ||
519 | { | ||
520 | BIO_free(bio_s_out); | ||
521 | bio_s_out=NULL; | ||
522 | } | ||
523 | EXIT(ret); | ||
524 | } | ||
525 | |||
526 | static void print_stats(bio,ssl_ctx) | ||
527 | BIO *bio; | ||
528 | SSL_CTX *ssl_ctx; | ||
529 | { | ||
530 | BIO_printf(bio,"%4ld items in the session cache\n", | ||
531 | SSL_CTX_sess_number(ssl_ctx)); | ||
532 | BIO_printf(bio,"%4d client connects (SSL_connect())\n", | ||
533 | SSL_CTX_sess_connect(ssl_ctx)); | ||
534 | BIO_printf(bio,"%4d client renegotiates (SSL_connect())\n", | ||
535 | SSL_CTX_sess_connect_renegotiate(ssl_ctx)); | ||
536 | BIO_printf(bio,"%4d client connects that finished\n", | ||
537 | SSL_CTX_sess_connect_good(ssl_ctx)); | ||
538 | BIO_printf(bio,"%4d server accepts (SSL_accept())\n", | ||
539 | SSL_CTX_sess_accept(ssl_ctx)); | ||
540 | BIO_printf(bio,"%4d server renegotiates (SSL_accept())\n", | ||
541 | SSL_CTX_sess_accept_renegotiate(ssl_ctx)); | ||
542 | BIO_printf(bio,"%4d server accepts that finished\n", | ||
543 | SSL_CTX_sess_accept_good(ssl_ctx)); | ||
544 | BIO_printf(bio,"%4d session cache hits\n",SSL_CTX_sess_hits(ssl_ctx)); | ||
545 | BIO_printf(bio,"%4d session cache misses\n",SSL_CTX_sess_misses(ssl_ctx)); | ||
546 | BIO_printf(bio,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx)); | ||
547 | BIO_printf(bio,"%4d callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx)); | ||
548 | BIO_printf(bio,"%4d cache full overflows (%d allowed)\n", | ||
549 | SSL_CTX_sess_cache_full(ssl_ctx), | ||
550 | SSL_CTX_sess_get_cache_size(ssl_ctx)); | ||
551 | } | ||
552 | |||
553 | static int sv_body(hostname, s) | ||
554 | char *hostname; | ||
555 | int s; | ||
556 | { | ||
557 | char *buf=NULL; | ||
558 | fd_set readfds; | ||
559 | int ret=1,width; | ||
560 | int k,i; | ||
561 | unsigned long l; | ||
562 | SSL *con=NULL; | ||
563 | BIO *sbio; | ||
564 | |||
565 | if ((buf=Malloc(BUFSIZZ)) == NULL) | ||
566 | { | ||
567 | BIO_printf(bio_err,"out of memory\n"); | ||
568 | goto err; | ||
569 | } | ||
570 | #ifdef FIONBIO | ||
571 | if (s_nbio) | ||
572 | { | ||
573 | unsigned long sl=1; | ||
574 | |||
575 | if (!s_quiet) | ||
576 | BIO_printf(bio_err,"turning on non blocking io\n"); | ||
577 | if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) | ||
578 | ERR_print_errors(bio_err); | ||
579 | } | ||
580 | #endif | ||
581 | |||
582 | if (con == NULL) | ||
583 | con=(SSL *)SSL_new(ctx); | ||
584 | SSL_clear(con); | ||
585 | |||
586 | sbio=BIO_new_socket(s,BIO_NOCLOSE); | ||
587 | if (s_nbio_test) | ||
588 | { | ||
589 | BIO *test; | ||
590 | |||
591 | test=BIO_new(BIO_f_nbio_test()); | ||
592 | sbio=BIO_push(test,sbio); | ||
593 | } | ||
594 | SSL_set_bio(con,sbio,sbio); | ||
595 | SSL_set_accept_state(con); | ||
596 | /* SSL_set_fd(con,s); */ | ||
597 | |||
598 | if (s_debug) | ||
599 | { | ||
600 | con->debug=1; | ||
601 | BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); | ||
602 | BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out); | ||
603 | } | ||
604 | |||
605 | width=s+1; | ||
606 | for (;;) | ||
607 | { | ||
608 | FD_ZERO(&readfds); | ||
609 | #ifndef WINDOWS | ||
610 | FD_SET(fileno(stdin),&readfds); | ||
611 | #endif | ||
612 | FD_SET(s,&readfds); | ||
613 | i=select(width,&readfds,NULL,NULL,NULL); | ||
614 | if (i <= 0) continue; | ||
615 | if (FD_ISSET(fileno(stdin),&readfds)) | ||
616 | { | ||
617 | i=read(fileno(stdin),buf,128/*BUFSIZZ*/); | ||
618 | if (!s_quiet) | ||
619 | { | ||
620 | if ((i <= 0) || (buf[0] == 'Q')) | ||
621 | { | ||
622 | BIO_printf(bio_s_out,"DONE\n"); | ||
623 | SHUTDOWN(s); | ||
624 | close_accept_socket(); | ||
625 | ret= -11; | ||
626 | goto err; | ||
627 | } | ||
628 | if ((i <= 0) || (buf[0] == 'q')) | ||
629 | { | ||
630 | BIO_printf(bio_s_out,"DONE\n"); | ||
631 | SHUTDOWN(s); | ||
632 | /* close_accept_socket(); | ||
633 | ret= -11;*/ | ||
634 | goto err; | ||
635 | } | ||
636 | if ((buf[0] == 'r') && | ||
637 | ((buf[1] == '\n') || (buf[1] == '\r'))) | ||
638 | { | ||
639 | SSL_renegotiate(con); | ||
640 | i=SSL_do_handshake(con); | ||
641 | printf("SSL_do_handshake -> %d\n",i); | ||
642 | i=0; /*13; */ | ||
643 | continue; | ||
644 | strcpy(buf,"server side RE-NEGOTIATE\n"); | ||
645 | } | ||
646 | if ((buf[0] == 'R') && | ||
647 | ((buf[1] == '\0') || (buf[1] == '\r'))) | ||
648 | { | ||
649 | SSL_set_verify(con, | ||
650 | SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL); | ||
651 | SSL_renegotiate(con); | ||
652 | i=SSL_do_handshake(con); | ||
653 | printf("SSL_do_handshake -> %d\n",i); | ||
654 | i=0; /* 13; */ | ||
655 | continue; | ||
656 | strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); | ||
657 | } | ||
658 | if (buf[0] == 'P') | ||
659 | { | ||
660 | static char *str="Lets print some clear text\n"; | ||
661 | BIO_write(SSL_get_wbio(con),str,strlen(str)); | ||
662 | } | ||
663 | if (buf[0] == 'S') | ||
664 | { | ||
665 | print_stats(bio_s_out,SSL_get_SSL_CTX(con)); | ||
666 | } | ||
667 | } | ||
668 | l=k=0; | ||
669 | for (;;) | ||
670 | { | ||
671 | /* should do a select for the write */ | ||
672 | #ifdef RENEG | ||
673 | { static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } } | ||
674 | #endif | ||
675 | k=SSL_write(con,&(buf[l]),(unsigned int)i); | ||
676 | switch (SSL_get_error(con,k)) | ||
677 | { | ||
678 | case SSL_ERROR_NONE: | ||
679 | break; | ||
680 | case SSL_ERROR_WANT_WRITE: | ||
681 | case SSL_ERROR_WANT_READ: | ||
682 | case SSL_ERROR_WANT_X509_LOOKUP: | ||
683 | BIO_printf(bio_s_out,"Write BLOCK\n"); | ||
684 | break; | ||
685 | case SSL_ERROR_SYSCALL: | ||
686 | case SSL_ERROR_SSL: | ||
687 | BIO_printf(bio_s_out,"ERROR\n"); | ||
688 | ERR_print_errors(bio_err); | ||
689 | ret=1; | ||
690 | goto err; | ||
691 | break; | ||
692 | case SSL_ERROR_ZERO_RETURN: | ||
693 | BIO_printf(bio_s_out,"DONE\n"); | ||
694 | ret=1; | ||
695 | goto err; | ||
696 | } | ||
697 | l+=k; | ||
698 | i-=k; | ||
699 | if (i <= 0) break; | ||
700 | } | ||
701 | } | ||
702 | if (FD_ISSET(s,&readfds)) | ||
703 | { | ||
704 | if (!SSL_is_init_finished(con)) | ||
705 | { | ||
706 | i=init_ssl_connection(con); | ||
707 | |||
708 | if (i < 0) | ||
709 | { | ||
710 | ret=0; | ||
711 | goto err; | ||
712 | } | ||
713 | else if (i == 0) | ||
714 | { | ||
715 | ret=1; | ||
716 | goto err; | ||
717 | } | ||
718 | } | ||
719 | else | ||
720 | { | ||
721 | i=SSL_read(con,(char *)buf,128 /*BUFSIZZ */); | ||
722 | switch (SSL_get_error(con,i)) | ||
723 | { | ||
724 | case SSL_ERROR_NONE: | ||
725 | write(fileno(stdout),buf, | ||
726 | (unsigned int)i); | ||
727 | break; | ||
728 | case SSL_ERROR_WANT_WRITE: | ||
729 | case SSL_ERROR_WANT_READ: | ||
730 | case SSL_ERROR_WANT_X509_LOOKUP: | ||
731 | BIO_printf(bio_s_out,"Read BLOCK\n"); | ||
732 | break; | ||
733 | case SSL_ERROR_SYSCALL: | ||
734 | case SSL_ERROR_SSL: | ||
735 | BIO_printf(bio_s_out,"ERROR\n"); | ||
736 | ERR_print_errors(bio_err); | ||
737 | ret=1; | ||
738 | goto err; | ||
739 | case SSL_ERROR_ZERO_RETURN: | ||
740 | BIO_printf(bio_s_out,"DONE\n"); | ||
741 | ret=1; | ||
742 | goto err; | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | err: | ||
748 | BIO_printf(bio_s_out,"shutting down SSL\n"); | ||
749 | #if 1 | ||
750 | SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); | ||
751 | #else | ||
752 | SSL_shutdown(con); | ||
753 | #endif | ||
754 | if (con != NULL) SSL_free(con); | ||
755 | BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); | ||
756 | if (buf != NULL) | ||
757 | { | ||
758 | memset(buf,0,BUFSIZZ); | ||
759 | Free(buf); | ||
760 | } | ||
761 | if (ret >= 0) | ||
762 | BIO_printf(bio_s_out,"ACCEPT\n"); | ||
763 | return(ret); | ||
764 | } | ||
765 | |||
766 | static void close_accept_socket() | ||
767 | { | ||
768 | BIO_printf(bio_err,"shutdown accept socket\n"); | ||
769 | if (accept_socket >= 0) | ||
770 | { | ||
771 | SHUTDOWN2(accept_socket); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static int init_ssl_connection(con) | ||
776 | SSL *con; | ||
777 | { | ||
778 | int i; | ||
779 | char *str; | ||
780 | X509 *peer; | ||
781 | long verify_error; | ||
782 | MS_STATIC char buf[BUFSIZ]; | ||
783 | |||
784 | if ((i=SSL_accept(con)) <= 0) | ||
785 | { | ||
786 | if (BIO_sock_should_retry(i)) | ||
787 | { | ||
788 | BIO_printf(bio_s_out,"DELAY\n"); | ||
789 | return(1); | ||
790 | } | ||
791 | |||
792 | BIO_printf(bio_err,"ERROR\n"); | ||
793 | verify_error=SSL_get_verify_result(con); | ||
794 | if (verify_error != X509_V_OK) | ||
795 | { | ||
796 | BIO_printf(bio_err,"verify error:%s\n", | ||
797 | X509_verify_cert_error_string(verify_error)); | ||
798 | } | ||
799 | else | ||
800 | ERR_print_errors(bio_err); | ||
801 | return(0); | ||
802 | } | ||
803 | |||
804 | PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); | ||
805 | |||
806 | peer=SSL_get_peer_certificate(con); | ||
807 | if (peer != NULL) | ||
808 | { | ||
809 | BIO_printf(bio_s_out,"Client certificate\n"); | ||
810 | PEM_write_bio_X509(bio_s_out,peer); | ||
811 | X509_NAME_oneline(X509_get_subject_name(peer),buf,BUFSIZ); | ||
812 | BIO_printf(bio_s_out,"subject=%s\n",buf); | ||
813 | X509_NAME_oneline(X509_get_issuer_name(peer),buf,BUFSIZ); | ||
814 | BIO_printf(bio_s_out,"issuer=%s\n",buf); | ||
815 | X509_free(peer); | ||
816 | } | ||
817 | |||
818 | if (SSL_get_shared_ciphers(con,buf,BUFSIZ) != NULL) | ||
819 | BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); | ||
820 | str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); | ||
821 | BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); | ||
822 | if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); | ||
823 | return(1); | ||
824 | } | ||
825 | |||
826 | #ifndef NO_DH | ||
827 | static DH *load_dh_param() | ||
828 | { | ||
829 | DH *ret=NULL; | ||
830 | BIO *bio; | ||
831 | |||
832 | if ((bio=BIO_new_file(DH_PARAM,"r")) == NULL) | ||
833 | goto err; | ||
834 | ret=PEM_read_bio_DHparams(bio,NULL,NULL); | ||
835 | err: | ||
836 | if (bio != NULL) BIO_free(bio); | ||
837 | return(ret); | ||
838 | } | ||
839 | #endif | ||
840 | |||
841 | #if 0 | ||
842 | static int load_CA(ctx,file) | ||
843 | SSL_CTX *ctx; | ||
844 | char *file; | ||
845 | { | ||
846 | FILE *in; | ||
847 | X509 *x=NULL; | ||
848 | |||
849 | if ((in=fopen(file,"r")) == NULL) | ||
850 | return(0); | ||
851 | |||
852 | for (;;) | ||
853 | { | ||
854 | if (PEM_read_X509(in,&x,NULL) == NULL) | ||
855 | break; | ||
856 | SSL_CTX_add_client_CA(ctx,x); | ||
857 | } | ||
858 | if (x != NULL) X509_free(x); | ||
859 | fclose(in); | ||
860 | return(1); | ||
861 | } | ||
862 | #endif | ||
863 | |||
864 | static int www_body(hostname, s) | ||
865 | char *hostname; | ||
866 | int s; | ||
867 | { | ||
868 | char buf[1024]; | ||
869 | int ret=1; | ||
870 | int i,j,k,blank,dot; | ||
871 | struct stat st_buf; | ||
872 | SSL *con; | ||
873 | SSL_CIPHER *c; | ||
874 | BIO *io,*ssl_bio,*sbio; | ||
875 | long total_bytes; | ||
876 | |||
877 | io=BIO_new(BIO_f_buffer()); | ||
878 | ssl_bio=BIO_new(BIO_f_ssl()); | ||
879 | if ((io == NULL) || (ssl_bio == NULL)) goto err; | ||
880 | |||
881 | #ifdef FIONBIO | ||
882 | if (s_nbio) | ||
883 | { | ||
884 | unsigned long sl=1; | ||
885 | |||
886 | if (!s_quiet) | ||
887 | BIO_printf(bio_err,"turning on non blocking io\n"); | ||
888 | if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) | ||
889 | ERR_print_errors(bio_err); | ||
890 | } | ||
891 | #endif | ||
892 | |||
893 | /* lets make the output buffer a reasonable size */ | ||
894 | if (!BIO_set_write_buffer_size(io,253 /*16*1024*/)) goto err; | ||
895 | |||
896 | if ((con=(SSL *)SSL_new(ctx)) == NULL) goto err; | ||
897 | |||
898 | sbio=BIO_new_socket(s,BIO_NOCLOSE); | ||
899 | if (s_nbio_test) | ||
900 | { | ||
901 | BIO *test; | ||
902 | |||
903 | test=BIO_new(BIO_f_nbio_test()); | ||
904 | sbio=BIO_push(test,sbio); | ||
905 | } | ||
906 | SSL_set_bio(con,sbio,sbio); | ||
907 | SSL_set_accept_state(con); | ||
908 | |||
909 | /* SSL_set_fd(con,s); */ | ||
910 | BIO_set_ssl(ssl_bio,con,BIO_CLOSE); | ||
911 | BIO_push(io,ssl_bio); | ||
912 | |||
913 | if (s_debug) | ||
914 | { | ||
915 | con->debug=1; | ||
916 | BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); | ||
917 | BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out); | ||
918 | } | ||
919 | |||
920 | blank=0; | ||
921 | for (;;) | ||
922 | { | ||
923 | if (hack) | ||
924 | { | ||
925 | i=SSL_accept(con); | ||
926 | |||
927 | switch (SSL_get_error(con,i)) | ||
928 | { | ||
929 | case SSL_ERROR_NONE: | ||
930 | break; | ||
931 | case SSL_ERROR_WANT_WRITE: | ||
932 | case SSL_ERROR_WANT_READ: | ||
933 | case SSL_ERROR_WANT_X509_LOOKUP: | ||
934 | continue; | ||
935 | case SSL_ERROR_SYSCALL: | ||
936 | case SSL_ERROR_SSL: | ||
937 | case SSL_ERROR_ZERO_RETURN: | ||
938 | ret=1; | ||
939 | goto err; | ||
940 | break; | ||
941 | } | ||
942 | |||
943 | SSL_renegotiate(con); | ||
944 | SSL_write(con,NULL,0); | ||
945 | } | ||
946 | |||
947 | i=BIO_gets(io,buf,sizeof(buf)-1); | ||
948 | if (i < 0) /* error */ | ||
949 | { | ||
950 | if (!BIO_should_retry(io)) | ||
951 | { | ||
952 | if (!s_quiet) | ||
953 | ERR_print_errors(bio_err); | ||
954 | goto err; | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | BIO_printf(bio_s_out,"read R BLOCK\n"); | ||
959 | #ifndef MSDOS | ||
960 | sleep(1); | ||
961 | #endif | ||
962 | continue; | ||
963 | } | ||
964 | } | ||
965 | else if (i == 0) /* end of input */ | ||
966 | { | ||
967 | ret=1; | ||
968 | goto end; | ||
969 | } | ||
970 | |||
971 | /* else we have data */ | ||
972 | if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) || | ||
973 | ((www == 2) && (strncmp("GET /stats ",buf,10) == 0))) | ||
974 | { | ||
975 | char *p; | ||
976 | X509 *peer; | ||
977 | STACK *sk; | ||
978 | static char *space=" "; | ||
979 | |||
980 | BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); | ||
981 | BIO_puts(io,"<HTML><BODY BGCOLOR=ffffff>\n"); | ||
982 | BIO_puts(io,"<pre>\n"); | ||
983 | /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ | ||
984 | BIO_puts(io,"\n"); | ||
985 | for (i=0; i<local_argc; i++) | ||
986 | { | ||
987 | BIO_puts(io,local_argv[i]); | ||
988 | BIO_write(io," ",1); | ||
989 | } | ||
990 | BIO_puts(io,"\n"); | ||
991 | |||
992 | /* The following is evil and should not really | ||
993 | * be done */ | ||
994 | BIO_printf(io,"Ciphers supported in s_server binary\n"); | ||
995 | sk=SSL_get_ciphers(con); | ||
996 | j=sk_num(sk); | ||
997 | for (i=0; i<j; i++) | ||
998 | { | ||
999 | c=(SSL_CIPHER *)sk_value(sk,i); | ||
1000 | BIO_printf(io,"%-11s:%-25s", | ||
1001 | SSL_CIPHER_get_version(c), | ||
1002 | SSL_CIPHER_get_name(c)); | ||
1003 | if ((((i+1)%2) == 0) && (i+1 != j)) | ||
1004 | BIO_puts(io,"\n"); | ||
1005 | } | ||
1006 | BIO_puts(io,"\n"); | ||
1007 | p=SSL_get_shared_ciphers(con,buf,sizeof(buf)); | ||
1008 | if (p != NULL) | ||
1009 | { | ||
1010 | BIO_printf(io,"---\nCiphers common between both SSL end points:\n"); | ||
1011 | j=i=0; | ||
1012 | while (*p) | ||
1013 | { | ||
1014 | if (*p == ':') | ||
1015 | { | ||
1016 | BIO_write(io,space,26-j); | ||
1017 | i++; | ||
1018 | j=0; | ||
1019 | BIO_write(io,((i%3)?" ":"\n"),1); | ||
1020 | } | ||
1021 | else | ||
1022 | { | ||
1023 | BIO_write(io,p,1); | ||
1024 | j++; | ||
1025 | } | ||
1026 | p++; | ||
1027 | } | ||
1028 | BIO_puts(io,"\n"); | ||
1029 | } | ||
1030 | BIO_printf(io,((con->hit) | ||
1031 | ?"---\nReused, " | ||
1032 | :"---\nNew, ")); | ||
1033 | c=SSL_get_current_cipher(con); | ||
1034 | BIO_printf(io,"%s, Cipher is %s\n", | ||
1035 | SSL_CIPHER_get_version(c), | ||
1036 | SSL_CIPHER_get_name(c)); | ||
1037 | SSL_SESSION_print(io,SSL_get_session(con)); | ||
1038 | BIO_printf(io,"---\n"); | ||
1039 | print_stats(io,SSL_get_SSL_CTX(con)); | ||
1040 | BIO_printf(io,"---\n"); | ||
1041 | peer=SSL_get_peer_certificate(con); | ||
1042 | if (peer != NULL) | ||
1043 | { | ||
1044 | BIO_printf(io,"Client certificate\n"); | ||
1045 | X509_print(io,peer); | ||
1046 | PEM_write_bio_X509(io,peer); | ||
1047 | } | ||
1048 | else | ||
1049 | BIO_puts(io,"no client certificate available\n"); | ||
1050 | BIO_puts(io,"</BODY></HTML>\r\n\r\n"); | ||
1051 | break; | ||
1052 | } | ||
1053 | else if ((www == 2) && (strncmp("GET ",buf,4) == 0)) | ||
1054 | { | ||
1055 | BIO *file; | ||
1056 | char *p,*e; | ||
1057 | static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; | ||
1058 | |||
1059 | /* skip the '/' */ | ||
1060 | p= &(buf[5]); | ||
1061 | dot=0; | ||
1062 | for (e=p; *e != '\0'; e++) | ||
1063 | { | ||
1064 | if (e[0] == ' ') break; | ||
1065 | if ( (e[0] == '.') && | ||
1066 | (strncmp(&(e[-1]),"/../",4) == 0)) | ||
1067 | dot=1; | ||
1068 | } | ||
1069 | |||
1070 | |||
1071 | if (*e == '\0') | ||
1072 | { | ||
1073 | BIO_puts(io,text); | ||
1074 | BIO_printf(io,"'%s' is an invalid file name\r\n",p); | ||
1075 | break; | ||
1076 | } | ||
1077 | *e='\0'; | ||
1078 | |||
1079 | if (dot) | ||
1080 | { | ||
1081 | BIO_puts(io,text); | ||
1082 | BIO_printf(io,"'%s' contains '..' reference\r\n",p); | ||
1083 | break; | ||
1084 | } | ||
1085 | |||
1086 | if (*p == '/') | ||
1087 | { | ||
1088 | BIO_puts(io,text); | ||
1089 | BIO_printf(io,"'%s' is an invalid path\r\n",p); | ||
1090 | break; | ||
1091 | } | ||
1092 | |||
1093 | /* append if a directory lookup */ | ||
1094 | if (e[-1] == '/') | ||
1095 | strcat(p,"index.html"); | ||
1096 | |||
1097 | /* if a directory, do the index thang */ | ||
1098 | if (stat(p,&st_buf) < 0) | ||
1099 | { | ||
1100 | BIO_puts(io,text); | ||
1101 | BIO_printf(io,"Error accessing '%s'\r\n",p); | ||
1102 | ERR_print_errors(io); | ||
1103 | break; | ||
1104 | } | ||
1105 | if (S_ISDIR(st_buf.st_mode)) | ||
1106 | { | ||
1107 | strcat(p,"/index.html"); | ||
1108 | } | ||
1109 | |||
1110 | if ((file=BIO_new_file(p,"r")) == NULL) | ||
1111 | { | ||
1112 | BIO_puts(io,text); | ||
1113 | BIO_printf(io,"Error opening '%s'\r\n",p); | ||
1114 | ERR_print_errors(io); | ||
1115 | break; | ||
1116 | } | ||
1117 | |||
1118 | if (!s_quiet) | ||
1119 | BIO_printf(bio_err,"FILE:%s\n",p); | ||
1120 | |||
1121 | i=strlen(p); | ||
1122 | if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) || | ||
1123 | ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) || | ||
1124 | ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0))) | ||
1125 | BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); | ||
1126 | else | ||
1127 | BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); | ||
1128 | /* send the file */ | ||
1129 | total_bytes=0; | ||
1130 | for (;;) | ||
1131 | { | ||
1132 | i=BIO_read(file,buf,1024); | ||
1133 | if (i <= 0) break; | ||
1134 | |||
1135 | total_bytes+=i; | ||
1136 | fprintf(stderr,"%d\n",i); | ||
1137 | if (total_bytes > 3*1024) | ||
1138 | { | ||
1139 | total_bytes=0; | ||
1140 | fprintf(stderr,"RENEGOTIATE\n"); | ||
1141 | SSL_renegotiate(con); | ||
1142 | } | ||
1143 | |||
1144 | for (j=0; j<i; ) | ||
1145 | { | ||
1146 | #ifdef RENEG | ||
1147 | { static count=0; if (++count == 13) { SSL_renegotiate(con); } } | ||
1148 | #endif | ||
1149 | k=BIO_write(io,&(buf[j]),i-j); | ||
1150 | if (k <= 0) | ||
1151 | { | ||
1152 | if (!BIO_should_retry(io)) | ||
1153 | goto write_error; | ||
1154 | else | ||
1155 | { | ||
1156 | BIO_printf(bio_s_out,"rwrite W BLOCK\n"); | ||
1157 | } | ||
1158 | } | ||
1159 | else | ||
1160 | { | ||
1161 | j+=k; | ||
1162 | } | ||
1163 | } | ||
1164 | } | ||
1165 | write_error: | ||
1166 | BIO_free(file); | ||
1167 | break; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | for (;;) | ||
1172 | { | ||
1173 | i=(int)BIO_flush(io); | ||
1174 | if (i <= 0) | ||
1175 | { | ||
1176 | if (!BIO_should_retry(io)) | ||
1177 | break; | ||
1178 | } | ||
1179 | else | ||
1180 | break; | ||
1181 | } | ||
1182 | end: | ||
1183 | #if 1 | ||
1184 | /* make sure we re-use sessions */ | ||
1185 | SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); | ||
1186 | #else | ||
1187 | /* This kills performace */ | ||
1188 | /* SSL_shutdown(con); A shutdown gets sent in the | ||
1189 | * BIO_free_all(io) procession */ | ||
1190 | #endif | ||
1191 | |||
1192 | err: | ||
1193 | |||
1194 | if (ret >= 0) | ||
1195 | BIO_printf(bio_s_out,"ACCEPT\n"); | ||
1196 | |||
1197 | if (io != NULL) BIO_free_all(io); | ||
1198 | /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/ | ||
1199 | return(ret); | ||
1200 | } | ||
1201 | |||
1202 | static RSA MS_CALLBACK *tmp_rsa_cb(s,export) | ||
1203 | SSL *s; | ||
1204 | int export; | ||
1205 | { | ||
1206 | static RSA *rsa_tmp=NULL; | ||
1207 | |||
1208 | if (rsa_tmp == NULL) | ||
1209 | { | ||
1210 | if (!s_quiet) | ||
1211 | { | ||
1212 | BIO_printf(bio_err,"Generating temp (512 bit) RSA key..."); | ||
1213 | BIO_flush(bio_err); | ||
1214 | } | ||
1215 | #ifndef NO_RSA | ||
1216 | rsa_tmp=RSA_generate_key(512,RSA_F4,NULL,NULL); | ||
1217 | #endif | ||
1218 | if (!s_quiet) | ||
1219 | { | ||
1220 | BIO_printf(bio_err,"\n"); | ||
1221 | BIO_flush(bio_err); | ||
1222 | } | ||
1223 | } | ||
1224 | return(rsa_tmp); | ||
1225 | } | ||