Bug Summary

File:src/serv.c
Location:line 1487, column 17
Description:Dereference of null pointer

Annotated Source Code

1/*
2 * Copyright (C) 2004, 2006-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2001,2002 Paul Sheer
4 * Portions Copyright (C) 2002,2003 Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
8 * GnuTLS is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GnuTLS is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* This server is heavily modified for GnuTLS by Nikos Mavrogiannopoulos
23 * (which means it is quite unreadable)
24 */
25
26#include <config.h>
27
28#include "common.h"
29#include "serv-gaa.h"
30#include <stdio.h>
31#include <stdlib.h>
32#include <errno(*__errno_location ()).h>
33#include <sys/types.h>
34#include <string.h>
35#include <gnutls/gnutls.h>
36#include <gnutls/openpgp.h>
37#include <sys/time.h>
38#include <sys/select.h>
39#include <fcntl.h>
40#include <list.h>
41#include <netdb.h>
42#include <unistd.h>
43
44/* Gnulib portability files. */
45#include "progname.h"
46#include "version-etc.h"
47#include "read-file.h"
48#include "minmax.h"
49#include "sockets.h"
50#include "udp-serv.h"
51
52/* konqueror cannot handle sending the page in multiple
53 * pieces.
54 */
55/* global stuff */
56static int generate = 0;
57static int http = 0;
58static int x509ctype;
59static int debug;
60
61int verbose;
62static int nodb;
63static int noticket;
64int require_cert;
65int disable_client_cert;
66
67char *psk_passwd;
68char *srp_passwd;
69char *srp_passwd_conf;
70char *pgp_keyring;
71char *pgp_keyfile;
72char *pgp_certfile;
73char *x509_keyfile;
74char *x509_certfile;
75char *x509_dsakeyfile;
76char *x509_dsacertfile;
77char *x509_ecckeyfile;
78char *x509_ecccertfile;
79char *x509_cafile;
80char *dh_params_file;
81char *x509_crlfile = NULL((void*)0);
82
83gnutls_datum_t session_ticket_key;
84static void tcp_server(const char* name, int port);
85
86/* end of globals */
87
88/* This is a sample TCP echo server.
89 * This will behave as an http server if any argument in the
90 * command line is present
91 */
92
93#define SMALL_READ_TEST(2147483647) (2147483647)
94
95#define GERR(ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret)) fprintf(stdoutstdout, "Error: %s\n", safe_strerror(ret))
96
97#define HTTP_END"</BODY></HTML>\n\n" "</BODY></HTML>\n\n"
98
99#define HTTP_UNIMPLEMENTED"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>501 Method Not Implemented</TITLE>\r\n</HEAD><BODY>\r\n<H1>Method Not Implemented</H1>\r\n<HR>\r\n</BODY></HTML>\r\n" "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>501 Method Not Implemented</TITLE>\r\n</HEAD><BODY>\r\n<H1>Method Not Implemented</H1>\r\n<HR>\r\n</BODY></HTML>\r\n"
100#define HTTP_OK"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
101
102#define HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
HTTP_OK"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" \
103 "\n" \
104 "<HTML><BODY>\n" \
105 "<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">" \
106 "GnuTLS</a></H1></CENTER>\n\n"
107
108/* These are global */
109gnutls_srp_server_credentials_t srp_cred = NULL((void*)0);
110gnutls_psk_server_credentials_t psk_cred = NULL((void*)0);
111gnutls_anon_server_credentials_t dh_cred = NULL((void*)0);
112gnutls_certificate_credentials_t cert_cred = NULL((void*)0);
113
114static gaainfo info;
115
116const int ssl_session_cache = 128;
117
118static void wrap_db_init (void);
119static void wrap_db_deinit (void);
120static int wrap_db_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data);
121static gnutls_datum_t wrap_db_fetch (void *dbf, gnutls_datum_t key);
122static int wrap_db_delete (void *dbf, gnutls_datum_t key);
123
124
125#define HTTP_STATE_REQUEST1 1
126#define HTTP_STATE_RESPONSE2 2
127#define HTTP_STATE_CLOSING3 3
128
129LIST_TYPE_DECLARE (listener_item, char *http_request; char *http_response;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
130 int request_length; int response_length;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
131 int response_written; int http_state;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
132 int listen_socket; int fd;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
133 gnutls_session_t tls_session;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
134 int handshake_ok;typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
135 )typedef struct listener_item { struct listener_item *next; struct
listener_item *prev; char *http_request; char *http_response
; int request_length; int response_length; int response_written
; int http_state; int listen_socket; int fd; gnutls_session_t
tls_session; int handshake_ok; } listener_item
;
136
137static const char *
138safe_strerror (int value)
139{
140 const char *ret = gnutls_strerror (value);
141 if (ret == NULL((void*)0))
142 ret = str_unknown;
143 return ret;
144}
145
146static void
147listener_free (listener_item * j)
148{
149
150 free (j->http_request);
151 free (j->http_response);
152 if (j->fd >= 0)
153 {
154 gnutls_bye (j->tls_session, GNUTLS_SHUT_WR);
155 shutdown (j->fd, 2);
156 close (j->fd);
157 gnutls_deinit (j->tls_session);
158 }
159}
160
161
162/* we use primes up to 1024 in this server.
163 * otherwise we should add them here.
164 */
165
166gnutls_dh_params_t dh_params = NULL((void*)0);
167gnutls_rsa_params_t rsa_params = NULL((void*)0);
168
169static int
170generate_dh_primes (void)
171{
172 int prime_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL);
173
174 if (gnutls_dh_params_init (&dh_params) < 0)
175 {
176 fprintf (stderrstderr, "Error in dh parameter initialization\n");
177 exit (1);
178 }
179
180 /* Generate Diffie-Hellman parameters - for use with DHE
181 * kx algorithms. These should be discarded and regenerated
182 * once a week or once a month. Depends on the
183 * security requirements.
184 */
185 printf
186 ("Generating Diffie-Hellman parameters [%d]. Please wait...\n",
187 prime_bits);
188 fflush (stdoutstdout);
189
190 if (gnutls_dh_params_generate2 (dh_params, prime_bits) < 0)
191 {
192 fprintf (stderrstderr, "Error in prime generation\n");
193 exit (1);
194 }
195
196 return 0;
197}
198
199static void
200read_dh_params (void)
201{
202 char tmpdata[2048];
203 int size;
204 gnutls_datum_t params;
205 FILE *fd;
206
207 if (gnutls_dh_params_init (&dh_params) < 0)
208 {
209 fprintf (stderrstderr, "Error in dh parameter initialization\n");
210 exit (1);
211 }
212
213 /* read the params file
214 */
215 fd = fopen (dh_params_file, "r");
216 if (fd == NULL((void*)0))
217 {
218 fprintf (stderrstderr, "Could not open %s\n", dh_params_file);
219 exit (1);
220 }
221
222 size = fread (tmpdata, 1, sizeof (tmpdata) - 1, fd);
223 tmpdata[size] = 0;
224 fclose (fd);
225
226 params.data = (unsigned char *) tmpdata;
227 params.size = size;
228
229 size =
230 gnutls_dh_params_import_pkcs3 (dh_params, &params, GNUTLS_X509_FMT_PEM);
231
232 if (size < 0)
233 {
234 fprintf (stderrstderr, "Error parsing dh params: %s\n", safe_strerror (size));
235 exit (1);
236 }
237
238 printf ("Read Diffie-Hellman parameters.\n");
239 fflush (stdoutstdout);
240
241}
242
243static char pkcs3[] =
244 "-----BEGIN DH PARAMETERS-----\n"
245 "MIGGAoGAtkxw2jlsVCsrfLqxrN+IrF/3W8vVFvDzYbLmxi2GQv9s/PQGWP1d9i22\n"
246 "P2DprfcJknWt7KhCI1SaYseOQIIIAYP78CfyIpGScW/vS8khrw0rlQiyeCvQgF3O\n"
247 "GeGOEywcw+oQT4SmFOD7H0smJe2CNyjYpexBXQ/A0mbTF9QKm1cCAQU=\n"
248 "-----END DH PARAMETERS-----\n";
249
250static int
251static_dh_params (void)
252{
253 gnutls_datum_t params = { pkcs3, sizeof (pkcs3) };
254 int ret;
255
256 if (gnutls_dh_params_init (&dh_params) < 0)
257 {
258 fprintf (stderrstderr, "Error in dh parameter initialization\n");
259 exit (1);
260 }
261
262 ret = gnutls_dh_params_import_pkcs3 (dh_params, &params,
263 GNUTLS_X509_FMT_PEM);
264
265 if (ret < 0)
266 {
267 fprintf (stderrstderr, "Error parsing dh params: %s\n", safe_strerror (ret));
268 exit (1);
269 }
270
271 printf ("Set static Diffie-Hellman parameters, consider --dhparams.\n");
272
273 return 0;
274}
275
276static int
277get_params (gnutls_session_t session, gnutls_params_type_t type,
278 gnutls_params_st * st)
279{
280
281 if (type == GNUTLS_PARAMS_RSA_EXPORT)
282 {
283 if (rsa_params == NULL((void*)0))
284 return -1;
285 st->params.rsa_export = rsa_params;
286 }
287 else if (type == GNUTLS_PARAMS_DH)
288 {
289 if (dh_params == NULL((void*)0))
290 return -1;
291 st->params.dh = dh_params;
292 }
293 else
294 return -1;
295
296 st->type = type;
297 st->deinit = 0;
298
299 return 0;
300}
301
302static int
303generate_rsa_params (void)
304{
305 if (gnutls_rsa_params_init (&rsa_params) < 0)
306 {
307 fprintf (stderrstderr, "Error in rsa parameter initialization\n");
308 exit (1);
309 }
310
311 /* Generate RSA parameters - for use with RSA-export
312 * cipher suites. These should be discarded and regenerated
313 * once a day, once every 500 transactions etc. Depends on the
314 * security requirements.
315 */
316 printf ("Generating temporary RSA parameters. Please wait...\n");
317 fflush (stdoutstdout);
318
319 if (gnutls_rsa_params_generate2 (rsa_params, 512) < 0)
320 {
321 fprintf (stderrstderr, "Error in rsa parameter generation\n");
322 exit (1);
323 }
324
325 return 0;
326}
327
328LIST_DECLARE_INIT (listener_list, listener_item, listener_free)struct { long length; long item_size; listener_item *head, *tail
, *search; void (*free_func) (listener_item *); } listener_list
= {0, sizeof (listener_item), 0, 0, 0, (void (*) (listener_item
*)) listener_free}
;
329
330gnutls_session_t initialize_session (int dtls)
331{
332 gnutls_session_t session;
333 const char *err;
334
335 if (dtls)
336 gnutls_init (&session, GNUTLS_SERVER1|GNUTLS_DATAGRAM(1<<2));
337 else
338 gnutls_init (&session, GNUTLS_SERVER1);
339
340 /* allow the use of private ciphersuites.
341 */
342 gnutls_handshake_set_private_extensions (session, 1);
343
344 if (nodb == 0)
345 {
346 gnutls_db_set_retrieve_function (session, wrap_db_fetch);
347 gnutls_db_set_remove_function (session, wrap_db_delete);
348 gnutls_db_set_store_function (session, wrap_db_store);
349 gnutls_db_set_ptr (session, NULL((void*)0));
350 }
351#ifdef ENABLE_SESSION_TICKET
352 if (noticket == 0)
353 gnutls_session_ticket_enable_server (session, &session_ticket_key);
354#endif
355
356 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
357 {
358 fprintf (stderrstderr, "Syntax error at: %s\n", err);
359 exit (1);
360 }
361
362 gnutls_credentials_set (session, GNUTLS_CRD_ANON, dh_cred);
363
364 if (srp_cred != NULL((void*)0))
365 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
366
367 if (psk_cred != NULL((void*)0))
368 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
369
370 if (cert_cred != NULL((void*)0))
371 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cert_cred);
372
373 if (disable_client_cert)
374 gnutls_certificate_server_set_request (session, GNUTLS_CERT_IGNORE);
375 else
376 {
377 if (require_cert)
378 gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE);
379 else
380 gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
381 }
382
383 return session;
384}
385
386#include <gnutls/x509.h>
387
388static const char DEFAULT_DATA[] =
389 "This is the default message reported by the GnuTLS implementation. "
390 "For more information please visit "
391 "<a href=\"http://www.gnutls.org/\">http://www.gnutls.org/</a>.";
392
393/* Creates html with the current session information.
394 */
395#define tmp_buffer&http_buffer[strlen(http_buffer)] &http_buffer[strlen(http_buffer)]
396#define tmp_buffer_sizelen-strlen(http_buffer) len-strlen(http_buffer)
397static char *
398peer_print_info (gnutls_session_t session, int *ret_length,
399 const char *header)
400{
401 const char *tmp;
402 unsigned char sesid[32];
403 size_t i, sesid_size;
404 char *http_buffer;
405 gnutls_kx_algorithm_t kx_alg;
406 size_t len = 20 * 1024 + strlen (header);
407 char *crtinfo = NULL((void*)0);
408 size_t ncrtinfo = 0;
409
410 if (verbose != 0)
411 {
412 http_buffer = malloc (len);
413 if (http_buffer == NULL((void*)0))
414 return NULL((void*)0);
415
416 strcpy (http_buffer, HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
);
417 strcpy (&http_buffer[sizeof (HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
) - 1], DEFAULT_DATA);
418 strcpy (&http_buffer[sizeof (HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
) + sizeof (DEFAULT_DATA) - 2],
419 HTTP_END"</BODY></HTML>\n\n");
420 *ret_length =
421 sizeof (DEFAULT_DATA) + sizeof (HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
) + sizeof (HTTP_END"</BODY></HTML>\n\n") - 3;
422 return http_buffer;
423
424 }
425
426 if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509)
427 {
428 const gnutls_datum_t *cert_list;
429 unsigned int cert_list_size = 0;
430
431 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
432
433 for (i = 0; i < cert_list_size; i++)
434 {
435 gnutls_x509_crt_t cert;
436 gnutls_datum_t info;
437
438 if (gnutls_x509_crt_init (&cert) == 0 &&
439 gnutls_x509_crt_import (cert, &cert_list[i],
440 GNUTLS_X509_FMT_DER) == 0 &&
441 gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_FULL, &info) == 0)
442 {
443 const char *post = "</PRE><P><PRE>";
444
445 crtinfo = realloc (crtinfo, ncrtinfo + info.size +
446 strlen (post) + 1);
447 if (crtinfo == NULL((void*)0))
448 return NULL((void*)0);
449 memcpy (crtinfo + ncrtinfo, info.data, info.size);
450 ncrtinfo += info.size;
451 memcpy (crtinfo + ncrtinfo, post, strlen (post));
452 ncrtinfo += strlen (post);
453 crtinfo[ncrtinfo] = '\0';
454 gnutls_free (info.data);
455 }
456 }
457 }
458
459 http_buffer = malloc (len);
460 if (http_buffer == NULL((void*)0))
461 {
462 free (crtinfo);
463 return NULL((void*)0);
464 }
465
466 strcpy (http_buffer, HTTP_BEGIN"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" "\n" "<HTML><BODY>\n"
"<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">"
"GnuTLS</a></H1></CENTER>\n\n"
);
467
468 /* print session_id */
469 gnutls_session_get_id (session, sesid, &sesid_size);
470 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "\n<p>Session ID: <i>");
471 for (i = 0; i < sesid_size; i++)
472 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "%.2X", sesid[i]);
473 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "</i></p>\n");
474 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer),
475 "<h5>If your browser supports session resuming, then you should see the "
476 "same session ID, when you press the <b>reload</b> button.</h5>\n");
477
478 /* Here unlike print_info() we use the kx algorithm to distinguish
479 * the functions to call.
480 */
481 {
482 char dns[256];
483 size_t dns_size = sizeof (dns);
484 unsigned int type;
485
486 if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
487 {
488 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "\n<p>Server Name: %s</p>\n", dns);
489 }
490
491 }
492
493 kx_alg = gnutls_kx_get (session);
494
495 /* print srp specific data */
496#ifdef ENABLE_SRP1
497 if (kx_alg == GNUTLS_KX_SRP)
498 {
499 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<p>Connected as user '%s'.</p>\n",
500 gnutls_srp_server_get_username (session));
501 }
502#endif
503
504#ifdef ENABLE_PSK1
505 if (kx_alg == GNUTLS_KX_PSK)
506 {
507 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<p>Connected as user '%s'.</p>\n",
508 gnutls_psk_server_get_username (session));
509 }
510#endif
511
512#ifdef ENABLE_ANON1
513 if (kx_alg == GNUTLS_KX_ANON_DH)
514 {
515 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer),
516 "<p> Connect using anonymous DH (prime of %d bits)</p>\n",
517 gnutls_dh_get_prime_bits (session));
518 }
519#endif
520
521 if (kx_alg == GNUTLS_KX_DHE_RSA || kx_alg == GNUTLS_KX_DHE_DSS)
522 {
523 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer),
524 "Ephemeral DH using prime of <b>%d</b> bits.<br>\n",
525 gnutls_dh_get_prime_bits (session));
526 }
527
528 /* print session information */
529 strcat (http_buffer, "<P>\n");
530
531 tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
532 if (tmp == NULL((void*)0))
533 tmp = str_unknown;
534 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer),
535 "<TABLE border=1><TR><TD>Protocol version:</TD><TD>%s</TD></TR>\n",
536 tmp);
537
538 if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
539 {
540 tmp =
541 gnutls_certificate_type_get_name (gnutls_certificate_type_get
542 (session));
543 if (tmp == NULL((void*)0))
544 tmp = str_unknown;
545 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>Certificate Type:</TD><TD>%s</TD></TR>\n",
546 tmp);
547 }
548
549 tmp = gnutls_kx_get_name (kx_alg);
550 if (tmp == NULL((void*)0))
551 tmp = str_unknown;
552 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp);
553
554 tmp = gnutls_compression_get_name (gnutls_compression_get (session));
555 if (tmp == NULL((void*)0))
556 tmp = str_unknown;
557 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>Compression</TD><TD>%s</TD></TR>\n", tmp);
558
559 tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
560 if (tmp == NULL((void*)0))
561 tmp = str_unknown;
562 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>Cipher</TD><TD>%s</TD></TR>\n", tmp);
563
564 tmp = gnutls_mac_get_name (gnutls_mac_get (session));
565 if (tmp == NULL((void*)0))
566 tmp = str_unknown;
567 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", tmp);
568
569 tmp = gnutls_cipher_suite_get_name (kx_alg,
570 gnutls_cipher_get (session),
571 gnutls_mac_get (session));
572 if (tmp == NULL((void*)0))
573 tmp = str_unknown;
574 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n",
575 tmp);
576
577 if (crtinfo)
578 {
579 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<hr><PRE>%s\n</PRE>\n", crtinfo);
580 free (crtinfo);
581 }
582
583 snprintf (tmp_buffer&http_buffer[strlen(http_buffer)], tmp_buffer_sizelen-strlen(http_buffer), "<hr><P>Your HTTP header was:<PRE>%s</PRE></P>\n" HTTP_END"</BODY></HTML>\n\n",
584 header);
585
586 *ret_length = strlen (http_buffer);
587
588 return http_buffer;
589}
590
591const char *
592human_addr (const struct sockaddr *sa, socklen_t salen,
593 char *buf, size_t buflen)
594{
595 const char *save_buf = buf;
596 size_t l;
597
598 if (!buf || !buflen)
599 return NULL((void*)0);
600
601 *buf = '\0';
602
603 switch (sa->sa_family)
604 {
605#if HAVE_IPV61
606 case AF_INET610:
607 snprintf (buf, buflen, "IPv6 ");
608 break;
609#endif
610
611 case AF_INET2:
612 snprintf (buf, buflen, "IPv4 ");
613 break;
614 }
615
616 l = strlen (buf);
617 buf += l;
618 buflen -= l;
619
620 if (getnameinfo (sa, salen, buf, buflen, NULL((void*)0), 0, NI_NUMERICHOST1) != 0)
621 return NULL((void*)0);
622
623 l = strlen (buf);
624 buf += l;
625 buflen -= l;
626
627 strncat (buf, " port ", buflen);
628
629 l = strlen (buf);
630 buf += l;
631 buflen -= l;
632
633 if (getnameinfo (sa, salen, NULL((void*)0), 0, buf, buflen, NI_NUMERICSERV2) != 0)
634 return NULL((void*)0);
635
636 return save_buf;
637}
638
639int wait_for_connection(void)
640{
641 listener_item *j;
642 fd_set rd, wr;
643 int n, sock = -1;
644
645 FD_ZERO (&rd)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&rd)->fds_bits)[0]) :
"memory"); } while (0)
;
646 FD_ZERO (&wr)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&wr)->fds_bits)[0]) :
"memory"); } while (0)
;
647 n = 0;
648
649 lloopstart (listener_list, j)for (j = (void *) (listener_list).head; j;) { struct list_item
*__tl; __tl = (void *) j->next;
650 {
651 if (j->listen_socket)
652 {
653 FD_SET (j->fd, &rd)(((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask)))))
;
654 n = MAX (n, j->fd)(((n)>(j->fd))?(n):(j->fd));
655 }
656 }
657 lloopend (listener_list, j)j = (void *) __tl; };
658
659 /* waiting part */
660 n = select (n + 1, &rd, &wr, NULL((void*)0), NULL((void*)0));
661 if (n == -1 && errno(*__errno_location ()) == EINTR4)
662 return -1;
663 if (n < 0)
664 {
665 perror ("select()");
666 exit (1);
667 }
668
669 /* find which one is ready */
670 lloopstart (listener_list, j)for (j = (void *) (listener_list).head; j;) { struct list_item
*__tl; __tl = (void *) j->next;
671 {
672 /* a new connection has arrived */
673 if (FD_ISSET (j->fd, &rd)((((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask))))) != 0)
&& j->listen_socket)
674 {
675 sock = j->fd;
676 break;
677 }
678 }
679 lloopend (listener_list, j)j = (void *) __tl; };
680 return sock;
681}
682
683int
684listen_socket (const char *name, int listen_port, int socktype)
685{
686 struct addrinfo hints, *res, *ptr;
687 char portname[6];
688 int s;
689 int yes;
690 listener_item *j = NULL((void*)0);
691
692 snprintf (portname, sizeof (portname), "%d", listen_port);
693 memset (&hints, 0, sizeof (hints));
694 hints.ai_socktype = socktype;
695 hints.ai_flags = AI_PASSIVE0x0001
696#ifdef AI_ADDRCONFIG0x0020
697 | AI_ADDRCONFIG0x0020
698#endif
699 ;
700
701 if ((s = getaddrinfo (NULL((void*)0), portname, &hints, &res)) != 0)
702 {
703 fprintf (stderrstderr, "getaddrinfo() failed: %s\n", gai_strerror (s));
704 return -1;
705 }
706
707 for (ptr = res; ptr != NULL((void*)0); ptr = ptr->ai_next)
708 {
709#ifndef HAVE_IPV61
710 if (ptr->ai_family != AF_INET2) continue;
711#endif
712
713 /* Print what we are doing. */
714 {
715 char topbuf[512];
716
717 fprintf (stderrstderr, "%s listening on %s...",
718 name, human_addr (ptr->ai_addr, ptr->ai_addrlen,
719 topbuf, sizeof (topbuf)));
720 }
721
722 if ((s = socket (ptr->ai_family, ptr->ai_socktype,
723 ptr->ai_protocol)) < 0)
724 {
725 perror ("socket() failed");
726 continue;
727 }
728
729 if (socktype == SOCK_STREAMSOCK_STREAM)
730 {
731 yes = 1;
732 if (setsockopt (s, SOL_SOCKET1, SO_REUSEADDR2,
733 (const void *) &yes, sizeof (yes)) < 0)
734 {
735 perror ("setsockopt() failed");
736 close (s);
737 continue;
738 }
739 }
740 else
741 {
742#if defined(IP_DONTFRAG)
743 yes = 1;
744 if (setsockopt (s, IPPROTO_IPIPPROTO_IP, IP_DONTFRAG,
745 (const void *) &yes, sizeof (yes)) < 0)
746 perror ("setsockopt(IP_DF) failed");
747#elif defined(IP_MTU_DISCOVER10)
748 yes = IP_PMTUDISC_DO2;
749 if (setsockopt(s, IPPROTO_IPIPPROTO_IP, IP_MTU_DISCOVER10,
750 (const void*) &yes, sizeof (yes)) < 0)
751 perror ("setsockopt(IP_DF) failed");
752#endif
753 }
754
755 if (bind (s, ptr->ai_addr, ptr->ai_addrlen) < 0)
756 {
757 perror ("bind() failed");
758 close (s);
759 continue;
760 }
761
762 if (socktype == SOCK_STREAMSOCK_STREAM)
763 {
764 if (listen (s, 10) < 0)
765 {
766 perror ("listen() failed");
767 exit(1);
768 }
769 }
770
771 /* new list entry for the connection */
772 lappend (listener_list){ struct list_item *__t; __t = (struct list_item *) malloc ((
listener_list).item_size); memset (__t, 0, (listener_list).item_size
); __t->prev = (struct list_item *) (listener_list).tail; if
(__t->prev) __t->prev->next = __t; __t->next = 0
; if (!(listener_list).head) (listener_list).head = (void *) __t
; (listener_list).tail = (void *) __t; (listener_list).length
++; }
;
773 j = listener_list.tail;
774 j->listen_socket = 1;
775 j->fd = s;
776
777 /* Complete earlier message. */
778 fprintf (stderrstderr, "done\n");
779 }
780
781 fflush (stderrstderr);
782
783 freeaddrinfo (res);
784
785 return s;
786}
787
788/* strips \r\n from the end of the string
789 */
790static void
791strip (char *data)
792{
793 int i;
794 int len = strlen (data);
795
796 for (i = 0; i < len; i++)
797 {
798 if (data[i] == '\r' && data[i + 1] == '\n' && data[i + 1] == 0)
799 {
800 data[i] = '\n';
801 data[i + 1] = 0;
802 break;
803 }
804 }
805}
806
807static void
808get_response (gnutls_session_t session, char *request,
809 char **response, int *response_length)
810{
811 char *p, *h;
812
813 if (http != 0)
814 {
815 if (strncmp (request, "GET ", 4))
816 goto unimplemented;
817
818 if (!(h = strchr (request, '\n')))
819 goto unimplemented;
820
821 *h++ = '\0';
822 while (*h == '\r' || *h == '\n')
823 h++;
824
825 if (!(p = strchr (request + 4, ' ')))
826 goto unimplemented;
827 *p = '\0';
828 }
829/* *response = peer_print_info(session, request+4, h, response_length); */
830 if (http != 0)
831 {
832 *response = peer_print_info (session, response_length, h);
833 }
834 else
835 {
836 strip (request);
837 fprintf (stderrstderr, "received: %s\n", request);
838 if (request[0] == request[1] && request[0] == '*')
839 {
840 if (strncmp
841 (request, "**REHANDSHAKE**",
842 sizeof ("**REHANDSHAKE**") - 1) == 0)
843 {
844 fprintf (stderrstderr, "*** Sending rehandshake request\n");
845 gnutls_rehandshake (session);
846 }
847 *response = NULL((void*)0);
848 *response_length = 0;
849 return;
850 }
851 *response = strdup (request);
852 *response_length = ((*response) ? strlen (*response) : 0);
853 }
854
855 return;
856
857unimplemented:
858 *response = strdup (HTTP_UNIMPLEMENTED"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>501 Method Not Implemented</TITLE>\r\n</HEAD><BODY>\r\n<H1>Method Not Implemented</H1>\r\n<HR>\r\n</BODY></HTML>\r\n");
859 *response_length = ((*response) ? strlen (*response) : 0);
860}
861
862static void terminate (int sig) __attribute__ ((noreturn));
863
864static void
865terminate (int sig)
866{
867 fprintf (stderrstderr, "Exiting via signal %d\n", sig);
868 exit (1);
869}
870
871
872static void
873check_alert (gnutls_session_t session, int ret)
874{
875 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED-16
876 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED-12)
877 {
878 int last_alert = gnutls_alert_get (session);
879 if (last_alert == GNUTLS_A_NO_RENEGOTIATION &&
880 ret == GNUTLS_E_WARNING_ALERT_RECEIVED-16)
881 printf
882 ("* Received NO_RENEGOTIATION alert. Client does not support renegotiation.\n");
883 else
884 printf ("* Received alert '%d': %s.\n", last_alert,
885 gnutls_alert_get_name (last_alert));
886 }
887}
888
889static void
890tls_log_func (int level, const char *str)
891{
892 fprintf (stderrstderr, "|<%d>| %s", level, str);
893}
894
895static void
896tls_audit_log_func (gnutls_session_t session, const char *str)
897{
898 fprintf (stderrstderr, "|<%p>| %s", session, str);
899}
900
901static void gaa_parser (int argc, char **argv);
902
903int
904main (int argc, char **argv)
905{
906 int ret;
907 char name[256];
908
909 set_program_name (argv[0]);
910
911#ifndef _WIN32
912 signal (SIGPIPE13, SIG_IGN((__sighandler_t) 1));
913 signal (SIGHUP1, SIG_IGN((__sighandler_t) 1));
914 signal (SIGTERM15, terminate);
915 if (signal (SIGINT2, terminate) == SIG_IGN((__sighandler_t) 1))
916 signal (SIGINT2, SIG_IGN((__sighandler_t) 1)); /* e.g. background process */
917#endif
918
919 sockets_init ();
920
921 gaa_parser (argc, argv);
922
923 if (nodb == 0)
924 wrap_db_init ();
925
926 if (info.udp != 0)
927 strcpy(name, "UDP ");
928 else name[0] = 0;
929
930 if (http == 1)
931 {
932 strcat (name, "HTTP Server");
933 }
934 else
935 {
936 strcat (name, "Echo Server");
937 }
938
939 gnutls_global_set_log_function (tls_log_func);
940 gnutls_global_set_audit_log_function (tls_audit_log_func);
941 gnutls_global_set_log_level (debug);
942
943 if ((ret = gnutls_global_init ()) < 0)
944 {
945 fprintf (stderrstderr, "global_init: %s\n", gnutls_strerror (ret));
946 exit (1);
947 }
948
949#ifdef ENABLE_PKCS111
950 pkcs11_common ();
951#endif
952
953 /* Note that servers must generate parameters for
954 * Diffie-Hellman. See gnutls_dh_params_generate(), and
955 * gnutls_dh_params_set().
956 */
957 if (generate != 0)
958 {
959 generate_rsa_params ();
960 generate_dh_primes ();
961 }
962 else if (dh_params_file)
963 {
964 read_dh_params ();
965 }
966 else
967 {
968 static_dh_params ();
969 }
970
971 if (gnutls_certificate_allocate_credentials (&cert_cred) < 0)
972 {
973 fprintf (stderrstderr, "memory error\n");
974 exit (1);
975 }
976
977 if (x509_cafile != NULL((void*)0))
978 {
979 if ((ret = gnutls_certificate_set_x509_trust_file
980 (cert_cred, x509_cafile, x509ctype)) < 0)
981 {
982 fprintf (stderrstderr, "Error reading '%s'\n", x509_cafile);
983 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
984 exit (1);
985 }
986 else
987 {
988 printf ("Processed %d CA certificate(s).\n", ret);
989 }
990 }
991#ifdef ENABLE_PKI1
992 if (x509_crlfile != NULL((void*)0))
993 {
994 if ((ret = gnutls_certificate_set_x509_crl_file
995 (cert_cred, x509_crlfile, x509ctype)) < 0)
996 {
997 fprintf (stderrstderr, "Error reading '%s'\n", x509_crlfile);
998 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
999 exit (1);
1000 }
1001 else
1002 {
1003 printf ("Processed %d CRL(s).\n", ret);
1004 }
1005 }
1006#endif
1007
1008#ifdef ENABLE_OPENPGP1
1009 if (pgp_keyring != NULL((void*)0))
1010 {
1011 ret =
1012 gnutls_certificate_set_openpgp_keyring_file (cert_cred, pgp_keyring,
1013 GNUTLS_OPENPGP_FMT_BASE64);
1014 if (ret < 0)
1015 {
1016 fprintf (stderrstderr, "Error setting the OpenPGP keyring file\n");
1017 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1018 }
1019 }
1020
1021 if (pgp_certfile != NULL((void*)0))
1022 {
1023 if (info.pgp_subkey != NULL((void*)0))
1024 ret = gnutls_certificate_set_openpgp_key_file2
1025 (cert_cred, pgp_certfile, pgp_keyfile, info.pgp_subkey,
1026 GNUTLS_OPENPGP_FMT_BASE64);
1027 else
1028 ret = gnutls_certificate_set_openpgp_key_file
1029 (cert_cred, pgp_certfile, pgp_keyfile, GNUTLS_OPENPGP_FMT_BASE64);
1030
1031 if (ret < 0)
1032 {
1033 fprintf (stderrstderr,
1034 "Error[%d] while reading the OpenPGP key pair ('%s', '%s')\n",
1035 ret, pgp_certfile, pgp_keyfile);
1036 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1037 }
1038 }
1039#endif
1040
1041 if (x509_certfile != NULL((void*)0))
1042 if ((ret = gnutls_certificate_set_x509_key_file
1043 (cert_cred, x509_certfile, x509_keyfile, x509ctype)) < 0)
1044 {
1045 fprintf (stderrstderr,
1046 "Error reading '%s' or '%s'\n", x509_certfile, x509_keyfile);
1047 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1048 exit (1);
1049 }
1050
1051 if (x509_dsacertfile != NULL((void*)0))
1052 if ((ret = gnutls_certificate_set_x509_key_file
1053 (cert_cred, x509_dsacertfile, x509_dsakeyfile, x509ctype)) < 0)
1054 {
1055 fprintf (stderrstderr, "Error reading '%s' or '%s'\n",
1056 x509_dsacertfile, x509_dsakeyfile);
1057 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1058 exit (1);
1059 }
1060
1061 if (x509_ecccertfile != NULL((void*)0))
1062 if ((ret = gnutls_certificate_set_x509_key_file
1063 (cert_cred, x509_ecccertfile, x509_ecckeyfile, x509ctype)) < 0)
1064 {
1065 fprintf (stderrstderr, "Error reading '%s' or '%s'\n",
1066 x509_ecccertfile, x509_ecckeyfile);
1067 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1068 exit (1);
1069 }
1070
1071 gnutls_certificate_set_params_function (cert_cred, get_params);
1072/* gnutls_certificate_set_dh_params(cert_cred, dh_params);
1073 * gnutls_certificate_set_rsa_export_params(cert_cred, rsa_params);
1074 */
1075
1076 /* this is a password file (created with the included srpcrypt utility)
1077 * Read README.crypt prior to using SRP.
1078 */
1079#ifdef ENABLE_SRP1
1080 if (srp_passwd != NULL((void*)0))
1081 {
1082 gnutls_srp_allocate_server_credentials (&srp_cred);
1083
1084 if ((ret =
1085 gnutls_srp_set_server_credentials_file (srp_cred, srp_passwd,
1086 srp_passwd_conf)) < 0)
1087 {
1088 /* only exit is this function is not disabled
1089 */
1090 fprintf (stderrstderr, "Error while setting SRP parameters\n");
1091 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1092 }
1093 }
1094#endif
1095
1096 /* this is a password file
1097 */
1098#ifdef ENABLE_PSK1
1099 if (psk_passwd != NULL((void*)0))
1100 {
1101 gnutls_psk_allocate_server_credentials (&psk_cred);
1102
1103 if ((ret =
1104 gnutls_psk_set_server_credentials_file (psk_cred, psk_passwd)) < 0)
1105 {
1106 /* only exit is this function is not disabled
1107 */
1108 fprintf (stderrstderr, "Error while setting PSK parameters\n");
1109 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1110 }
1111
1112 if (info.psk_hint)
1113 {
1114 ret = gnutls_psk_set_server_credentials_hint (psk_cred,
1115 info.psk_hint);
1116 if (ret)
1117 {
1118 fprintf (stderrstderr, "Error setting PSK identity hint.\n");
1119 GERR (ret)fprintf(stdout, "Error: %s\n", safe_strerror(ret));
1120 }
1121 }
1122
1123 gnutls_psk_set_server_params_function (psk_cred, get_params);
1124 }
1125#endif
1126
1127#ifdef ENABLE_ANON1
1128 gnutls_anon_allocate_server_credentials (&dh_cred);
1129 gnutls_anon_set_server_params_function (dh_cred, get_params);
1130
1131/* gnutls_anon_set_server_dh_params(dh_cred, dh_params); */
1132#endif
1133
1134#ifdef ENABLE_SESSION_TICKET
1135 if (noticket == 0)
1136 gnutls_session_ticket_key_generate (&session_ticket_key);
1137#endif
1138
1139 if (info.udp)
1140 udp_server(name, info.port, info.mtu);
1141 else
1142 tcp_server(name, info.port);
1143}
1144
1145static void tcp_server(const char* name, int port)
1146{
1147 int n, s;
1148 char topbuf[512];
1149 int accept_fd;
1150 struct sockaddr_storage client_address;
1151 socklen_t calen;
1152
1153 s = listen_socket (name, port, SOCK_STREAMSOCK_STREAM);
1154 if (s < 0)
1
Taking false branch
1155 exit (1);
1156
1157 for (;;)
2
Loop condition is true. Entering loop body
1158 {
1159 listener_item *j;
1160 fd_set rd, wr;
1161#ifndef _WIN32
1162 int val;
1163#endif
1164
1165 FD_ZERO (&rd)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&rd)->fds_bits)[0]) :
"memory"); } while (0)
;
1166 FD_ZERO (&wr)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&wr)->fds_bits)[0]) :
"memory"); } while (0)
;
1167 n = 0;
1168
1169/* flag which connections we are reading or writing to within the fd sets */
1170 lloopstart (listener_list, j)for (j = (void *) (listener_list).head; j;) { struct list_item
*__tl; __tl = (void *) j->next;
1171 {
1172
1173#ifndef _WIN32
1174 val = fcntl (j->fd, F_GETFL3, 0);
1175 if ((val == -1) || (fcntl (j->fd, F_SETFL4, val | O_NONBLOCK04000) < 0))
3
Taking false branch
1176 {
1177 perror ("fcntl()");
1178 exit (1);
1179 }
1180#endif
1181
1182 if (j->listen_socket)
4
Taking false branch
1183 {
1184 FD_SET (j->fd, &rd)(((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask)))))
;
1185 n = MAX (n, j->fd)(((n)>(j->fd))?(n):(j->fd));
1186 }
1187 if (j->http_state == HTTP_STATE_REQUEST1)
5
Taking false branch
1188 {
1189 FD_SET (j->fd, &rd)(((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask)))))
;
1190 n = MAX (n, j->fd)(((n)>(j->fd))?(n):(j->fd));
1191 }
1192 if (j->http_state == HTTP_STATE_RESPONSE2)
6
Taking false branch
1193 {
1194 FD_SET (j->fd, &wr)(((&wr)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask)))))
;
1195 n = MAX (n, j->fd)(((n)>(j->fd))?(n):(j->fd));
1196 }
1197 }
1198 lloopend (listener_list, j)j = (void *) __tl; };
1199
1200/* core operation */
1201 n = select (n + 1, &rd, &wr, NULL((void*)0), NULL((void*)0));
1202 if (n == -1 && errno(*__errno_location ()) == EINTR4)
7
Taking false branch
1203 continue;
1204 if (n < 0)
8
Taking false branch
1205 {
1206 perror ("select()");
1207 exit (1);
1208 }
1209
1210/* read or write to each connection as indicated by select()'s return argument */
1211 lloopstart (listener_list, j)for (j = (void *) (listener_list).head; j;) { struct list_item
*__tl; __tl = (void *) j->next;
1212 {
1213
1214 /* a new connection has arrived */
1215 if (FD_ISSET (j->fd, &rd)((((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask))))) != 0)
&& j->listen_socket)
9
Taking false branch
1216 {
1217 gnutls_session_t tls_session;
1218
1219 tls_session = initialize_session (0);
1220
1221 calen = sizeof (client_address);
1222 memset (&client_address, 0, calen);
1223 accept_fd = accept (j->fd, (struct sockaddr *) &client_address,
1224 &calen);
1225
1226 if (accept_fd < 0)
1227 {
1228 perror ("accept()");
1229 }
1230 else
1231 {
1232 time_t tt;
1233 char *ctt;
1234
1235 /* new list entry for the connection */
1236 lappend (listener_list){ struct list_item *__t; __t = (struct list_item *) malloc ((
listener_list).item_size); memset (__t, 0, (listener_list).item_size
); __t->prev = (struct list_item *) (listener_list).tail; if
(__t->prev) __t->prev->next = __t; __t->next = 0
; if (!(listener_list).head) (listener_list).head = (void *) __t
; (listener_list).tail = (void *) __t; (listener_list).length
++; }
;
1237 j = listener_list.tail;
1238 j->http_request = (char *) strdup ("");
1239 j->http_state = HTTP_STATE_REQUEST1;
1240 j->fd = accept_fd;
1241
1242 j->tls_session = tls_session;
1243 gnutls_transport_set_ptr (tls_session,
1244 (gnutls_transport_ptr_t)
1245 gl_fd_to_handle (accept_fd)(accept_fd));
1246 j->handshake_ok = 0;
1247
1248 if (verbose == 0)
1249 {
1250 tt = time (0);
1251 ctt = ctime (&tt);
1252 ctt[strlen (ctt) - 1] = 0;
1253
1254 printf ("\n* Accepted connection from %s on %s\n",
1255 human_addr ((struct sockaddr *)
1256 &client_address, calen, topbuf,
1257 sizeof (topbuf)), ctt);
1258 }
1259 }
1260 }
1261
1262 if (FD_ISSET (j->fd, &rd)((((&rd)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask))))) != 0)
&& !j->listen_socket)
10
Taking true branch
1263 {
1264/* read partial GET request */
1265 char buf[1024];
1266 int r, ret;
1267
1268 if (j->handshake_ok == 0)
11
Taking false branch
1269 {
1270 r = gnutls_handshake (j->tls_session);
1271 if (r < 0 && gnutls_error_is_fatal (r) == 0)
1272 {
1273 check_alert (j->tls_session, r);
1274 /* nothing */
1275 }
1276 else if (r < 0 && gnutls_error_is_fatal (r) == 1)
1277 {
1278 check_alert (j->tls_session, r);
1279 fprintf (stderrstderr, "Error in handshake\n");
1280 GERR (r)fprintf(stdout, "Error: %s\n", safe_strerror(r));
1281
1282 do
1283 {
1284 ret =
1285 gnutls_alert_send_appropriate (j->tls_session, r);
1286 }
1287 while (ret == GNUTLS_E_AGAIN-28
1288 || ret == GNUTLS_E_INTERRUPTED-52);
1289 j->http_state = HTTP_STATE_CLOSING3;
1290 }
1291 else if (r == 0)
1292 {
1293 if (gnutls_session_is_resumed (j->tls_session) != 0
1294 && verbose == 0)
1295 printf ("*** This is a resumed session\n");
1296
1297 if (verbose == 0)
1298 {
1299 printf ("\n* Successful handshake from %s\n",
1300 human_addr ((struct sockaddr *)
1301 &client_address, calen, topbuf,
1302 sizeof (topbuf)));
1303 print_info (j->tls_session, NULL((void*)0), 1);
1304 }
1305 j->handshake_ok = 1;
1306 }
1307 }
1308
1309 if (j->handshake_ok == 1)
12
Taking true branch
1310 {
1311 r = gnutls_record_recv (j->tls_session, buf,
1312 MIN (1024, SMALL_READ_TEST)(((1024)<((2147483647)))?(1024):((2147483647))));
1313 if (r == GNUTLS_E_INTERRUPTED-52 || r == GNUTLS_E_AGAIN-28)
13
Taking true branch
1314 {
1315 /* do nothing */
1316 }
1317 else if (r <= 0)
1318 {
1319 if (r == GNUTLS_E_REHANDSHAKE-37)
1320 {
1321 fprintf (stderrstderr, "*** Received hello message\n");
1322 do
1323 {
1324 r = gnutls_handshake (j->tls_session);
1325 }
1326 while (r == GNUTLS_E_INTERRUPTED-52
1327 || r == GNUTLS_E_AGAIN-28);
1328
1329 if (r < 0)
1330 {
1331 do
1332 {
1333 ret = gnutls_alert_send_appropriate
1334 (j->tls_session, r);
1335 }
1336 while (ret == GNUTLS_E_AGAIN-28
1337 || ret == GNUTLS_E_INTERRUPTED-52);
1338
1339 GERR (r)fprintf(stdout, "Error: %s\n", safe_strerror(r));
1340 j->http_state = HTTP_STATE_CLOSING3;
1341 }
1342 }
1343 else
1344 {
1345 j->http_state = HTTP_STATE_CLOSING3;
1346 if (r < 0 && r != GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9)
1347 {
1348 check_alert (j->tls_session, r);
1349 fprintf (stderrstderr, "Error while receiving data\n");
1350 GERR (r)fprintf(stdout, "Error: %s\n", safe_strerror(r));
1351 }
1352 }
1353 }
1354 else
1355 {
1356 j->http_request =
1357 realloc (j->http_request, j->request_length + r + 1);
1358 if (j->http_request != NULL((void*)0))
1359 {
1360 memcpy (j->http_request + j->request_length, buf, r);
1361 j->request_length += r;
1362 j->http_request[j->request_length] = '\0';
1363 }
1364 else
1365 j->http_state = HTTP_STATE_CLOSING3;
1366
1367 }
1368/* check if we have a full HTTP header */
1369
1370 j->http_response = NULL((void*)0);
1371 if (j->http_request != NULL((void*)0))
14
Assuming pointer value is null
15
Taking false branch
1372 {
1373 if ((http == 0 && strchr (j->http_request, '\n'))
1374 || strstr (j->http_request, "\r\n\r\n")
1375 || strstr (j->http_request, "\n\n"))
1376 {
1377 get_response (j->tls_session, j->http_request,
1378 &j->http_response, &j->response_length);
1379 j->http_state = HTTP_STATE_RESPONSE2;
1380 j->response_written = 0;
1381 }
1382 }
1383 }
1384 }
1385 if (FD_ISSET (j->fd, &wr)((((&wr)->fds_bits)[((j->fd) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((j->fd) % (8 * (int) sizeof
(__fd_mask))))) != 0)
)
16
Taking true branch
1386 {
1387/* write partial response request */
1388 int r;
1389
1390 if (j->handshake_ok == 0)
17
Taking false branch
1391 {
1392 r = gnutls_handshake (j->tls_session);
1393 if (r < 0 && gnutls_error_is_fatal (r) == 0)
1394 {
1395 check_alert (j->tls_session, r);
1396 /* nothing */
1397 }
1398 else if (r < 0 && gnutls_error_is_fatal (r) == 1)
1399 {
1400 int ret;
1401
1402 j->http_state = HTTP_STATE_CLOSING3;
1403 check_alert (j->tls_session, r);
1404 fprintf (stderrstderr, "Error in handshake\n");
1405 GERR (r)fprintf(stdout, "Error: %s\n", safe_strerror(r));
1406
1407 do
1408 {
1409 ret =
1410 gnutls_alert_send_appropriate (j->tls_session, r);
1411 }
1412 while (ret == GNUTLS_E_AGAIN-28);
1413 }
1414 else if (r == 0)
1415 {
1416 if (gnutls_session_is_resumed (j->tls_session) != 0
1417 && verbose == 0)
1418 printf ("*** This is a resumed session\n");
1419 if (verbose == 0)
1420 {
1421 printf ("- connection from %s\n",
1422 human_addr ((struct sockaddr *)
1423 &client_address, calen, topbuf,
1424 sizeof (topbuf)));
1425
1426 print_info (j->tls_session, NULL((void*)0), 1);
1427 }
1428 j->handshake_ok = 1;
1429 }
1430 }
1431
1432 if (j->handshake_ok == 1 && j->http_response != NULL((void*)0))
18
Taking false branch
1433 {
1434 /* FIXME if j->http_response == NULL? */
1435 r = gnutls_record_send (j->tls_session,
1436 j->http_response +
1437 j->response_written,
1438 MIN (j->response_length -(((j->response_length - j->response_written)<((2147483647
)))?(j->response_length - j->response_written):((2147483647
)))
1439 j->response_written,(((j->response_length - j->response_written)<((2147483647
)))?(j->response_length - j->response_written):((2147483647
)))
1440 SMALL_READ_TEST)(((j->response_length - j->response_written)<((2147483647
)))?(j->response_length - j->response_written):((2147483647
)))
);
1441 if (r == GNUTLS_E_INTERRUPTED-52 || r == GNUTLS_E_AGAIN-28)
1442 {
1443 /* do nothing */
1444 }
1445 else if (r <= 0)
1446 {
1447 if (http != 0)
1448 j->http_state = HTTP_STATE_CLOSING3;
1449 else
1450 {
1451 j->http_state = HTTP_STATE_REQUEST1;
1452 free (j->http_response);
1453 j->response_length = 0;
1454 j->request_length = 0;
1455 j->http_request[0] = 0;
1456 }
1457
1458 if (r < 0)
1459 {
1460 fprintf (stderrstderr, "Error while sending data\n");
1461 GERR (r)fprintf(stdout, "Error: %s\n", safe_strerror(r));
1462 }
1463 check_alert (j->tls_session, r);
1464 }
1465 else
1466 {
1467 j->response_written += r;
1468/* check if we have written a complete response */
1469 if (j->response_written == j->response_length)
1470 {
1471 if (http != 0)
1472 j->http_state = HTTP_STATE_CLOSING3;
1473 else
1474 {
1475 j->http_state = HTTP_STATE_REQUEST1;
1476 free (j->http_response);
1477 j->response_length = 0;
1478 j->request_length = 0;
1479 j->http_request[0] = 0;
1480 }
1481 }
1482 }
1483 }
1484 else
1485 {
1486 j->request_length = 0;
1487 j->http_request[0] = 0;
19
Dereference of null pointer
1488 j->http_state = HTTP_STATE_REQUEST1;
1489 }
1490 }
1491 }
1492 lloopend (listener_list, j)j = (void *) __tl; };
1493
1494/* loop through all connections, closing those that are in error */
1495 lloopstart (listener_list, j)for (j = (void *) (listener_list).head; j;) { struct list_item
*__tl; __tl = (void *) j->next;
1496 {
1497 if (j->http_state == HTTP_STATE_CLOSING3)
1498 {
1499 ldeleteinc (listener_list, j){ struct list_item *__t; (listener_list).search = 0; __t = (void
*) j; if ((void *) (listener_list).head == (void *) __t) (listener_list
).head = (listener_list).head->next; if ((void *) (listener_list
).tail == (void *) __t) (listener_list).tail = (listener_list
).tail->prev; if (__t->next) __t->next->prev = __t
->prev; if (__t->prev) __t->prev->next = __t->
next; __t = __t->next; if ((listener_list).free_func) (*(listener_list
).free_func) ((void *) j); free (j); j = (void *) __t; (listener_list
).length--; }
;
1500 }
1501 }
1502 lloopend (listener_list, j)j = (void *) __tl; };
1503 }
1504
1505
1506 gnutls_certificate_free_credentials (cert_cred);
1507
1508#ifdef ENABLE_SRP1
1509 if (srp_cred)
1510 gnutls_srp_free_server_credentials (srp_cred);
1511#endif
1512
1513#ifdef ENABLE_PSK1
1514 if (psk_cred)
1515 gnutls_psk_free_server_credentials (psk_cred);
1516#endif
1517
1518#ifdef ENABLE_ANON1
1519 gnutls_anon_free_server_credentials (dh_cred);
1520#endif
1521
1522#ifdef ENABLE_SESSION_TICKET
1523 if (noticket == 0)
1524 gnutls_free (session_ticket_key.data);
1525#endif
1526
1527 if (nodb == 0)
1528 wrap_db_deinit ();
1529 gnutls_global_deinit ();
1530
1531}
1532
1533void
1534gaa_parser (int argc, char **argv)
1535{
1536 if (gaa (argc, argv, &info) != -1)
1537 {
1538 fprintf (stderrstderr,
1539 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
1540 exit (1);
1541 }
1542
1543 disable_client_cert = info.disable_client_cert;
1544 require_cert = info.require_cert;
1545 debug = info.debug;
1546 verbose = info.quiet;
1547 nodb = info.nodb;
1548 noticket = info.noticket;
1549
1550 if (info.http == 0)
1551 http = 0;
1552 else
1553 http = 1;
1554
1555 if (info.fmtder == 0)
1556 x509ctype = GNUTLS_X509_FMT_PEM;
1557 else
1558 x509ctype = GNUTLS_X509_FMT_DER;
1559
1560 if (info.generate == 0)
1561 generate = 0;
1562 else
1563 generate = 1;
1564
1565 dh_params_file = info.dh_params_file;
1566
1567 x509_certfile = info.x509_certfile;
1568 x509_keyfile = info.x509_keyfile;
1569 x509_dsacertfile = info.x509_dsacertfile;
1570 x509_dsakeyfile = info.x509_dsakeyfile;
1571 x509_ecccertfile = info.x509_ecccertfile;
1572 x509_ecckeyfile = info.x509_ecckeyfile;
1573 x509_cafile = info.x509_cafile;
1574 x509_crlfile = info.x509_crlfile;
1575 pgp_certfile = info.pgp_certfile;
1576 pgp_keyfile = info.pgp_keyfile;
1577 srp_passwd = info.srp_passwd;
1578 srp_passwd_conf = info.srp_passwd_conf;
1579
1580 psk_passwd = info.psk_passwd;
1581
1582 pgp_keyring = info.pgp_keyring;
1583}
1584
1585extern void serv_version (void);
1586
1587void
1588serv_version (void)
1589{
1590 const char *p = PACKAGE_NAME"GnuTLS";
1591 if (strcmp (gnutls_check_version (NULL((void*)0)), PACKAGE_VERSION"3.0.12") != 0)
1592 p = PACKAGE_STRING"GnuTLS 3.0.12";
1593 version_etc (stdoutstdout, program_name, p, gnutls_check_version (NULL((void*)0)),
1594 "Nikos Mavrogiannopoulos", (char *) NULL((void*)0));
1595}
1596
1597/* session resuming support */
1598
1599#define SESSION_ID_SIZE32 32
1600#define SESSION_DATA_SIZE1024 1024
1601
1602typedef struct
1603{
1604 char session_id[SESSION_ID_SIZE32];
1605 unsigned int session_id_size;
1606
1607 char session_data[SESSION_DATA_SIZE1024];
1608 unsigned int session_data_size;
1609} CACHE;
1610
1611static CACHE *cache_db;
1612int cache_db_ptr = 0;
1613
1614static void
1615wrap_db_init (void)
1616{
1617 /* allocate cache_db */
1618 cache_db = calloc (1, ssl_session_cache * sizeof (CACHE));
1619}
1620
1621static void
1622wrap_db_deinit (void)
1623{
1624}
1625
1626static int
1627wrap_db_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data)
1628{
1629
1630 if (cache_db == NULL((void*)0))
1631 return -1;
1632
1633 if (key.size > SESSION_ID_SIZE32)
1634 return -1;
1635 if (data.size > SESSION_DATA_SIZE1024)
1636 return -1;
1637
1638 memcpy (cache_db[cache_db_ptr].session_id, key.data, key.size);
1639 cache_db[cache_db_ptr].session_id_size = key.size;
1640
1641 memcpy (cache_db[cache_db_ptr].session_data, data.data, data.size);
1642 cache_db[cache_db_ptr].session_data_size = data.size;
1643
1644 cache_db_ptr++;
1645 cache_db_ptr %= ssl_session_cache;
1646
1647 return 0;
1648}
1649
1650static gnutls_datum_t
1651wrap_db_fetch (void *dbf, gnutls_datum_t key)
1652{
1653 gnutls_datum_t res = { NULL((void*)0), 0 };
1654 int i;
1655
1656 if (cache_db == NULL((void*)0))
1657 return res;
1658
1659 for (i = 0; i < ssl_session_cache; i++)
1660 {
1661 if (key.size == cache_db[i].session_id_size &&
1662 memcmp (key.data, cache_db[i].session_id, key.size) == 0)
1663 {
1664 res.size = cache_db[i].session_data_size;
1665
1666 res.data = gnutls_malloc (res.size);
1667 if (res.data == NULL((void*)0))
1668 return res;
1669
1670 memcpy (res.data, cache_db[i].session_data, res.size);
1671
1672 return res;
1673 }
1674 }
1675 return res;
1676}
1677
1678static int
1679wrap_db_delete (void *dbf, gnutls_datum_t key)
1680{
1681 int i;
1682
1683 if (cache_db == NULL((void*)0))
1684 return -1;
1685
1686 for (i = 0; i < ssl_session_cache; i++)
1687 {
1688 if (key.size == (unsigned int) cache_db[i].session_id_size &&
1689 memcmp (key.data, cache_db[i].session_id, key.size) == 0)
1690 {
1691
1692 cache_db[i].session_id_size = 0;
1693 cache_db[i].session_data_size = 0;
1694
1695 return 0;
1696 }
1697 }
1698
1699 return -1;
1700}