1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
/**
* Copyright 2004-2005 Paul Querna
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_connection.h"
#include "http_request.h"
#include "http_core.h"
#include "http_log.h"
#include "apr_buckets.h"
#include "apr_strings.h"
#include "apr_tables.h"
#include "ap_release.h"
#include <gcrypt.h>
#include <gnutls/gnutls.h>
#include <gnutls/extra.h>
#include <gnutls/openpgp.h>
#include <gnutls/x509.h>
#ifndef __mod_gnutls_h_inc
#define __mod_gnutls_h_inc
#define HAVE_APR_MEMCACHE @have_apr_memcache@
extern module AP_MODULE_DECLARE_DATA gnutls_module;
#define GNUTLS_OUTPUT_FILTER_NAME "gnutls_output_filter"
#define GNUTLS_INPUT_FILTER_NAME "gnutls_input_filter"
#define GNUTLS_ENABLED_FALSE 0
#define GNUTLS_ENABLED_TRUE 1
#define MOD_GNUTLS_VERSION "@MOD_GNUTLS_VERSION@"
#define MOD_GNUTLS_DEBUG @OOO_MAINTAIN@
/* Recent Versions of 2.1 renamed several hooks. This allows us to
compile on 2.0.xx */
#if AP_SERVER_MINORVERSION_NUMBER >= 1
#if AP_SERVER_PATCHLEVEL_NUMBER >= 3
#define USING_2_1_RECENT 1
#endif
#endif
#ifndef USING_2_1_RECENT
#define USING_2_1_RECENT 0
#endif
typedef enum
{
mgs_cache_none,
mgs_cache_dbm,
#if HAVE_APR_MEMCACHE
mgs_cache_memcache
#endif
} mgs_cache_e;
typedef struct
{
int client_verify_mode;
const char* lua_bytecode;
apr_size_t lua_bytecode_len;
} mgs_dirconf_rec;
/* The maximum number of client CA certificates allowed.
*/
#define MAX_CA_CRTS 128
/* The maximum number of certificates to send in a chain
*/
#define MAX_CHAIN_SIZE 8
typedef struct
{
gnutls_certificate_credentials_t certs;
gnutls_srp_server_credentials_t srp_creds;
gnutls_anon_server_credentials_t anon_creds;
char* cert_cn;
gnutls_x509_crt_t certs_x509[MAX_CHAIN_SIZE]; /* A certificate chain */
unsigned int certs_x509_num;
gnutls_x509_privkey_t privkey_x509;
gnutls_openpgp_crt_t cert_pgp; /* A certificate chain */
gnutls_openpgp_privkey_t privkey_pgp;
int enabled;
/* whether to send the PEM encoded certificates
* to CGIs
*/
int export_certificates_enabled;
gnutls_priority_t priorities;
gnutls_rsa_params_t rsa_params;
gnutls_dh_params_t dh_params;
int cache_timeout;
mgs_cache_e cache_type;
const char* cache_config;
const char* srp_tpasswd_file;
const char* srp_tpasswd_conf_file;
gnutls_x509_crt_t ca_list[MAX_CA_CRTS];
gnutls_openpgp_keyring_t pgp_list;
unsigned int ca_list_size;
int client_verify_mode;
} mgs_srvconf_rec;
typedef struct {
int length;
char *value;
} mgs_char_buffer_t;
typedef struct
{
mgs_srvconf_rec *sc;
conn_rec* c;
gnutls_session_t session;
apr_status_t input_rc;
ap_filter_t *input_filter;
apr_bucket_brigade *input_bb;
apr_read_type_e input_block;
ap_input_mode_t input_mode;
mgs_char_buffer_t input_cbuf;
char input_buffer[AP_IOBUFSIZE];
apr_status_t output_rc;
ap_filter_t *output_filter;
apr_bucket_brigade *output_bb;
char output_buffer[AP_IOBUFSIZE];
apr_size_t output_blen;
apr_size_t output_length;
int status;
int non_https;
} mgs_handle_t;
/** Functions in gnutls_io.c **/
/**
* mgs_filter_input will filter the input data
* by decrypting it using GnuTLS and passes it cleartext.
*
* @param f the filter info record
* @param bb the bucket brigade, where to store the result to
* @param mode what shall we read?
* @param block a block index we shall read from?
* @return result status
*/
apr_status_t mgs_filter_input(ap_filter_t * f,
apr_bucket_brigade * bb,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t readbytes);
/**
* mgs_filter_output will filter the encrypt
* the incoming bucket using GnuTLS and passes it onto the next filter.
*
* @param f the filter info record
* @param bb the bucket brigade, where to store the result to
* @return result status
*/
apr_status_t mgs_filter_output(ap_filter_t * f,
apr_bucket_brigade * bb);
/**
* mgs_transport_read is called from GnuTLS to provide encrypted
* data from the client.
*
* @param ptr pointer to the filter context
* @param buffer place to put data
* @param len maximum size
* @return size length of the data stored in buffer
*/
ssize_t mgs_transport_read(gnutls_transport_ptr_t ptr,
void *buffer, size_t len);
/**
* mgs_transport_write is called from GnuTLS to
* write data to the client.
*
* @param ptr pointer to the filter context
* @param buffer buffer to write to the client
* @param len size of the buffer
* @return size length of the data written
*/
ssize_t mgs_transport_write(gnutls_transport_ptr_t ptr,
const void *buffer, size_t len);
int mgs_rehandshake(mgs_handle_t * ctxt);
/**
* Init the Cache after Configuration is done
*/
int mgs_cache_post_config(apr_pool_t *p, server_rec *s,
mgs_srvconf_rec *sc);
/**
* Init the Cache inside each Process
*/
int mgs_cache_child_init(apr_pool_t *p, server_rec *s,
mgs_srvconf_rec *sc);
/**
* Setup the Session Caching
*/
int mgs_cache_session_init(mgs_handle_t *ctxt);
#define GNUTLS_SESSION_ID_STRING_LEN \
((GNUTLS_MAX_SESSION_ID + 1) * 2)
/**
* Convert a SSL Session ID into a Null Terminated Hex Encoded String
* @param id raw SSL Session ID
* @param idlen Length of the raw Session ID
* @param str Location to store the Hex Encoded String
* @param strsize The Maximum Length that can be stored in str
*/
char *mgs_session_id2sz(unsigned char *id, int idlen,
char *str, int strsize);
/**
* Convert a time_t into a Null Terminated String
* @param t time_t time
* @param str Location to store the Hex Encoded String
* @param strsize The Maximum Length that can be stored in str
*/
char *mgs_time2sz(time_t t, char *str, int strsize);
/* Configuration Functions */
const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_cache(cmd_parms * parms, void *dummy,
const char *type, const char* arg);
const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_priorities(cmd_parms * parms, void *dummy,
const char *arg);
const char *mgs_set_require_section(cmd_parms *cmd,
void *mconfig, const char *arg);
void *mgs_config_server_create(apr_pool_t * p, server_rec * s);
void *mgs_config_dir_merge(apr_pool_t *p, void *basev, void *addv);
void *mgs_config_dir_create(apr_pool_t *p, char *dir);
const char *mgs_set_require_bytecode(cmd_parms *cmd,
void *mconfig, const char *arg);
mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session);
/* mod_gnutls Hooks. */
int mgs_hook_pre_config(apr_pool_t * pconf,
apr_pool_t * plog, apr_pool_t * ptemp);
int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
apr_pool_t * ptemp,
server_rec * base_server);
void mgs_hook_child_init(apr_pool_t *p, server_rec *s);
const char *mgs_hook_http_scheme(const request_rec * r);
apr_port_t mgs_hook_default_port(const request_rec * r);
int mgs_hook_pre_connection(conn_rec * c, void *csd);
int mgs_hook_fixups(request_rec *r);
int mgs_hook_authz(request_rec *r);
int mgs_authz_lua(request_rec* r);
#endif /* __mod_gnutls_h_inc */
|