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
47static ssize_t
48recv_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
102bool
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
145void
147{
148 connection->recv_cls = &recv_tls_adapter;
149}
150
151
158bool
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 */
Methods for managing connections.
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
bool MHD_tls_connection_shutdown(struct MHD_Connection *connection)
void MHD_set_https_callbacks(struct MHD_Connection *connection)
static ssize_t recv_tls_adapter(struct MHD_Connection *connection, void *other, size_t i)
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
Methods for managing connections.
void MHD_update_last_activity_(struct MHD_Connection *connection)
@ MHD_REQUEST_TERMINATED_WITH_ERROR
Definition: microhttpd.h:1831
#define MHD_ERR_AGAIN_
Definition: internal.h:1863
#define MHD_ERR_NOTCONN_
Definition: internal.h:1874
#define _(String)
Definition: mhd_options.h:42
internal shared structures
@ MHD_TLS_CONN_WR_CLOSING
Definition: internal.h:548
@ MHD_TLS_CONN_WR_CLOSED
Definition: internal.h:549
@ MHD_TLS_CONN_INIT
Definition: internal.h:545
@ MHD_TLS_CONN_TLS_FAILED
Definition: internal.h:552
@ MHD_TLS_CONN_CONNECTED
Definition: internal.h:547
@ MHD_TLS_CONN_HANDSHAKING
Definition: internal.h:546
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
#define SSIZE_MAX
Definition: mhd_limits.h:111
internal monotonic clock functions implementations
Methods for managing response objects.
bool tls_read_ready
Definition: internal.h:769
ReceiveCallback recv_cls
Definition: internal.h:706
struct MHD_Daemon * daemon
Definition: internal.h:675