GNU libmicrohttpd
1.0.6
Toggle main menu visibility
Loading...
Searching...
No Matches
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
Copyright (C) 2015-2022 Karlson2k (Evgeny Grin)
5
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2.1 of the License, or (at your option) any later version.
10
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
15
16
You should have received a copy of the GNU Lesser General Public
17
License along with this library; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20
*/
21
30
31
#include "
internal.h
"
32
#include "
connection.h
"
33
#include "
connection_https.h
"
34
#include "
memorypool.h
"
35
#include "
response.h
"
36
#include "
mhd_mono_clock.h
"
37
#include <gnutls/gnutls.h>
38
#include "
mhd_send.h
"
39
40
50
static
ssize_t
51
recv_tls_adapter
(
struct
MHD_Connection
*connection,
52
void
*other,
53
size_t
i)
54
{
55
ssize_t res;
56
57
if
(i >
SSIZE_MAX
)
58
i =
SSIZE_MAX
;
59
60
res = gnutls_record_recv (connection->tls_session,
61
other,
62
i);
63
if
( (GNUTLS_E_AGAIN == res) ||
64
(GNUTLS_E_INTERRUPTED == res) )
65
{
66
#ifdef EPOLL_SUPPORT
67
if
(GNUTLS_E_AGAIN == res)
68
connection->epoll_state &=
69
~((
enum
MHD_EpollState
)
MHD_EPOLL_STATE_READ_READY
);
70
#endif
71
/* Any network errors means that buffer is empty. */
72
connection->tls_read_ready =
false
;
73
return
MHD_ERR_AGAIN_
;
74
}
75
if
(res < 0)
76
{
77
connection->tls_read_ready =
false
;
78
if
( (GNUTLS_E_DECRYPTION_FAILED == res) ||
79
(GNUTLS_E_INVALID_SESSION == res) ||
80
(GNUTLS_E_DECOMPRESSION_FAILED == res) ||
81
(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER == res) ||
82
(GNUTLS_E_UNSUPPORTED_VERSION_PACKET == res) ||
83
(GNUTLS_E_UNEXPECTED_PACKET_LENGTH == res) ||
84
(GNUTLS_E_UNEXPECTED_PACKET == res) ||
85
(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET == res) ||
86
(GNUTLS_E_EXPIRED == res) ||
87
(GNUTLS_E_REHANDSHAKE == res) )
88
return
MHD_ERR_TLS_
;
89
if
( (GNUTLS_E_PULL_ERROR == res) ||
90
(GNUTLS_E_INTERNAL_ERROR == res) ||
91
(GNUTLS_E_CRYPTODEV_IOCTL_ERROR == res) ||
92
(GNUTLS_E_CRYPTODEV_DEVICE_ERROR == res) )
93
return
MHD_ERR_PIPE_
;
94
#if defined(GNUTLS_E_PREMATURE_TERMINATION)
95
if
(GNUTLS_E_PREMATURE_TERMINATION == res)
96
return
MHD_ERR_CONNRESET_
;
97
#elif defined(GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
98
if
(GNUTLS_E_UNEXPECTED_PACKET_LENGTH == res)
99
return
MHD_ERR_CONNRESET_
;
100
#endif
/* GNUTLS_E_UNEXPECTED_PACKET_LENGTH */
101
if
(GNUTLS_E_MEMORY_ERROR == res)
102
return
MHD_ERR_NOMEM_
;
103
/* Treat any other error as a hard error. */
104
return
MHD_ERR_NOTCONN_
;
105
}
106
107
#ifdef EPOLL_SUPPORT
108
/* Unlike non-TLS connections, do not reset "read-ready" if
109
* received amount smaller than provided amount, as TLS
110
* connections may receive data by fixed-size chunks. */
111
#endif
/* EPOLL_SUPPORT */
112
113
/* Check whether TLS buffers still have some unread data. */
114
connection->tls_read_ready =
115
( ((size_t) res == i) &&
116
(0 != gnutls_record_check_pending (connection->tls_session)) );
117
return
res;
118
}
119
120
130
bool
131
MHD_run_tls_handshake_
(
struct
MHD_Connection
*connection)
132
{
133
int
ret;
134
135
if
((
MHD_TLS_CONN_INIT
== connection->tls_state) ||
136
(
MHD_TLS_CONN_HANDSHAKING
== connection->tls_state))
137
{
138
#if 0
139
/* According to real-live testing, Nagel's Algorithm is not blocking
140
* partial packets on just connected sockets on modern OSes. As TLS setup
141
* is performed as the fist action upon socket connection, the next
142
* optimisation typically is not required. If any specific OS will
143
* require this optimization, it could be enabled by allowing the next
144
* lines for this specific OS. */
145
if
(
_MHD_ON
!= connection->
sk_nodelay
)
146
MHD_connection_set_nodelay_state_
(connection,
true
);
147
#endif
148
ret = gnutls_handshake (connection->tls_session);
149
if
(ret == GNUTLS_E_SUCCESS)
150
{
151
/* set connection TLS state to enable HTTP processing */
152
connection->tls_state =
MHD_TLS_CONN_CONNECTED
;
153
MHD_update_last_activity_
(connection);
154
return
true
;
155
}
156
if
( (GNUTLS_E_AGAIN == ret) ||
157
(GNUTLS_E_INTERRUPTED == ret) )
158
{
159
connection->tls_state =
MHD_TLS_CONN_HANDSHAKING
;
160
/* handshake not done */
161
return
false
;
162
}
163
/* handshake failed */
164
connection->tls_state =
MHD_TLS_CONN_TLS_FAILED
;
165
#ifdef HAVE_MESSAGES
166
MHD_DLOG (connection->
daemon
,
167
_
(
"Error: received handshake message out of context.\n"
));
168
#endif
169
MHD_connection_close_
(connection,
170
MHD_REQUEST_TERMINATED_WITH_ERROR
);
171
return
false
;
172
}
173
return
true
;
174
}
175
176
183
void
184
MHD_set_https_callbacks
(
struct
MHD_Connection
*connection)
185
{
186
connection->
recv_cls
= &
recv_tls_adapter
;
187
}
188
189
196
bool
197
MHD_tls_connection_shutdown
(
struct
MHD_Connection
*connection)
198
{
199
if
(
MHD_TLS_CONN_WR_CLOSED
> connection->tls_state)
200
{
201
const
int
res =
202
gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
203
if
(GNUTLS_E_SUCCESS == res)
204
{
205
connection->tls_state =
MHD_TLS_CONN_WR_CLOSED
;
206
return
true
;
207
}
208
if
((GNUTLS_E_AGAIN == res) ||
209
(GNUTLS_E_INTERRUPTED == res))
210
{
211
connection->tls_state =
MHD_TLS_CONN_WR_CLOSING
;
212
return
true
;
213
}
214
else
215
connection->tls_state =
MHD_TLS_CONN_TLS_FAILED
;
216
}
217
return
false
;
218
}
219
220
221
/* end of connection_https.c */
MHD_update_last_activity_
void MHD_update_last_activity_(struct MHD_Connection *connection)
Definition
connection.c:6691
MHD_connection_close_
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
Definition
connection.c:1332
connection.h
Methods for managing connections.
MHD_ERR_CONNRESET_
#define MHD_ERR_CONNRESET_
Definition
connection.h:42
MHD_ERR_NOMEM_
#define MHD_ERR_NOMEM_
Definition
connection.h:53
MHD_ERR_TLS_
#define MHD_ERR_TLS_
Definition
connection.h:78
MHD_ERR_AGAIN_
#define MHD_ERR_AGAIN_
Definition
connection.h:37
MHD_ERR_PIPE_
#define MHD_ERR_PIPE_
Definition
connection.h:73
MHD_ERR_NOTCONN_
#define MHD_ERR_NOTCONN_
Definition
connection.h:48
MHD_tls_connection_shutdown
bool MHD_tls_connection_shutdown(struct MHD_Connection *connection)
Definition
connection_https.c:197
MHD_set_https_callbacks
void MHD_set_https_callbacks(struct MHD_Connection *connection)
Definition
connection_https.c:184
recv_tls_adapter
static ssize_t recv_tls_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition
connection_https.c:51
MHD_run_tls_handshake_
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
Definition
connection_https.c:131
connection_https.h
Methods for managing connections.
MHD_REQUEST_TERMINATED_WITH_ERROR
@ MHD_REQUEST_TERMINATED_WITH_ERROR
Definition
microhttpd.h:2337
internal.h
MHD internal shared structures.
MHD_EpollState
MHD_EpollState
Definition
internal.h:169
MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_READ_READY
Definition
internal.h:181
MHD_TLS_CONN_WR_CLOSING
@ MHD_TLS_CONN_WR_CLOSING
Definition
internal.h:764
MHD_TLS_CONN_WR_CLOSED
@ MHD_TLS_CONN_WR_CLOSED
Definition
internal.h:765
MHD_TLS_CONN_INIT
@ MHD_TLS_CONN_INIT
Definition
internal.h:761
MHD_TLS_CONN_TLS_FAILED
@ MHD_TLS_CONN_TLS_FAILED
Definition
internal.h:768
MHD_TLS_CONN_CONNECTED
@ MHD_TLS_CONN_CONNECTED
Definition
internal.h:763
MHD_TLS_CONN_HANDSHAKING
@ MHD_TLS_CONN_HANDSHAKING
Definition
internal.h:762
_MHD_ON
@ _MHD_ON
Definition
internal.h:160
memorypool.h
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
SSIZE_MAX
#define SSIZE_MAX
Definition
mhd_limits.h:121
mhd_mono_clock.h
internal monotonic clock functions implementations
_
#define _(String)
Definition
mhd_options.h:42
MHD_connection_set_nodelay_state_
bool MHD_connection_set_nodelay_state_(struct MHD_Connection *connection, bool nodelay_state)
Definition
mhd_send.c:174
mhd_send.h
Declarations of send() wrappers.
response.h
Methods for managing response objects.
MHD_Connection
Definition
internal.h:1325
MHD_Connection::sk_nodelay
enum MHD_tristate sk_nodelay
Definition
internal.h:1515
MHD_Connection::recv_cls
ReceiveCallback recv_cls
Definition
internal.h:1581
MHD_Connection::daemon
struct MHD_Daemon * daemon
Definition
internal.h:1366
src
microhttpd
connection_https.c
Generated by
1.17.0