1748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/*
2748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat This file is part of libmicrohttpd
3748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Copyright (C) 2007 Christian Grothoff
4748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
5748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat libmicrohttpd is free software; you can redistribute it and/or modify
6748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat it under the terms of the GNU General Public License as published
7748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat by the Free Software Foundation; either version 2, or (at your
8748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat option) any later version.
9748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
10748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat libmicrohttpd is distributed in the hope that it will be useful, but
11748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat WITHOUT ANY WARRANTY; without even the implied warranty of
12748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat General Public License for more details.
14748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
15748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat You should have received a copy of the GNU General Public License
16748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat along with libmicrohttpd; see the file COPYING.  If not, write to the
17748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Boston, MA 02111-1307, USA.
19748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */
20748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
21748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/**
22748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @file mhds_get_test.c
23748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @brief: daemon TLS alert response test-case
24748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat *
25748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @author Sagie Amir
26748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */
27748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
28748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "platform.h"
29748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "microhttpd.h"
30748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "internal.h"
31748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "tls_test_common.h"
32748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <gcrypt.h>
33748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
34748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef _WIN32
35748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef WIN32_LEAN_AND_MEAN
36748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define WIN32_LEAN_AND_MEAN 1
37748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* !WIN32_LEAN_AND_MEAN */
38748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <windows.h>
39748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
40748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
41748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratextern const char srv_key_pem[];
42748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratextern const char srv_self_signed_cert_pem[];
43748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
44748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic const int TIME_OUT = 3;
45748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
46748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic int
47748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattest_tls_session_time_out (gnutls_session_t session)
48748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
49748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int ret;
50748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket sd;
51748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct sockaddr_in sa;
52748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
53748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  sd = socket (AF_INET, SOCK_STREAM, 0);
54748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (sd == -1)
55748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
56748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
57748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return -1;
58748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
59748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
60748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  memset (&sa, '\0', sizeof (struct sockaddr_in));
61748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  sa.sin_family = AF_INET;
62748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  sa.sin_port = htons (DEAMON_TEST_PORT);
63748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
64748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
65748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd);
66748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
67748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  ret = connect (sd, &sa, sizeof (struct sockaddr_in));
68748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
69748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (ret < 0)
70748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
71748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT);
72748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      close (sd);
73748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return -1;
74748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
75748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
76748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  ret = gnutls_handshake (session);
77748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (ret < 0)
78748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
79748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "Handshake failed\n");
80748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      close (sd);
81748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return -1;
82748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
83748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
84748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  sleep (TIME_OUT + 1);
85748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
86748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  /* check that server has closed the connection */
87748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  /* TODO better RST trigger */
88748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (send (sd, "", 1, 0) == 0)
89748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
90748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "Connection failed to time-out\n");
91748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      close (sd);
92748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return -1;
93748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
94748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
95748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  close (sd);
96748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return 0;
97748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
98748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
99748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
100748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint
101748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratmain (int argc, char *const *argv)
102748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
103748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int errorCount = 0;;
104748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct MHD_Daemon *d;
105748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_session_t session;
106748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_datum_t key;
107748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_datum_t cert;
108748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_certificate_credentials_t xcred;
109748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
110748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
111748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
112748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef GCRYCTL_INITIALIZATION_FINISHED
113748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
114748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
115748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_global_init ();
116748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_global_set_log_level (11);
117748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
118748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
119748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_USE_DEBUG, DEAMON_TEST_PORT,
120748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        NULL, NULL, &http_dummy_ahc, NULL,
121748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT,
122748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
123748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
124748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_END);
125748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
126748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (d == NULL)
127748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
128748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, MHD_E_SERVER_INIT);
129748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return -1;
130748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
131748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
132748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != setup_session (&session, &key, &cert, &xcred))
133748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
134748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "failed to setup session\n");
135748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 1;
136748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
137748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  errorCount += test_tls_session_time_out (session);
138748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  teardown_session (session, &key, &cert, xcred);
139748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
140748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  print_test_result (errorCount, argv[0]);
141748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
142748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_stop_daemon (d);
143748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  gnutls_global_deinit ();
144748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
145748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return errorCount != 0;
146748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
147