GNU libmicrohttpd  0.9.71
connection_https.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007, 2008, 2010 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 */
20 
29 #include "internal.h"
30 #include "connection.h"
31 #include "connection_https.h"
32 #include "memorypool.h"
33 #include "response.h"
34 #include "mhd_mono_clock.h"
35 #include <gnutls/gnutls.h>
36 
37 
47 static ssize_t
48 recv_tls_adapter (struct MHD_Connection *connection,
49  void *other,
50  size_t i)
51 {
52  ssize_t res;
53 
54  if (i > SSIZE_MAX)
55  i = SSIZE_MAX;
56 
57  res = gnutls_record_recv (connection->tls_session,
58  other,
59  i);
60  if ( (GNUTLS_E_AGAIN == res) ||
61  (GNUTLS_E_INTERRUPTED == res) )
62  {
63 #ifdef EPOLL_SUPPORT
64  if (GNUTLS_E_AGAIN == res)
65  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
66 #endif
67  /* Any network errors means that buffer is empty. */
68  connection->tls_read_ready = false;
69  return MHD_ERR_AGAIN_;
70  }
71  if (res < 0)
72  {
73  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
74  disrupted); interpret as a hard error */
75  connection->tls_read_ready = false;
76  return MHD_ERR_NOTCONN_;
77  }
78 
79 #ifdef EPOLL_SUPPORT
80  /* Unlike non-TLS connections, do not reset "read-ready" if
81  * received amount smaller than provided amount, as TLS
82  * connections may receive data by fixed-size chunks. */
83 #endif /* EPOLL_SUPPORT */
84 
85  /* Check whether TLS buffers still have some unread data. */
86  connection->tls_read_ready = ( ((size_t) res == i) &&
87  (0 != gnutls_record_check_pending (
88  connection->tls_session)) );
89  return res;
90 }
91 
92 
102 bool
104 {
105  int ret;
106 
107  if ((MHD_TLS_CONN_INIT == connection->tls_state) ||
108  (MHD_TLS_CONN_HANDSHAKING == connection->tls_state))
109  {
110  ret = gnutls_handshake (connection->tls_session);
111  if (ret == GNUTLS_E_SUCCESS)
112  {
113  /* set connection TLS state to enable HTTP processing */
114  connection->tls_state = MHD_TLS_CONN_CONNECTED;
115  MHD_update_last_activity_ (connection);
116  return true;
117  }
118  if ( (GNUTLS_E_AGAIN == ret) ||
119  (GNUTLS_E_INTERRUPTED == ret) )
120  {
121  connection->tls_state = MHD_TLS_CONN_HANDSHAKING;
122  /* handshake not done */
123  return false;
124  }
125  /* handshake failed */
126  connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
127 #ifdef HAVE_MESSAGES
128  MHD_DLOG (connection->daemon,
129  _ ("Error: received handshake message out of context.\n"));
130 #endif
131  MHD_connection_close_ (connection,
133  return false;
134  }
135  return true;
136 }
137 
138 
145 void
147 {
148  connection->recv_cls = &recv_tls_adapter;
149 }
150 
151 
158 bool
160 {
161  if (MHD_TLS_CONN_WR_CLOSED > connection->tls_state)
162  {
163  const int res =
164  gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
165  if (GNUTLS_E_SUCCESS == res)
166  {
167  connection->tls_state = MHD_TLS_CONN_WR_CLOSED;
168  return true;
169  }
170  if ((GNUTLS_E_AGAIN == res) ||
171  (GNUTLS_E_INTERRUPTED == res))
172  {
173  connection->tls_state = MHD_TLS_CONN_WR_CLOSING;
174  return true;
175  }
176  else
177  connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
178  }
179  return false;
180 }
181 
182 
183 /* end of connection_https.c */
MHD_Connection::recv_cls
ReceiveCallback recv_cls
Definition: internal.h:706
_
#define _(String)
Definition: mhd_options.h:42
MHD_TLS_CONN_WR_CLOSING
@ MHD_TLS_CONN_WR_CLOSING
Definition: internal.h:548
MHD_Connection::tls_read_ready
bool tls_read_ready
Definition: internal.h:769
MHD_ERR_AGAIN_
#define MHD_ERR_AGAIN_
Definition: internal.h:1863
memorypool.h
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
MHD_run_tls_handshake_
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
Definition: connection_https.c:103
connection_https.h
Methods for managing connections.
response.h
Methods for managing response objects.
recv_tls_adapter
static ssize_t recv_tls_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition: connection_https.c:48
internal.h
internal shared structures
MHD_connection_close_
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
Definition: connection_close.c:83
MHD_TLS_CONN_CONNECTED
@ MHD_TLS_CONN_CONNECTED
Definition: internal.h:547
MHD_TLS_CONN_TLS_FAILED
@ MHD_TLS_CONN_TLS_FAILED
Definition: internal.h:552
mhd_mono_clock.h
internal monotonic clock functions implementations
MHD_TLS_CONN_WR_CLOSED
@ MHD_TLS_CONN_WR_CLOSED
Definition: internal.h:549
MHD_TLS_CONN_HANDSHAKING
@ MHD_TLS_CONN_HANDSHAKING
Definition: internal.h:546
SSIZE_MAX
#define SSIZE_MAX
Definition: mhd_limits.h:111
MHD_update_last_activity_
void MHD_update_last_activity_(struct MHD_Connection *connection)
Definition: connection_options.c:88
connection.h
Methods for managing connections.
MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_READ_READY
Definition: internal.h:600
MHD_Connection::daemon
struct MHD_Daemon * daemon
Definition: internal.h:675
MHD_REQUEST_TERMINATED_WITH_ERROR
@ MHD_REQUEST_TERMINATED_WITH_ERROR
Definition: microhttpd.h:1831
MHD_Connection
Definition: internal.h:634
MHD_ERR_NOTCONN_
#define MHD_ERR_NOTCONN_
Definition: internal.h:1874
MHD_tls_connection_shutdown
bool MHD_tls_connection_shutdown(struct MHD_Connection *connection)
Definition: connection_https.c:159
MHD_TLS_CONN_INIT
@ MHD_TLS_CONN_INIT
Definition: internal.h:545
MHD_set_https_callbacks
void MHD_set_https_callbacks(struct MHD_Connection *connection)
Definition: connection_https.c:146