|
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 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. |
|
60 * |
|
61 * Redistribution and use in source and binary forms, with or without |
|
62 * modification, are permitted provided that the following conditions |
|
63 * are met: |
|
64 * |
|
65 * 1. Redistributions of source code must retain the above copyright |
|
66 * notice, this list of conditions and the following disclaimer. |
|
67 * |
|
68 * 2. Redistributions in binary form must reproduce the above copyright |
|
69 * notice, this list of conditions and the following disclaimer in |
|
70 * the documentation and/or other materials provided with the |
|
71 * distribution. |
|
72 * |
|
73 * 3. All advertising materials mentioning features or use of this |
|
74 * software must display the following acknowledgment: |
|
75 * "This product includes software developed by the OpenSSL Project |
|
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
|
77 * |
|
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
79 * endorse or promote products derived from this software without |
|
80 * prior written permission. For written permission, please contact |
|
81 * openssl-core@openssl.org. |
|
82 * |
|
83 * 5. Products derived from this software may not be called "OpenSSL" |
|
84 * nor may "OpenSSL" appear in their names without prior written |
|
85 * permission of the OpenSSL Project. |
|
86 * |
|
87 * 6. Redistributions of any form whatsoever must retain the following |
|
88 * acknowledgment: |
|
89 * "This product includes software developed by the OpenSSL Project |
|
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
|
91 * |
|
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
103 * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
104 * ==================================================================== |
|
105 * |
|
106 * This product includes cryptographic software written by Eric Young |
|
107 * (eay@cryptsoft.com). This product includes software written by Tim |
|
108 * Hudson (tjh@cryptsoft.com). |
|
109 * |
|
110 */ |
|
111 /* ==================================================================== |
|
112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. |
|
113 * ECC cipher suite support in OpenSSL originally developed by |
|
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. |
|
115 */ |
|
116 |
|
117 /* Until the key-gen callbacks are modified to use newer prototypes, we allow |
|
118 * deprecated functions for openssl-internal code */ |
|
119 #ifdef OPENSSL_NO_DEPRECATED |
|
120 #undef OPENSSL_NO_DEPRECATED |
|
121 #endif |
|
122 |
|
123 #include <assert.h> |
|
124 #include <stdio.h> |
|
125 #include <stdlib.h> |
|
126 #include <string.h> |
|
127 #include <sys/select.h> |
|
128 #include <sys/stat.h> |
|
129 #include <openssl/e_os2.h> |
|
130 #ifdef OPENSSL_NO_STDIO |
|
131 #define APPS_WIN16 |
|
132 #endif |
|
133 |
|
134 #if !defined(OPENSSL_SYS_NETWARE) /* conflicts with winsock2 stuff on netware */ |
|
135 #include <sys/types.h> |
|
136 #endif |
|
137 |
|
138 /* With IPv6, it looks like Digital has mixed up the proper order of |
|
139 recursive header file inclusion, resulting in the compiler complaining |
|
140 that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which |
|
141 is needed to have fileno() declared correctly... So let's define u_int */ |
|
142 #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) |
|
143 #define __U_INT |
|
144 typedef unsigned int u_int; |
|
145 #endif |
|
146 |
|
147 #include <openssl/lhash.h> |
|
148 #include <openssl/bn.h> |
|
149 #define USE_SOCKETS |
|
150 #include "apps.h" |
|
151 #include <openssl/err.h> |
|
152 #include <openssl/pem.h> |
|
153 #include <openssl/x509.h> |
|
154 #include <openssl/ssl.h> |
|
155 #include <openssl/rand.h> |
|
156 #ifndef OPENSSL_NO_DH |
|
157 #include <openssl/dh.h> |
|
158 #endif |
|
159 #ifndef OPENSSL_NO_RSA |
|
160 #include <openssl/rsa.h> |
|
161 #endif |
|
162 #include "s_apps.h" |
|
163 #include "timeouts.h" |
|
164 |
|
165 #ifdef OPENSSL_SYS_WINCE |
|
166 /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */ |
|
167 #ifdef fileno |
|
168 #undef fileno |
|
169 #endif |
|
170 #define fileno(a) (int)_fileno(a) |
|
171 #endif |
|
172 |
|
173 #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) |
|
174 /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ |
|
175 #undef FIONBIO |
|
176 #endif |
|
177 |
|
178 #ifndef OPENSSL_NO_RSA |
|
179 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); |
|
180 #endif |
|
181 static int sv_body(char *hostname, int s, unsigned char *context); |
|
182 static int www_body(char *hostname, int s, unsigned char *context); |
|
183 static void close_accept_socket(void ); |
|
184 static void sv_usage(void); |
|
185 static int init_ssl_connection(SSL *s); |
|
186 static void print_stats(BIO *bp,SSL_CTX *ctx); |
|
187 static int generate_session_id(const SSL *ssl, unsigned char *id, |
|
188 unsigned int *id_len); |
|
189 #ifndef OPENSSL_NO_DH |
|
190 static DH *load_dh_param(const char *dhfile); |
|
191 static DH *get_dh512(void); |
|
192 #endif |
|
193 |
|
194 |
|
195 #ifdef MONOLITH |
|
196 static void s_server_init(void); |
|
197 #endif |
|
198 |
|
199 #ifndef S_ISDIR |
|
200 # if defined(_S_IFMT) && defined(_S_IFDIR) |
|
201 # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) |
|
202 # else |
|
203 # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) |
|
204 # endif |
|
205 #endif |
|
206 |
|
207 #ifndef OPENSSL_NO_DH |
|
208 static unsigned char dh512_p[]={ |
|
209 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, |
|
210 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, |
|
211 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, |
|
212 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, |
|
213 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, |
|
214 0x47,0x74,0xE8,0x33, |
|
215 }; |
|
216 static unsigned char dh512_g[]={ |
|
217 0x02, |
|
218 }; |
|
219 |
|
220 static DH *get_dh512(void) |
|
221 { |
|
222 DH *dh=NULL; |
|
223 |
|
224 if ((dh=DH_new()) == NULL) return(NULL); |
|
225 dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); |
|
226 dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); |
|
227 if ((dh->p == NULL) || (dh->g == NULL)) |
|
228 return(NULL); |
|
229 return(dh); |
|
230 } |
|
231 #endif |
|
232 |
|
233 |
|
234 /* static int load_CA(SSL_CTX *ctx, char *file);*/ |
|
235 |
|
236 #undef BUFSIZZ |
|
237 #define BUFSIZZ 16*1024 |
|
238 static int bufsize=BUFSIZZ; |
|
239 static int accept_socket= -1; |
|
240 |
|
241 #define TEST_CERT "server.pem" |
|
242 #undef PROG |
|
243 #define PROG s_server_main |
|
244 |
|
245 extern int verify_depth; |
|
246 |
|
247 static char *cipher=NULL; |
|
248 static int s_server_verify=SSL_VERIFY_NONE; |
|
249 static int s_server_session_id_context = 1; /* anything will do */ |
|
250 static const char *s_cert_file=TEST_CERT,*s_key_file=NULL; |
|
251 static char *s_dcert_file=NULL,*s_dkey_file=NULL; |
|
252 #ifdef FIONBIO |
|
253 static int s_nbio=0; |
|
254 #endif |
|
255 static int s_nbio_test=0; |
|
256 int s_crlf=0; |
|
257 static SSL_CTX *ctx=NULL; |
|
258 static int www=0; |
|
259 |
|
260 static BIO *bio_s_out=NULL; |
|
261 static int s_debug=0; |
|
262 static int s_msg=0; |
|
263 static int s_quiet=0; |
|
264 |
|
265 static int hack=0; |
|
266 #ifndef OPENSSL_NO_ENGINE |
|
267 static char *engine_id=NULL; |
|
268 #endif |
|
269 static const char *session_id_prefix=NULL; |
|
270 |
|
271 static int enable_timeouts = 0; |
|
272 #ifdef mtu |
|
273 #undef mtu |
|
274 #endif |
|
275 static long mtu; |
|
276 static int cert_chain = 0; |
|
277 |
|
278 |
|
279 #ifdef MONOLITH |
|
280 static void s_server_init(void) |
|
281 { |
|
282 accept_socket=-1; |
|
283 cipher=NULL; |
|
284 s_server_verify=SSL_VERIFY_NONE; |
|
285 s_dcert_file=NULL; |
|
286 s_dkey_file=NULL; |
|
287 s_cert_file=TEST_CERT; |
|
288 s_key_file=NULL; |
|
289 #ifdef FIONBIO |
|
290 s_nbio=0; |
|
291 #endif |
|
292 s_nbio_test=0; |
|
293 ctx=NULL; |
|
294 www=0; |
|
295 |
|
296 bio_s_out=NULL; |
|
297 s_debug=0; |
|
298 s_msg=0; |
|
299 s_quiet=0; |
|
300 hack=0; |
|
301 #ifndef OPENSSL_NO_ENGINE |
|
302 engine_id=NULL; |
|
303 #endif |
|
304 } |
|
305 #endif |
|
306 |
|
307 static void sv_usage(void) |
|
308 { |
|
309 BIO_printf(bio_err,"usage: s_server [args ...]\n"); |
|
310 BIO_printf(bio_err,"\n"); |
|
311 BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT); |
|
312 BIO_printf(bio_err," -context arg - set session ID context\n"); |
|
313 BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); |
|
314 BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); |
|
315 BIO_printf(bio_err," -cert arg - certificate file to use\n"); |
|
316 BIO_printf(bio_err," (default is %s)\n",TEST_CERT); |
|
317 BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n"); |
|
318 BIO_printf(bio_err," -key arg - Private Key file to use, in cert file if\n"); |
|
319 BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT); |
|
320 BIO_printf(bio_err," -keyform arg - key format (PEM, DER or ENGINE) PEM default\n"); |
|
321 BIO_printf(bio_err," -pass arg - private key file pass phrase source\n"); |
|
322 BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n"); |
|
323 BIO_printf(bio_err," -dcertform x - second certificate format (PEM or DER) PEM default\n"); |
|
324 BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n"); |
|
325 BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n"); |
|
326 BIO_printf(bio_err," -dpass arg - second private key file pass phrase source\n"); |
|
327 BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n"); |
|
328 BIO_printf(bio_err," or a default set of parameters is used\n"); |
|
329 #ifndef OPENSSL_NO_ECDH |
|
330 BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ |
|
331 " Use \"openssl ecparam -list_curves\" for all names\n" \ |
|
332 " (default is sect163r2).\n"); |
|
333 #endif |
|
334 #ifdef FIONBIO |
|
335 BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); |
|
336 #endif |
|
337 BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n"); |
|
338 BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n"); |
|
339 BIO_printf(bio_err," -debug - Print more output\n"); |
|
340 BIO_printf(bio_err," -msg - Show protocol messages\n"); |
|
341 BIO_printf(bio_err," -state - Print the SSL states\n"); |
|
342 BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n"); |
|
343 BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n"); |
|
344 BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n"); |
|
345 BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n"); |
|
346 BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n"); |
|
347 BIO_printf(bio_err," -quiet - No server output\n"); |
|
348 BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n"); |
|
349 BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); |
|
350 BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); |
|
351 BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); |
|
352 BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n"); |
|
353 BIO_printf(bio_err," -timeout - Enable timeouts\n"); |
|
354 BIO_printf(bio_err," -mtu - Set MTU\n"); |
|
355 BIO_printf(bio_err," -chain - Read a certificate chain\n"); |
|
356 BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n"); |
|
357 BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n"); |
|
358 BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n"); |
|
359 #ifndef OPENSSL_NO_DH |
|
360 BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n"); |
|
361 #endif |
|
362 #ifndef OPENSSL_NO_ECDH |
|
363 BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n"); |
|
364 #endif |
|
365 BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n"); |
|
366 BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n"); |
|
367 BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); |
|
368 BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); |
|
369 BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n"); |
|
370 #ifndef OPENSSL_NO_ENGINE |
|
371 BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n"); |
|
372 #endif |
|
373 BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); |
|
374 BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); |
|
375 } |
|
376 |
|
377 static int local_argc=0; |
|
378 static char **local_argv; |
|
379 |
|
380 #ifdef CHARSET_EBCDIC |
|
381 static int ebcdic_new(BIO *bi); |
|
382 static int ebcdic_free(BIO *a); |
|
383 static int ebcdic_read(BIO *b, char *out, int outl); |
|
384 static int ebcdic_write(BIO *b, const char *in, int inl); |
|
385 static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); |
|
386 static int ebcdic_gets(BIO *bp, char *buf, int size); |
|
387 static int ebcdic_puts(BIO *bp, const char *str); |
|
388 |
|
389 #define BIO_TYPE_EBCDIC_FILTER (18|0x0200) |
|
390 static BIO_METHOD methods_ebcdic= |
|
391 { |
|
392 BIO_TYPE_EBCDIC_FILTER, |
|
393 "EBCDIC/ASCII filter", |
|
394 ebcdic_write, |
|
395 ebcdic_read, |
|
396 ebcdic_puts, |
|
397 ebcdic_gets, |
|
398 ebcdic_ctrl, |
|
399 ebcdic_new, |
|
400 ebcdic_free, |
|
401 }; |
|
402 |
|
403 typedef struct |
|
404 { |
|
405 size_t alloced; |
|
406 char buff[1]; |
|
407 } EBCDIC_OUTBUFF; |
|
408 |
|
409 BIO_METHOD *BIO_f_ebcdic_filter() |
|
410 { |
|
411 return(&methods_ebcdic); |
|
412 } |
|
413 |
|
414 static int ebcdic_new(BIO *bi) |
|
415 { |
|
416 EBCDIC_OUTBUFF *wbuf; |
|
417 |
|
418 wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024); |
|
419 wbuf->alloced = 1024; |
|
420 wbuf->buff[0] = '\0'; |
|
421 |
|
422 bi->ptr=(char *)wbuf; |
|
423 bi->init=1; |
|
424 bi->flags=0; |
|
425 return(1); |
|
426 } |
|
427 |
|
428 static int ebcdic_free(BIO *a) |
|
429 { |
|
430 if (a == NULL) return(0); |
|
431 if (a->ptr != NULL) |
|
432 OPENSSL_free(a->ptr); |
|
433 a->ptr=NULL; |
|
434 a->init=0; |
|
435 a->flags=0; |
|
436 return(1); |
|
437 } |
|
438 |
|
439 static int ebcdic_read(BIO *b, char *out, int outl) |
|
440 { |
|
441 int ret=0; |
|
442 |
|
443 if (out == NULL || outl == 0) return(0); |
|
444 if (b->next_bio == NULL) return(0); |
|
445 |
|
446 ret=BIO_read(b->next_bio,out,outl); |
|
447 if (ret > 0) |
|
448 ascii2ebcdic(out,out,ret); |
|
449 return(ret); |
|
450 } |
|
451 |
|
452 static int ebcdic_write(BIO *b, const char *in, int inl) |
|
453 { |
|
454 EBCDIC_OUTBUFF *wbuf; |
|
455 int ret=0; |
|
456 int num; |
|
457 unsigned char n; |
|
458 |
|
459 if ((in == NULL) || (inl <= 0)) return(0); |
|
460 if (b->next_bio == NULL) return(0); |
|
461 |
|
462 wbuf=(EBCDIC_OUTBUFF *)b->ptr; |
|
463 |
|
464 if (inl > (num = wbuf->alloced)) |
|
465 { |
|
466 num = num + num; /* double the size */ |
|
467 if (num < inl) |
|
468 num = inl; |
|
469 OPENSSL_free(wbuf); |
|
470 wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); |
|
471 |
|
472 wbuf->alloced = num; |
|
473 wbuf->buff[0] = '\0'; |
|
474 |
|
475 b->ptr=(char *)wbuf; |
|
476 } |
|
477 |
|
478 ebcdic2ascii(wbuf->buff, in, inl); |
|
479 |
|
480 ret=BIO_write(b->next_bio, wbuf->buff, inl); |
|
481 |
|
482 return(ret); |
|
483 } |
|
484 |
|
485 static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) |
|
486 { |
|
487 long ret; |
|
488 |
|
489 if (b->next_bio == NULL) return(0); |
|
490 switch (cmd) |
|
491 { |
|
492 case BIO_CTRL_DUP: |
|
493 ret=0L; |
|
494 break; |
|
495 default: |
|
496 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); |
|
497 break; |
|
498 } |
|
499 return(ret); |
|
500 } |
|
501 |
|
502 static int ebcdic_gets(BIO *bp, char *buf, int size) |
|
503 { |
|
504 int i, ret=0; |
|
505 if (bp->next_bio == NULL) return(0); |
|
506 /* return(BIO_gets(bp->next_bio,buf,size));*/ |
|
507 for (i=0; i<size-1; ++i) |
|
508 { |
|
509 ret = ebcdic_read(bp,&buf[i],1); |
|
510 if (ret <= 0) |
|
511 break; |
|
512 else if (buf[i] == '\n') |
|
513 { |
|
514 ++i; |
|
515 break; |
|
516 } |
|
517 } |
|
518 if (i < size) |
|
519 buf[i] = '\0'; |
|
520 return (ret < 0 && i == 0) ? ret : i; |
|
521 } |
|
522 |
|
523 static int ebcdic_puts(BIO *bp, const char *str) |
|
524 { |
|
525 if (bp->next_bio == NULL) return(0); |
|
526 return ebcdic_write(bp, str, strlen(str)); |
|
527 } |
|
528 #endif |
|
529 |
|
530 int MAIN(int, char **); |
|
531 |
|
532 int MAIN(int argc, char *argv[]) |
|
533 { |
|
534 X509_STORE *store = NULL; |
|
535 int vflags = 0; |
|
536 short port=PORT; |
|
537 char *CApath=NULL,*CAfile=NULL; |
|
538 unsigned char *context = NULL; |
|
539 char *dhfile = NULL; |
|
540 #ifndef OPENSSL_NO_ECDH |
|
541 char *named_curve = NULL; |
|
542 #endif |
|
543 int badop=0,bugs=0; |
|
544 int ret=1; |
|
545 int off=0; |
|
546 int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0; |
|
547 int state=0; |
|
548 SSL_METHOD *meth=NULL; |
|
549 int socket_type=SOCK_STREAM; |
|
550 #ifndef OPENSSL_NO_ENGINE |
|
551 ENGINE *e=NULL; |
|
552 #endif |
|
553 char *inrand=NULL; |
|
554 int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; |
|
555 char *passarg = NULL, *pass = NULL; |
|
556 char *dpassarg = NULL, *dpass = NULL; |
|
557 int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; |
|
558 X509 *s_cert = NULL, *s_dcert = NULL; |
|
559 EVP_PKEY *s_key = NULL, *s_dkey = NULL; |
|
560 |
|
561 |
|
562 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) |
|
563 meth=SSLv23_server_method(); |
|
564 #elif !defined(OPENSSL_NO_SSL3) |
|
565 meth=SSLv3_server_method(); |
|
566 #elif !defined(OPENSSL_NO_SSL2) |
|
567 meth=SSLv2_server_method(); |
|
568 #endif |
|
569 |
|
570 local_argc=argc; |
|
571 local_argv=argv; |
|
572 |
|
573 apps_startup(); |
|
574 #ifdef MONOLITH |
|
575 s_server_init(); |
|
576 #endif |
|
577 |
|
578 if (bio_err == NULL) |
|
579 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); |
|
580 |
|
581 if (!load_config(bio_err, NULL)) |
|
582 goto end; |
|
583 |
|
584 verify_depth=0; |
|
585 #ifdef FIONBIO |
|
586 s_nbio=0; |
|
587 #endif |
|
588 s_nbio_test=0; |
|
589 |
|
590 argc--; |
|
591 argv++; |
|
592 |
|
593 while (argc >= 1) |
|
594 { |
|
595 if ((strcmp(*argv,"-port") == 0) || |
|
596 (strcmp(*argv,"-accept") == 0)) |
|
597 { |
|
598 if (--argc < 1) goto bad; |
|
599 if (!extract_port(*(++argv),&port)) |
|
600 goto bad; |
|
601 } |
|
602 else if (strcmp(*argv,"-verify") == 0) |
|
603 { |
|
604 s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE; |
|
605 if (--argc < 1) goto bad; |
|
606 verify_depth=atoi(*(++argv)); |
|
607 BIO_printf(bio_err,"verify depth is %d\n",verify_depth); |
|
608 } |
|
609 else if (strcmp(*argv,"-Verify") == 0) |
|
610 { |
|
611 s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| |
|
612 SSL_VERIFY_CLIENT_ONCE; |
|
613 if (--argc < 1) goto bad; |
|
614 verify_depth=atoi(*(++argv)); |
|
615 BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth); |
|
616 } |
|
617 else if (strcmp(*argv,"-context") == 0) |
|
618 { |
|
619 if (--argc < 1) goto bad; |
|
620 context= (unsigned char *)*(++argv); |
|
621 } |
|
622 else if (strcmp(*argv,"-cert") == 0) |
|
623 { |
|
624 if (--argc < 1) goto bad; |
|
625 s_cert_file= *(++argv); |
|
626 } |
|
627 else if (strcmp(*argv,"-certform") == 0) |
|
628 { |
|
629 if (--argc < 1) goto bad; |
|
630 s_cert_format = str2fmt(*(++argv)); |
|
631 } |
|
632 else if (strcmp(*argv,"-key") == 0) |
|
633 { |
|
634 if (--argc < 1) goto bad; |
|
635 s_key_file= *(++argv); |
|
636 } |
|
637 else if (strcmp(*argv,"-keyform") == 0) |
|
638 { |
|
639 if (--argc < 1) goto bad; |
|
640 s_key_format = str2fmt(*(++argv)); |
|
641 } |
|
642 else if (strcmp(*argv,"-pass") == 0) |
|
643 { |
|
644 if (--argc < 1) goto bad; |
|
645 passarg = *(++argv); |
|
646 } |
|
647 else if (strcmp(*argv,"-dhparam") == 0) |
|
648 { |
|
649 if (--argc < 1) goto bad; |
|
650 dhfile = *(++argv); |
|
651 } |
|
652 #ifndef OPENSSL_NO_ECDH |
|
653 else if (strcmp(*argv,"-named_curve") == 0) |
|
654 { |
|
655 if (--argc < 1) goto bad; |
|
656 named_curve = *(++argv); |
|
657 } |
|
658 #endif |
|
659 else if (strcmp(*argv,"-dcertform") == 0) |
|
660 { |
|
661 if (--argc < 1) goto bad; |
|
662 s_dcert_format = str2fmt(*(++argv)); |
|
663 } |
|
664 else if (strcmp(*argv,"-dcert") == 0) |
|
665 { |
|
666 if (--argc < 1) goto bad; |
|
667 s_dcert_file= *(++argv); |
|
668 } |
|
669 else if (strcmp(*argv,"-dkeyform") == 0) |
|
670 { |
|
671 if (--argc < 1) goto bad; |
|
672 s_dkey_format = str2fmt(*(++argv)); |
|
673 } |
|
674 else if (strcmp(*argv,"-dpass") == 0) |
|
675 { |
|
676 if (--argc < 1) goto bad; |
|
677 dpassarg = *(++argv); |
|
678 } |
|
679 else if (strcmp(*argv,"-dkey") == 0) |
|
680 { |
|
681 if (--argc < 1) goto bad; |
|
682 s_dkey_file= *(++argv); |
|
683 } |
|
684 else if (strcmp(*argv,"-nocert") == 0) |
|
685 { |
|
686 nocert=1; |
|
687 } |
|
688 else if (strcmp(*argv,"-CApath") == 0) |
|
689 { |
|
690 if (--argc < 1) goto bad; |
|
691 CApath= *(++argv); |
|
692 } |
|
693 else if (strcmp(*argv,"-crl_check") == 0) |
|
694 { |
|
695 vflags |= X509_V_FLAG_CRL_CHECK; |
|
696 } |
|
697 else if (strcmp(*argv,"-crl_check") == 0) |
|
698 { |
|
699 vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; |
|
700 } |
|
701 else if (strcmp(*argv,"-serverpref") == 0) |
|
702 { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } |
|
703 else if (strcmp(*argv,"-cipher") == 0) |
|
704 { |
|
705 if (--argc < 1) goto bad; |
|
706 cipher= *(++argv); |
|
707 } |
|
708 else if (strcmp(*argv,"-CAfile") == 0) |
|
709 { |
|
710 if (--argc < 1) goto bad; |
|
711 CAfile= *(++argv); |
|
712 } |
|
713 #ifdef FIONBIO |
|
714 else if (strcmp(*argv,"-nbio") == 0) |
|
715 { s_nbio=1; } |
|
716 #endif |
|
717 else if (strcmp(*argv,"-nbio_test") == 0) |
|
718 { |
|
719 #ifdef FIONBIO |
|
720 s_nbio=1; |
|
721 #endif |
|
722 s_nbio_test=1; |
|
723 } |
|
724 else if (strcmp(*argv,"-debug") == 0) |
|
725 { s_debug=1; } |
|
726 else if (strcmp(*argv,"-msg") == 0) |
|
727 { s_msg=1; } |
|
728 else if (strcmp(*argv,"-hack") == 0) |
|
729 { hack=1; } |
|
730 else if (strcmp(*argv,"-state") == 0) |
|
731 { state=1; } |
|
732 else if (strcmp(*argv,"-crlf") == 0) |
|
733 { s_crlf=1; } |
|
734 else if (strcmp(*argv,"-quiet") == 0) |
|
735 { s_quiet=1; } |
|
736 else if (strcmp(*argv,"-bugs") == 0) |
|
737 { bugs=1; } |
|
738 else if (strcmp(*argv,"-no_tmp_rsa") == 0) |
|
739 { no_tmp_rsa=1; } |
|
740 else if (strcmp(*argv,"-no_dhe") == 0) |
|
741 { no_dhe=1; } |
|
742 else if (strcmp(*argv,"-no_ecdhe") == 0) |
|
743 { no_ecdhe=1; } |
|
744 else if (strcmp(*argv,"-www") == 0) |
|
745 { www=1; } |
|
746 else if (strcmp(*argv,"-WWW") == 0) |
|
747 { www=2; } |
|
748 else if (strcmp(*argv,"-HTTP") == 0) |
|
749 { www=3; } |
|
750 else if (strcmp(*argv,"-no_ssl2") == 0) |
|
751 { off|=SSL_OP_NO_SSLv2; } |
|
752 else if (strcmp(*argv,"-no_ssl3") == 0) |
|
753 { off|=SSL_OP_NO_SSLv3; } |
|
754 else if (strcmp(*argv,"-no_tls1") == 0) |
|
755 { off|=SSL_OP_NO_TLSv1; } |
|
756 #ifndef OPENSSL_NO_SSL2 |
|
757 else if (strcmp(*argv,"-ssl2") == 0) |
|
758 { meth=SSLv2_server_method(); } |
|
759 #endif |
|
760 #ifndef OPENSSL_NO_SSL3 |
|
761 else if (strcmp(*argv,"-ssl3") == 0) |
|
762 { meth=SSLv3_server_method(); } |
|
763 #endif |
|
764 #ifndef OPENSSL_NO_TLS1 |
|
765 else if (strcmp(*argv,"-tls1") == 0) |
|
766 { meth=TLSv1_server_method(); } |
|
767 #endif |
|
768 #ifndef OPENSSL_NO_DTLS1 |
|
769 else if (strcmp(*argv,"-dtls1") == 0) |
|
770 { |
|
771 meth=DTLSv1_server_method(); |
|
772 socket_type = SOCK_DGRAM; |
|
773 } |
|
774 else if (strcmp(*argv,"-timeout") == 0) |
|
775 enable_timeouts = 1; |
|
776 else if (strcmp(*argv,"-mtu") == 0) |
|
777 { |
|
778 if (--argc < 1) goto bad; |
|
779 mtu = atol(*(++argv)); |
|
780 } |
|
781 else if (strcmp(*argv, "-chain") == 0) |
|
782 cert_chain = 1; |
|
783 #endif |
|
784 else if (strcmp(*argv, "-id_prefix") == 0) |
|
785 { |
|
786 if (--argc < 1) goto bad; |
|
787 session_id_prefix = *(++argv); |
|
788 } |
|
789 #ifndef OPENSSL_NO_ENGINE |
|
790 else if (strcmp(*argv,"-engine") == 0) |
|
791 { |
|
792 if (--argc < 1) goto bad; |
|
793 engine_id= *(++argv); |
|
794 } |
|
795 #endif |
|
796 else if (strcmp(*argv,"-rand") == 0) |
|
797 { |
|
798 if (--argc < 1) goto bad; |
|
799 inrand= *(++argv); |
|
800 } |
|
801 else |
|
802 { |
|
803 BIO_printf(bio_err,"unknown option %s\n",*argv); |
|
804 badop=1; |
|
805 break; |
|
806 } |
|
807 argc--; |
|
808 argv++; |
|
809 } |
|
810 if (badop) |
|
811 { |
|
812 bad: |
|
813 sv_usage(); |
|
814 goto end; |
|
815 } |
|
816 |
|
817 SSL_load_error_strings(); |
|
818 OpenSSL_add_ssl_algorithms(); |
|
819 |
|
820 #ifndef OPENSSL_NO_ENGINE |
|
821 e = setup_engine(bio_err, engine_id, 1); |
|
822 #endif |
|
823 |
|
824 if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) |
|
825 { |
|
826 BIO_printf(bio_err, "Error getting password\n"); |
|
827 goto end; |
|
828 } |
|
829 |
|
830 |
|
831 if (s_key_file == NULL) |
|
832 s_key_file = s_cert_file; |
|
833 |
|
834 if (nocert == 0) |
|
835 { |
|
836 s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e, |
|
837 "server certificate private key file"); |
|
838 if (!s_key) |
|
839 { |
|
840 ERR_print_errors(bio_err); |
|
841 goto end; |
|
842 } |
|
843 |
|
844 s_cert = load_cert(bio_err,s_cert_file,s_cert_format, |
|
845 NULL, e, "server certificate file"); |
|
846 |
|
847 if (!s_cert) |
|
848 { |
|
849 ERR_print_errors(bio_err); |
|
850 goto end; |
|
851 } |
|
852 |
|
853 } |
|
854 if (s_dcert_file) |
|
855 { |
|
856 |
|
857 if (s_dkey_file == NULL) |
|
858 s_dkey_file = s_dcert_file; |
|
859 |
|
860 s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format, |
|
861 0, dpass, e, |
|
862 "second certificate private key file"); |
|
863 if (!s_dkey) |
|
864 { |
|
865 ERR_print_errors(bio_err); |
|
866 goto end; |
|
867 } |
|
868 |
|
869 s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format, |
|
870 NULL, e, "second server certificate file"); |
|
871 |
|
872 if (!s_dcert) |
|
873 { |
|
874 ERR_print_errors(bio_err); |
|
875 goto end; |
|
876 } |
|
877 |
|
878 } |
|
879 |
|
880 if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL |
|
881 && !RAND_status()) |
|
882 { |
|
883 BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); |
|
884 } |
|
885 if (inrand != NULL) |
|
886 BIO_printf(bio_err,"%ld semi-random bytes loaded\n", |
|
887 app_RAND_load_files(inrand)); |
|
888 |
|
889 if (bio_s_out == NULL) |
|
890 { |
|
891 if (s_quiet && !s_debug && !s_msg) |
|
892 { |
|
893 bio_s_out=BIO_new(BIO_s_null()); |
|
894 } |
|
895 else |
|
896 { |
|
897 if (bio_s_out == NULL) |
|
898 bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE); |
|
899 |
|
900 } |
|
901 } |
|
902 |
|
903 #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) |
|
904 if (nocert) |
|
905 #endif |
|
906 { |
|
907 s_cert_file=NULL; |
|
908 s_key_file=NULL; |
|
909 s_dcert_file=NULL; |
|
910 s_dkey_file=NULL; |
|
911 } |
|
912 |
|
913 ctx=SSL_CTX_new(meth); |
|
914 if (ctx == NULL) |
|
915 { |
|
916 ERR_print_errors(bio_err); |
|
917 goto end; |
|
918 } |
|
919 if (session_id_prefix) |
|
920 { |
|
921 if(strlen(session_id_prefix) >= 32) |
|
922 BIO_printf(bio_err, |
|
923 "warning: id_prefix is too long, only one new session will be possible\n"); |
|
924 else if(strlen(session_id_prefix) >= 16) |
|
925 BIO_printf(bio_err, |
|
926 "warning: id_prefix is too long if you use SSLv2\n"); |
|
927 if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) |
|
928 { |
|
929 BIO_printf(bio_err,"error setting 'id_prefix'\n"); |
|
930 ERR_print_errors(bio_err); |
|
931 goto end; |
|
932 } |
|
933 BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); |
|
934 } |
|
935 SSL_CTX_set_quiet_shutdown(ctx,1); |
|
936 if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL); |
|
937 if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); |
|
938 SSL_CTX_set_options(ctx,off); |
|
939 /* DTLS: partial reads end up discarding unread UDP bytes :-( |
|
940 * Setting read ahead solves this problem. |
|
941 */ |
|
942 if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); |
|
943 |
|
944 if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); |
|
945 |
|
946 SSL_CTX_sess_set_cache_size(ctx,128); |
|
947 |
|
948 #if 0 |
|
949 if (cipher == NULL) cipher=getenv("SSL_CIPHER"); |
|
950 #endif |
|
951 |
|
952 #if 0 |
|
953 if (s_cert_file == NULL) |
|
954 { |
|
955 BIO_printf(bio_err,"You must specify a certificate file for the server to use\n"); |
|
956 goto end; |
|
957 } |
|
958 #endif |
|
959 |
|
960 if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || |
|
961 (!SSL_CTX_set_default_verify_paths(ctx))) |
|
962 { |
|
963 /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ |
|
964 ERR_print_errors(bio_err); |
|
965 /* goto end; */ |
|
966 } |
|
967 store = SSL_CTX_get_cert_store(ctx); |
|
968 X509_STORE_set_flags(store, vflags); |
|
969 |
|
970 #ifndef OPENSSL_NO_DH |
|
971 if (!no_dhe) |
|
972 { |
|
973 DH *dh=NULL; |
|
974 |
|
975 if (dhfile) |
|
976 dh = load_dh_param(dhfile); |
|
977 else if (s_cert_file) |
|
978 dh = load_dh_param(s_cert_file); |
|
979 |
|
980 if (dh != NULL) |
|
981 { |
|
982 BIO_printf(bio_s_out,"Setting temp DH parameters\n"); |
|
983 } |
|
984 else |
|
985 { |
|
986 BIO_printf(bio_s_out,"Using default temp DH parameters\n"); |
|
987 dh=get_dh512(); |
|
988 } |
|
989 (void)BIO_flush(bio_s_out); |
|
990 |
|
991 SSL_CTX_set_tmp_dh(ctx,dh); |
|
992 DH_free(dh); |
|
993 } |
|
994 #endif |
|
995 |
|
996 #ifndef OPENSSL_NO_ECDH |
|
997 if (!no_ecdhe) |
|
998 { |
|
999 EC_KEY *ecdh=NULL; |
|
1000 |
|
1001 if (named_curve) |
|
1002 { |
|
1003 int nid = OBJ_sn2nid(named_curve); |
|
1004 |
|
1005 if (nid == 0) |
|
1006 { |
|
1007 BIO_printf(bio_err, "unknown curve name (%s)\n", |
|
1008 named_curve); |
|
1009 goto end; |
|
1010 } |
|
1011 ecdh = EC_KEY_new_by_curve_name(nid); |
|
1012 if (ecdh == NULL) |
|
1013 { |
|
1014 BIO_printf(bio_err, "unable to create curve (%s)\n", |
|
1015 named_curve); |
|
1016 goto end; |
|
1017 } |
|
1018 } |
|
1019 |
|
1020 if (ecdh != NULL) |
|
1021 { |
|
1022 BIO_printf(bio_s_out,"Setting temp ECDH parameters\n"); |
|
1023 } |
|
1024 else |
|
1025 { |
|
1026 BIO_printf(bio_s_out,"Using default temp ECDH parameters\n"); |
|
1027 ecdh = EC_KEY_new_by_curve_name(NID_sect163r2); |
|
1028 if (ecdh == NULL) |
|
1029 { |
|
1030 BIO_printf(bio_err, "unable to create curve (sect163r2)\n"); |
|
1031 goto end; |
|
1032 } |
|
1033 } |
|
1034 (void)BIO_flush(bio_s_out); |
|
1035 |
|
1036 SSL_CTX_set_tmp_ecdh(ctx,ecdh); |
|
1037 |
|
1038 EC_KEY_free(ecdh); |
|
1039 } |
|
1040 #endif |
|
1041 |
|
1042 if (!set_cert_key_stuff(ctx,s_cert,s_key)) |
|
1043 goto end; |
|
1044 |
|
1045 if (s_dcert != NULL) |
|
1046 { |
|
1047 if (!set_cert_key_stuff(ctx,s_dcert,s_dkey)) |
|
1048 goto end; |
|
1049 } |
|
1050 |
|
1051 #ifndef OPENSSL_NO_RSA |
|
1052 #if 1 |
|
1053 if (!no_tmp_rsa) |
|
1054 { |
|
1055 SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); |
|
1056 |
|
1057 } |
|
1058 #else |
|
1059 if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) |
|
1060 { |
|
1061 RSA *rsa; |
|
1062 |
|
1063 BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key..."); |
|
1064 BIO_flush(bio_s_out); |
|
1065 |
|
1066 rsa=RSA_generate_key(512,RSA_F4,NULL); |
|
1067 |
|
1068 if (!SSL_CTX_set_tmp_rsa(ctx,rsa)) |
|
1069 { |
|
1070 ERR_print_errors(bio_err); |
|
1071 goto end; |
|
1072 } |
|
1073 RSA_free(rsa); |
|
1074 BIO_printf(bio_s_out,"\n"); |
|
1075 } |
|
1076 #endif |
|
1077 #endif |
|
1078 |
|
1079 if (cipher != NULL) |
|
1080 if(!SSL_CTX_set_cipher_list(ctx,cipher)) { |
|
1081 BIO_printf(bio_err,"error setting cipher list\n"); |
|
1082 ERR_print_errors(bio_err); |
|
1083 goto end; |
|
1084 } |
|
1085 SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); |
|
1086 SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, |
|
1087 sizeof s_server_session_id_context); |
|
1088 |
|
1089 if (CAfile != NULL) |
|
1090 { |
|
1091 SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); |
|
1092 } |
|
1093 BIO_printf(bio_s_out,"ACCEPT\n"); |
|
1094 if (www) |
|
1095 do_server(port,socket_type,&accept_socket,www_body, context); |
|
1096 else |
|
1097 do_server(port,socket_type,&accept_socket,sv_body, context); |
|
1098 print_stats(bio_s_out,ctx); |
|
1099 ret=0; |
|
1100 end: |
|
1101 if (ctx != NULL) SSL_CTX_free(ctx); |
|
1102 if (s_cert) |
|
1103 X509_free(s_cert); |
|
1104 if (s_dcert) |
|
1105 X509_free(s_dcert); |
|
1106 if (s_key) |
|
1107 EVP_PKEY_free(s_key); |
|
1108 if (s_dkey) |
|
1109 EVP_PKEY_free(s_dkey); |
|
1110 if (pass) |
|
1111 OPENSSL_free(pass); |
|
1112 if (dpass) |
|
1113 OPENSSL_free(dpass); |
|
1114 if (bio_s_out != NULL) |
|
1115 { |
|
1116 BIO_free(bio_s_out); |
|
1117 bio_s_out=NULL; |
|
1118 } |
|
1119 apps_shutdown(); |
|
1120 OPENSSL_EXIT(ret); |
|
1121 } |
|
1122 |
|
1123 static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) |
|
1124 { |
|
1125 BIO_printf(bio,"%4ld items in the session cache\n", |
|
1126 SSL_CTX_sess_number(ssl_ctx)); |
|
1127 BIO_printf(bio,"%4ld client connects (SSL_connect())\n", |
|
1128 SSL_CTX_sess_connect(ssl_ctx)); |
|
1129 BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n", |
|
1130 SSL_CTX_sess_connect_renegotiate(ssl_ctx)); |
|
1131 BIO_printf(bio,"%4ld client connects that finished\n", |
|
1132 SSL_CTX_sess_connect_good(ssl_ctx)); |
|
1133 BIO_printf(bio,"%4ld server accepts (SSL_accept())\n", |
|
1134 SSL_CTX_sess_accept(ssl_ctx)); |
|
1135 BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n", |
|
1136 SSL_CTX_sess_accept_renegotiate(ssl_ctx)); |
|
1137 BIO_printf(bio,"%4ld server accepts that finished\n", |
|
1138 SSL_CTX_sess_accept_good(ssl_ctx)); |
|
1139 BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx)); |
|
1140 BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx)); |
|
1141 BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx)); |
|
1142 BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx)); |
|
1143 BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n", |
|
1144 SSL_CTX_sess_cache_full(ssl_ctx), |
|
1145 SSL_CTX_sess_get_cache_size(ssl_ctx)); |
|
1146 } |
|
1147 |
|
1148 static int sv_body(char *hostname, int s, unsigned char *context) |
|
1149 { |
|
1150 char *buf=NULL; |
|
1151 fd_set readfds; |
|
1152 int ret=1,width; |
|
1153 int k,i; |
|
1154 unsigned long l; |
|
1155 SSL *con=NULL; |
|
1156 BIO *sbio; |
|
1157 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) |
|
1158 struct timeval tv; |
|
1159 #endif |
|
1160 |
|
1161 if ((buf=OPENSSL_malloc(bufsize)) == NULL) |
|
1162 { |
|
1163 BIO_printf(bio_err,"out of memory\n"); |
|
1164 goto err; |
|
1165 } |
|
1166 #ifdef FIONBIO |
|
1167 if (s_nbio) |
|
1168 { |
|
1169 unsigned long sl=1; |
|
1170 |
|
1171 if (!s_quiet) |
|
1172 BIO_printf(bio_err,"turning on non blocking io\n"); |
|
1173 if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) |
|
1174 ERR_print_errors(bio_err); |
|
1175 } |
|
1176 #endif |
|
1177 |
|
1178 if (con == NULL) { |
|
1179 con=SSL_new(ctx); |
|
1180 #ifndef OPENSSL_NO_KRB5 |
|
1181 if ((con->kssl_ctx = kssl_ctx_new()) != NULL) |
|
1182 { |
|
1183 kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, |
|
1184 KRB5SVC); |
|
1185 kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, |
|
1186 KRB5KEYTAB); |
|
1187 } |
|
1188 #endif /* OPENSSL_NO_KRB5 */ |
|
1189 if(context) |
|
1190 SSL_set_session_id_context(con, context, |
|
1191 strlen((char *)context)); |
|
1192 } |
|
1193 SSL_clear(con); |
|
1194 |
|
1195 if (SSL_version(con) == DTLS1_VERSION) |
|
1196 { |
|
1197 struct timeval timeout; |
|
1198 |
|
1199 sbio=BIO_new_dgram(s,BIO_NOCLOSE); |
|
1200 |
|
1201 if ( enable_timeouts) |
|
1202 { |
|
1203 timeout.tv_sec = 0; |
|
1204 timeout.tv_usec = DGRAM_RCV_TIMEOUT; |
|
1205 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); |
|
1206 |
|
1207 timeout.tv_sec = 0; |
|
1208 timeout.tv_usec = DGRAM_SND_TIMEOUT; |
|
1209 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); |
|
1210 } |
|
1211 |
|
1212 |
|
1213 if ( mtu > 0) |
|
1214 { |
|
1215 SSL_set_options(con, SSL_OP_NO_QUERY_MTU); |
|
1216 SSL_set_mtu(con, mtu); |
|
1217 } |
|
1218 else |
|
1219 /* want to do MTU discovery */ |
|
1220 BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); |
|
1221 |
|
1222 /* turn on cookie exchange */ |
|
1223 SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); |
|
1224 } |
|
1225 else |
|
1226 sbio=BIO_new_socket(s,BIO_NOCLOSE); |
|
1227 |
|
1228 if (s_nbio_test) |
|
1229 { |
|
1230 BIO *test; |
|
1231 |
|
1232 test=BIO_new(BIO_f_nbio_test()); |
|
1233 sbio=BIO_push(test,sbio); |
|
1234 } |
|
1235 SSL_set_bio(con,sbio,sbio); |
|
1236 SSL_set_accept_state(con); |
|
1237 /* SSL_set_fd(con,s); */ |
|
1238 |
|
1239 if (s_debug) |
|
1240 { |
|
1241 con->debug=1; |
|
1242 BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); |
|
1243 BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); |
|
1244 } |
|
1245 if (s_msg) |
|
1246 { |
|
1247 SSL_set_msg_callback(con, msg_cb); |
|
1248 SSL_set_msg_callback_arg(con, bio_s_out); |
|
1249 } |
|
1250 |
|
1251 width=s+1; |
|
1252 for (;;) |
|
1253 { |
|
1254 int read_from_terminal; |
|
1255 int read_from_sslcon; |
|
1256 |
|
1257 read_from_terminal = 0; |
|
1258 read_from_sslcon = SSL_pending(con); |
|
1259 |
|
1260 if (!read_from_sslcon) |
|
1261 { |
|
1262 FD_ZERO(&readfds); |
|
1263 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) |
|
1264 FD_SET(fileno(stdin),&readfds); |
|
1265 |
|
1266 #endif |
|
1267 FD_SET(s,&readfds); |
|
1268 /* Note: under VMS with SOCKETSHR the second parameter is |
|
1269 * currently of type (int *) whereas under other systems |
|
1270 * it is (void *) if you don't have a cast it will choke |
|
1271 * the compiler: if you do have a cast then you can either |
|
1272 * go for (int *) or (void *). |
|
1273 */ |
|
1274 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) |
|
1275 /* Under DOS (non-djgpp) and Windows we can't select on stdin: only |
|
1276 * on sockets. As a workaround we timeout the select every |
|
1277 * second and check for any keypress. In a proper Windows |
|
1278 * application we wouldn't do this because it is inefficient. |
|
1279 */ |
|
1280 tv.tv_sec = 1; |
|
1281 tv.tv_usec = 0; |
|
1282 i=select(width,(void *)&readfds,NULL,NULL,&tv); |
|
1283 if((i < 0) || (!i && !_kbhit() ) )continue; |
|
1284 if(_kbhit()) |
|
1285 read_from_terminal = 1; |
|
1286 #else |
|
1287 i=select(width,(void *)&readfds,NULL,NULL,NULL); |
|
1288 if (i <= 0) continue; |
|
1289 if (FD_ISSET(fileno(stdin),&readfds)) |
|
1290 |
|
1291 read_from_terminal = 1; |
|
1292 #endif |
|
1293 if (FD_ISSET(s,&readfds)) |
|
1294 read_from_sslcon = 1; |
|
1295 } |
|
1296 if (read_from_terminal) |
|
1297 { |
|
1298 if (s_crlf) |
|
1299 { |
|
1300 int j, lf_num; |
|
1301 i=read(fileno(stdin), buf, bufsize/2); |
|
1302 lf_num = 0; |
|
1303 /* both loops are skipped when i <= 0 */ |
|
1304 for (j = 0; j < i; j++) |
|
1305 if (buf[j] == '\n') |
|
1306 lf_num++; |
|
1307 for (j = i-1; j >= 0; j--) |
|
1308 { |
|
1309 buf[j+lf_num] = buf[j]; |
|
1310 if (buf[j] == '\n') |
|
1311 { |
|
1312 lf_num--; |
|
1313 i++; |
|
1314 buf[j+lf_num] = '\r'; |
|
1315 } |
|
1316 } |
|
1317 assert(lf_num == 0); |
|
1318 } |
|
1319 else |
|
1320 i=read(fileno(stdin),buf,bufsize); |
|
1321 |
|
1322 if (!s_quiet) |
|
1323 { |
|
1324 if ((i <= 0) || (buf[0] == 'Q')) |
|
1325 { |
|
1326 BIO_printf(bio_s_out,"DONE\n"); |
|
1327 SHUTDOWN(s); |
|
1328 close_accept_socket(); |
|
1329 ret= -11; |
|
1330 goto err; |
|
1331 } |
|
1332 if ((i <= 0) || (buf[0] == 'q')) |
|
1333 { |
|
1334 BIO_printf(bio_s_out,"DONE\n"); |
|
1335 if (SSL_version(con) != DTLS1_VERSION) |
|
1336 SHUTDOWN(s); |
|
1337 /* close_accept_socket(); |
|
1338 ret= -11;*/ |
|
1339 goto err; |
|
1340 } |
|
1341 if ((buf[0] == 'r') && |
|
1342 ((buf[1] == '\n') || (buf[1] == '\r'))) |
|
1343 { |
|
1344 SSL_renegotiate(con); |
|
1345 i=SSL_do_handshake(con); |
|
1346 printf("SSL_do_handshake -> %d\n",i); |
|
1347 |
|
1348 i=0; /*13; */ |
|
1349 continue; |
|
1350 /* strcpy(buf,"server side RE-NEGOTIATE\n"); */ |
|
1351 } |
|
1352 if ((buf[0] == 'R') && |
|
1353 ((buf[1] == '\n') || (buf[1] == '\r'))) |
|
1354 { |
|
1355 SSL_set_verify(con, |
|
1356 SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL); |
|
1357 SSL_renegotiate(con); |
|
1358 i=SSL_do_handshake(con); |
|
1359 printf("SSL_do_handshake -> %d\n",i); |
|
1360 |
|
1361 i=0; /* 13; */ |
|
1362 continue; |
|
1363 /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */ |
|
1364 } |
|
1365 if (buf[0] == 'P') |
|
1366 { |
|
1367 static const char *str="Lets print some clear text\n"; |
|
1368 BIO_write(SSL_get_wbio(con),str,strlen(str)); |
|
1369 } |
|
1370 if (buf[0] == 'S') |
|
1371 { |
|
1372 print_stats(bio_s_out,SSL_get_SSL_CTX(con)); |
|
1373 } |
|
1374 } |
|
1375 #ifdef CHARSET_EBCDIC |
|
1376 ebcdic2ascii(buf,buf,i); |
|
1377 #endif |
|
1378 l=k=0; |
|
1379 for (;;) |
|
1380 { |
|
1381 /* should do a select for the write */ |
|
1382 #ifdef RENEG |
|
1383 { static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } } |
|
1384 #endif |
|
1385 k=SSL_write(con,&(buf[l]),(unsigned int)i); |
|
1386 switch (SSL_get_error(con,k)) |
|
1387 { |
|
1388 case SSL_ERROR_NONE: |
|
1389 break; |
|
1390 case SSL_ERROR_WANT_WRITE: |
|
1391 case SSL_ERROR_WANT_READ: |
|
1392 case SSL_ERROR_WANT_X509_LOOKUP: |
|
1393 BIO_printf(bio_s_out,"Write BLOCK\n"); |
|
1394 break; |
|
1395 case SSL_ERROR_SYSCALL: |
|
1396 case SSL_ERROR_SSL: |
|
1397 BIO_printf(bio_s_out,"ERROR\n"); |
|
1398 ERR_print_errors(bio_err); |
|
1399 ret=1; |
|
1400 goto err; |
|
1401 /* break; */ |
|
1402 case SSL_ERROR_ZERO_RETURN: |
|
1403 BIO_printf(bio_s_out,"DONE\n"); |
|
1404 ret=1; |
|
1405 goto err; |
|
1406 } |
|
1407 l+=k; |
|
1408 i-=k; |
|
1409 if (i <= 0) break; |
|
1410 } |
|
1411 } |
|
1412 if (read_from_sslcon) |
|
1413 { |
|
1414 if (!SSL_is_init_finished(con)) |
|
1415 { |
|
1416 i=init_ssl_connection(con); |
|
1417 |
|
1418 if (i < 0) |
|
1419 { |
|
1420 ret=0; |
|
1421 goto err; |
|
1422 } |
|
1423 else if (i == 0) |
|
1424 { |
|
1425 ret=1; |
|
1426 goto err; |
|
1427 } |
|
1428 } |
|
1429 else |
|
1430 { |
|
1431 again: |
|
1432 i=SSL_read(con,(char *)buf,bufsize); |
|
1433 switch (SSL_get_error(con,i)) |
|
1434 { |
|
1435 case SSL_ERROR_NONE: |
|
1436 #ifdef CHARSET_EBCDIC |
|
1437 ascii2ebcdic(buf,buf,i); |
|
1438 #endif |
|
1439 write(fileno(stdout),buf, |
|
1440 (unsigned int)i); |
|
1441 |
|
1442 if (SSL_pending(con)) goto again; |
|
1443 break; |
|
1444 case SSL_ERROR_WANT_WRITE: |
|
1445 case SSL_ERROR_WANT_READ: |
|
1446 case SSL_ERROR_WANT_X509_LOOKUP: |
|
1447 BIO_printf(bio_s_out,"Read BLOCK\n"); |
|
1448 break; |
|
1449 case SSL_ERROR_SYSCALL: |
|
1450 case SSL_ERROR_SSL: |
|
1451 BIO_printf(bio_s_out,"ERROR\n"); |
|
1452 ERR_print_errors(bio_err); |
|
1453 ret=1; |
|
1454 goto err; |
|
1455 case SSL_ERROR_ZERO_RETURN: |
|
1456 BIO_printf(bio_s_out,"DONE\n"); |
|
1457 ret=1; |
|
1458 goto err; |
|
1459 } |
|
1460 } |
|
1461 } |
|
1462 } |
|
1463 err: |
|
1464 BIO_printf(bio_s_out,"shutting down SSL\n"); |
|
1465 #if 1 |
|
1466 SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); |
|
1467 #else |
|
1468 SSL_shutdown(con); |
|
1469 #endif |
|
1470 if (con != NULL) SSL_free(con); |
|
1471 BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); |
|
1472 if (buf != NULL) |
|
1473 { |
|
1474 OPENSSL_cleanse(buf,bufsize); |
|
1475 OPENSSL_free(buf); |
|
1476 } |
|
1477 if (ret >= 0) |
|
1478 BIO_printf(bio_s_out,"ACCEPT\n"); |
|
1479 return(ret); |
|
1480 } |
|
1481 |
|
1482 static void close_accept_socket(void) |
|
1483 { |
|
1484 BIO_printf(bio_err,"shutdown accept socket\n"); |
|
1485 if (accept_socket >= 0) |
|
1486 { |
|
1487 SHUTDOWN2(accept_socket); |
|
1488 } |
|
1489 } |
|
1490 |
|
1491 static int init_ssl_connection(SSL *con) |
|
1492 { |
|
1493 int i; |
|
1494 const char *str; |
|
1495 X509 *peer; |
|
1496 long verify_error; |
|
1497 MS_STATIC char buf[BUFSIZ]; |
|
1498 |
|
1499 if ((i=SSL_accept(con)) <= 0) |
|
1500 { |
|
1501 if (BIO_sock_should_retry(i)) |
|
1502 { |
|
1503 BIO_printf(bio_s_out,"DELAY\n"); |
|
1504 return(1); |
|
1505 } |
|
1506 |
|
1507 BIO_printf(bio_err,"ERROR\n"); |
|
1508 verify_error=SSL_get_verify_result(con); |
|
1509 if (verify_error != X509_V_OK) |
|
1510 { |
|
1511 BIO_printf(bio_err,"verify error:%s\n", |
|
1512 X509_verify_cert_error_string(verify_error)); |
|
1513 } |
|
1514 else |
|
1515 ERR_print_errors(bio_err); |
|
1516 return(0); |
|
1517 } |
|
1518 |
|
1519 PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); |
|
1520 |
|
1521 peer=SSL_get_peer_certificate(con); |
|
1522 if (peer != NULL) |
|
1523 { |
|
1524 BIO_printf(bio_s_out,"Client certificate\n"); |
|
1525 PEM_write_bio_X509(bio_s_out,peer); |
|
1526 X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf); |
|
1527 BIO_printf(bio_s_out,"subject=%s\n",buf); |
|
1528 X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf); |
|
1529 BIO_printf(bio_s_out,"issuer=%s\n",buf); |
|
1530 X509_free(peer); |
|
1531 } |
|
1532 |
|
1533 if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL) |
|
1534 BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); |
|
1535 str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); |
|
1536 BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); |
|
1537 if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); |
|
1538 if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & |
|
1539 TLS1_FLAGS_TLS_PADDING_BUG) |
|
1540 BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n"); |
|
1541 #ifndef OPENSSL_NO_KRB5 |
|
1542 if (con->kssl_ctx->client_princ != NULL) |
|
1543 { |
|
1544 BIO_printf(bio_s_out,"Kerberos peer principal is %s\n", |
|
1545 con->kssl_ctx->client_princ); |
|
1546 } |
|
1547 #endif /* OPENSSL_NO_KRB5 */ |
|
1548 return(1); |
|
1549 } |
|
1550 |
|
1551 #ifndef OPENSSL_NO_DH |
|
1552 static DH *load_dh_param(const char *dhfile) |
|
1553 { |
|
1554 DH *ret=NULL; |
|
1555 BIO *bio; |
|
1556 |
|
1557 if ((bio=BIO_new_file(dhfile,"r")) == NULL) |
|
1558 goto err; |
|
1559 ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL); |
|
1560 err: |
|
1561 if (bio != NULL) BIO_free(bio); |
|
1562 return(ret); |
|
1563 } |
|
1564 #endif |
|
1565 |
|
1566 #if 0 |
|
1567 static int load_CA(SSL_CTX *ctx, char *file) |
|
1568 { |
|
1569 FILE *in; |
|
1570 X509 *x=NULL; |
|
1571 |
|
1572 if ((in=fopen(file,"r")) == NULL) |
|
1573 return(0); |
|
1574 |
|
1575 for (;;) |
|
1576 { |
|
1577 if (PEM_read_X509(in,&x,NULL) == NULL) |
|
1578 break; |
|
1579 SSL_CTX_add_client_CA(ctx,x); |
|
1580 } |
|
1581 if (x != NULL) X509_free(x); |
|
1582 fclose(in); |
|
1583 return(1); |
|
1584 } |
|
1585 #endif |
|
1586 |
|
1587 static int www_body(char *hostname, int s, unsigned char *context) |
|
1588 { |
|
1589 char *buf=NULL; |
|
1590 int ret=1; |
|
1591 int i,j,k,blank,dot; |
|
1592 struct stat st_buf; |
|
1593 SSL *con; |
|
1594 SSL_CIPHER *c; |
|
1595 BIO *io,*ssl_bio,*sbio; |
|
1596 long total_bytes; |
|
1597 |
|
1598 buf=OPENSSL_malloc(bufsize); |
|
1599 if (buf == NULL) return(0); |
|
1600 io=BIO_new(BIO_f_buffer()); |
|
1601 ssl_bio=BIO_new(BIO_f_ssl()); |
|
1602 if ((io == NULL) || (ssl_bio == NULL)) goto err; |
|
1603 |
|
1604 #ifdef FIONBIO |
|
1605 if (s_nbio) |
|
1606 { |
|
1607 unsigned long sl=1; |
|
1608 |
|
1609 if (!s_quiet) |
|
1610 BIO_printf(bio_err,"turning on non blocking io\n"); |
|
1611 if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) |
|
1612 ERR_print_errors(bio_err); |
|
1613 } |
|
1614 #endif |
|
1615 |
|
1616 /* lets make the output buffer a reasonable size */ |
|
1617 if (!BIO_set_write_buffer_size(io,bufsize)) goto err; |
|
1618 |
|
1619 if ((con=SSL_new(ctx)) == NULL) goto err; |
|
1620 #ifndef OPENSSL_NO_KRB5 |
|
1621 if ((con->kssl_ctx = kssl_ctx_new()) != NULL) |
|
1622 { |
|
1623 kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC); |
|
1624 kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB); |
|
1625 } |
|
1626 #endif /* OPENSSL_NO_KRB5 */ |
|
1627 if(context) SSL_set_session_id_context(con, context, |
|
1628 strlen((char *)context)); |
|
1629 |
|
1630 sbio=BIO_new_socket(s,BIO_NOCLOSE); |
|
1631 if (s_nbio_test) |
|
1632 { |
|
1633 BIO *test; |
|
1634 |
|
1635 test=BIO_new(BIO_f_nbio_test()); |
|
1636 sbio=BIO_push(test,sbio); |
|
1637 } |
|
1638 SSL_set_bio(con,sbio,sbio); |
|
1639 SSL_set_accept_state(con); |
|
1640 |
|
1641 /* SSL_set_fd(con,s); */ |
|
1642 BIO_set_ssl(ssl_bio,con,BIO_CLOSE); |
|
1643 BIO_push(io,ssl_bio); |
|
1644 #ifdef CHARSET_EBCDIC |
|
1645 io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io); |
|
1646 #endif |
|
1647 |
|
1648 if (s_debug) |
|
1649 { |
|
1650 con->debug=1; |
|
1651 BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); |
|
1652 BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); |
|
1653 } |
|
1654 if (s_msg) |
|
1655 { |
|
1656 SSL_set_msg_callback(con, msg_cb); |
|
1657 SSL_set_msg_callback_arg(con, bio_s_out); |
|
1658 } |
|
1659 |
|
1660 blank=0; |
|
1661 for (;;) |
|
1662 { |
|
1663 if (hack) |
|
1664 { |
|
1665 i=SSL_accept(con); |
|
1666 |
|
1667 switch (SSL_get_error(con,i)) |
|
1668 { |
|
1669 case SSL_ERROR_NONE: |
|
1670 break; |
|
1671 case SSL_ERROR_WANT_WRITE: |
|
1672 case SSL_ERROR_WANT_READ: |
|
1673 case SSL_ERROR_WANT_X509_LOOKUP: |
|
1674 continue; |
|
1675 case SSL_ERROR_SYSCALL: |
|
1676 case SSL_ERROR_SSL: |
|
1677 case SSL_ERROR_ZERO_RETURN: |
|
1678 ret=1; |
|
1679 goto err; |
|
1680 /* break; */ |
|
1681 } |
|
1682 |
|
1683 SSL_renegotiate(con); |
|
1684 SSL_write(con,NULL,0); |
|
1685 } |
|
1686 |
|
1687 i=BIO_gets(io,buf,bufsize-1); |
|
1688 if (i < 0) /* error */ |
|
1689 { |
|
1690 if (!BIO_should_retry(io)) |
|
1691 { |
|
1692 if (!s_quiet) |
|
1693 ERR_print_errors(bio_err); |
|
1694 goto err; |
|
1695 } |
|
1696 else |
|
1697 { |
|
1698 BIO_printf(bio_s_out,"read R BLOCK\n"); |
|
1699 #if defined(OPENSSL_SYS_NETWARE) |
|
1700 delay(1000); |
|
1701 #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__) |
|
1702 sleep(1); |
|
1703 #endif |
|
1704 continue; |
|
1705 } |
|
1706 } |
|
1707 else if (i == 0) /* end of input */ |
|
1708 { |
|
1709 ret=1; |
|
1710 goto end; |
|
1711 } |
|
1712 |
|
1713 /* else we have data */ |
|
1714 if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) || |
|
1715 ((www == 2) && (strncmp("GET /stats ",buf,10) == 0))) |
|
1716 { |
|
1717 char *p; |
|
1718 X509 *peer; |
|
1719 STACK_OF(SSL_CIPHER) *sk; |
|
1720 static const char *space=" "; |
|
1721 |
|
1722 BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); |
|
1723 BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n"); |
|
1724 BIO_puts(io,"<pre>\n"); |
|
1725 /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ |
|
1726 BIO_puts(io,"\n"); |
|
1727 for (i=0; i<local_argc; i++) |
|
1728 { |
|
1729 BIO_puts(io,local_argv[i]); |
|
1730 BIO_write(io," ",1); |
|
1731 } |
|
1732 BIO_puts(io,"\n"); |
|
1733 |
|
1734 /* The following is evil and should not really |
|
1735 * be done */ |
|
1736 BIO_printf(io,"Ciphers supported in s_server binary\n"); |
|
1737 sk=SSL_get_ciphers(con); |
|
1738 j=sk_SSL_CIPHER_num(sk); |
|
1739 for (i=0; i<j; i++) |
|
1740 { |
|
1741 c=sk_SSL_CIPHER_value(sk,i); |
|
1742 BIO_printf(io,"%-11s:%-25s", |
|
1743 SSL_CIPHER_get_version(c), |
|
1744 SSL_CIPHER_get_name(c)); |
|
1745 if ((((i+1)%2) == 0) && (i+1 != j)) |
|
1746 BIO_puts(io,"\n"); |
|
1747 } |
|
1748 BIO_puts(io,"\n"); |
|
1749 p=SSL_get_shared_ciphers(con,buf,bufsize); |
|
1750 if (p != NULL) |
|
1751 { |
|
1752 BIO_printf(io,"---\nCiphers common between both SSL end points:\n"); |
|
1753 j=i=0; |
|
1754 while (*p) |
|
1755 { |
|
1756 if (*p == ':') |
|
1757 { |
|
1758 BIO_write(io,space,26-j); |
|
1759 i++; |
|
1760 j=0; |
|
1761 BIO_write(io,((i%3)?" ":"\n"),1); |
|
1762 } |
|
1763 else |
|
1764 { |
|
1765 BIO_write(io,p,1); |
|
1766 j++; |
|
1767 } |
|
1768 p++; |
|
1769 } |
|
1770 BIO_puts(io,"\n"); |
|
1771 } |
|
1772 BIO_printf(io,((con->hit) |
|
1773 ?"---\nReused, " |
|
1774 :"---\nNew, ")); |
|
1775 c=SSL_get_current_cipher(con); |
|
1776 BIO_printf(io,"%s, Cipher is %s\n", |
|
1777 SSL_CIPHER_get_version(c), |
|
1778 SSL_CIPHER_get_name(c)); |
|
1779 SSL_SESSION_print(io,SSL_get_session(con)); |
|
1780 BIO_printf(io,"---\n"); |
|
1781 print_stats(io,SSL_get_SSL_CTX(con)); |
|
1782 BIO_printf(io,"---\n"); |
|
1783 peer=SSL_get_peer_certificate(con); |
|
1784 if (peer != NULL) |
|
1785 { |
|
1786 BIO_printf(io,"Client certificate\n"); |
|
1787 X509_print(io,peer); |
|
1788 PEM_write_bio_X509(io,peer); |
|
1789 } |
|
1790 else |
|
1791 BIO_puts(io,"no client certificate available\n"); |
|
1792 BIO_puts(io,"</BODY></HTML>\r\n\r\n"); |
|
1793 break; |
|
1794 } |
|
1795 else if ((www == 2 || www == 3) |
|
1796 && (strncmp("GET /",buf,5) == 0)) |
|
1797 { |
|
1798 BIO *file; |
|
1799 char *p,*e; |
|
1800 static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; |
|
1801 |
|
1802 /* skip the '/' */ |
|
1803 p= &(buf[5]); |
|
1804 |
|
1805 dot = 1; |
|
1806 for (e=p; *e != '\0'; e++) |
|
1807 { |
|
1808 if (e[0] == ' ') |
|
1809 break; |
|
1810 |
|
1811 switch (dot) |
|
1812 { |
|
1813 case 1: |
|
1814 dot = (e[0] == '.') ? 2 : 0; |
|
1815 break; |
|
1816 case 2: |
|
1817 dot = (e[0] == '.') ? 3 : 0; |
|
1818 break; |
|
1819 case 3: |
|
1820 dot = (e[0] == '/') ? -1 : 0; |
|
1821 break; |
|
1822 } |
|
1823 if (dot == 0) |
|
1824 dot = (e[0] == '/') ? 1 : 0; |
|
1825 } |
|
1826 dot = (dot == 3) || (dot == -1); /* filename contains ".." component */ |
|
1827 |
|
1828 if (*e == '\0') |
|
1829 { |
|
1830 BIO_puts(io,text); |
|
1831 BIO_printf(io,"'%s' is an invalid file name\r\n",p); |
|
1832 break; |
|
1833 } |
|
1834 *e='\0'; |
|
1835 |
|
1836 if (dot) |
|
1837 { |
|
1838 BIO_puts(io,text); |
|
1839 BIO_printf(io,"'%s' contains '..' reference\r\n",p); |
|
1840 break; |
|
1841 } |
|
1842 |
|
1843 if (*p == '/') |
|
1844 { |
|
1845 BIO_puts(io,text); |
|
1846 BIO_printf(io,"'%s' is an invalid path\r\n",p); |
|
1847 break; |
|
1848 } |
|
1849 |
|
1850 #if 0 |
|
1851 /* append if a directory lookup */ |
|
1852 if (e[-1] == '/') |
|
1853 strcat(p,"index.html"); |
|
1854 #endif |
|
1855 |
|
1856 /* if a directory, do the index thang */ |
|
1857 if (stat(p,&st_buf) < 0) |
|
1858 { |
|
1859 BIO_puts(io,text); |
|
1860 BIO_printf(io,"Error accessing '%s'\r\n",p); |
|
1861 ERR_print_errors(io); |
|
1862 break; |
|
1863 } |
|
1864 if (S_ISDIR(st_buf.st_mode)) |
|
1865 { |
|
1866 #if 0 /* must check buffer size */ |
|
1867 strcat(p,"/index.html"); |
|
1868 #else |
|
1869 BIO_puts(io,text); |
|
1870 BIO_printf(io,"'%s' is a directory\r\n",p); |
|
1871 break; |
|
1872 #endif |
|
1873 } |
|
1874 |
|
1875 if ((file=BIO_new_file(p,"r")) == NULL) |
|
1876 { |
|
1877 BIO_puts(io,text); |
|
1878 BIO_printf(io,"Error opening '%s'\r\n",p); |
|
1879 ERR_print_errors(io); |
|
1880 break; |
|
1881 } |
|
1882 |
|
1883 if (!s_quiet) |
|
1884 BIO_printf(bio_err,"FILE:%s\n",p); |
|
1885 |
|
1886 if (www == 2) |
|
1887 { |
|
1888 i=strlen(p); |
|
1889 if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) || |
|
1890 ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) || |
|
1891 ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0))) |
|
1892 BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); |
|
1893 else |
|
1894 BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); |
|
1895 } |
|
1896 /* send the file */ |
|
1897 total_bytes=0; |
|
1898 for (;;) |
|
1899 { |
|
1900 i=BIO_read(file,buf,bufsize); |
|
1901 if (i <= 0) break; |
|
1902 |
|
1903 #ifdef RENEG |
|
1904 total_bytes+=i; |
|
1905 fprintf(stderr,"%d\n",i); |
|
1906 if (total_bytes > 3*1024) |
|
1907 { |
|
1908 total_bytes=0; |
|
1909 fprintf(stderr,"RENEGOTIATE\n"); |
|
1910 SSL_renegotiate(con); |
|
1911 } |
|
1912 |
|
1913 #endif |
|
1914 |
|
1915 for (j=0; j<i; ) |
|
1916 { |
|
1917 #ifdef RENEG |
|
1918 { static count=0; if (++count == 13) { SSL_renegotiate(con); } } |
|
1919 #endif |
|
1920 k=BIO_write(io,&(buf[j]),i-j); |
|
1921 if (k <= 0) |
|
1922 { |
|
1923 if (!BIO_should_retry(io)) |
|
1924 goto write_error; |
|
1925 else |
|
1926 { |
|
1927 BIO_printf(bio_s_out,"rwrite W BLOCK\n"); |
|
1928 } |
|
1929 } |
|
1930 else |
|
1931 { |
|
1932 j+=k; |
|
1933 } |
|
1934 } |
|
1935 } |
|
1936 write_error: |
|
1937 BIO_free(file); |
|
1938 break; |
|
1939 } |
|
1940 } |
|
1941 |
|
1942 for (;;) |
|
1943 { |
|
1944 i=(int)BIO_flush(io); |
|
1945 if (i <= 0) |
|
1946 { |
|
1947 if (!BIO_should_retry(io)) |
|
1948 break; |
|
1949 } |
|
1950 else |
|
1951 break; |
|
1952 } |
|
1953 end: |
|
1954 #if 1 |
|
1955 /* make sure we re-use sessions */ |
|
1956 SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); |
|
1957 #else |
|
1958 /* This kills performance */ |
|
1959 /* SSL_shutdown(con); A shutdown gets sent in the |
|
1960 * BIO_free_all(io) procession */ |
|
1961 #endif |
|
1962 |
|
1963 err: |
|
1964 |
|
1965 if (ret >= 0) |
|
1966 BIO_printf(bio_s_out,"ACCEPT\n"); |
|
1967 |
|
1968 if (buf != NULL) OPENSSL_free(buf); |
|
1969 if (io != NULL) BIO_free_all(io); |
|
1970 /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/ |
|
1971 return(ret); |
|
1972 } |
|
1973 |
|
1974 #ifndef OPENSSL_NO_RSA |
|
1975 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) |
|
1976 { |
|
1977 BIGNUM *bn = NULL; |
|
1978 static RSA *rsa_tmp=NULL; |
|
1979 |
|
1980 if (!rsa_tmp && ((bn = BN_new()) == NULL)) |
|
1981 BIO_printf(bio_err,"Allocation error in generating RSA key\n"); |
|
1982 if (!rsa_tmp && bn) |
|
1983 { |
|
1984 if (!s_quiet) |
|
1985 { |
|
1986 BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); |
|
1987 (void)BIO_flush(bio_err); |
|
1988 } |
|
1989 if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) || |
|
1990 !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) |
|
1991 { |
|
1992 if(rsa_tmp) RSA_free(rsa_tmp); |
|
1993 rsa_tmp = NULL; |
|
1994 } |
|
1995 if (!s_quiet) |
|
1996 { |
|
1997 BIO_printf(bio_err,"\n"); |
|
1998 (void)BIO_flush(bio_err); |
|
1999 } |
|
2000 BN_free(bn); |
|
2001 } |
|
2002 return(rsa_tmp); |
|
2003 } |
|
2004 #endif |
|
2005 |
|
2006 #define MAX_SESSION_ID_ATTEMPTS 10 |
|
2007 static int generate_session_id(const SSL *ssl, unsigned char *id, |
|
2008 unsigned int *id_len) |
|
2009 { |
|
2010 unsigned int count = 0; |
|
2011 do { |
|
2012 RAND_pseudo_bytes(id, *id_len); |
|
2013 /* Prefix the session_id with the required prefix. NB: If our |
|
2014 * prefix is too long, clip it - but there will be worse effects |
|
2015 * anyway, eg. the server could only possibly create 1 session |
|
2016 * ID (ie. the prefix!) so all future session negotiations will |
|
2017 * fail due to conflicts. */ |
|
2018 memcpy(id, session_id_prefix, |
|
2019 (strlen(session_id_prefix) < *id_len) ? |
|
2020 strlen(session_id_prefix) : *id_len); |
|
2021 } |
|
2022 while(SSL_has_matching_session_id(ssl, id, *id_len) && |
|
2023 (++count < MAX_SESSION_ID_ATTEMPTS)); |
|
2024 if(count >= MAX_SESSION_ID_ATTEMPTS) |
|
2025 return 0; |
|
2026 return 1; |
|
2027 } |