]>
Commit | Line | Data |
---|---|---|
34374067 MT |
1 | diff -Naur Pound-2.6.orig/config.c Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c |
2 | --- Pound-2.6.orig/config.c 2011-12-28 14:57:45.000000000 +0100 | |
3 | +++ Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c 2012-02-15 21:49:39.000000000 +0100 | |
4 | @@ -31,6 +31,8 @@ | |
5 | ||
6 | #include "pound.h" | |
7 | ||
8 | +#include <openssl/x509v3.h> | |
9 | + | |
10 | #ifdef MISS_FACILITYNAMES | |
11 | ||
12 | /* This is lifted verbatim from the Linux sys/syslog.h */ | |
13 | @@ -76,7 +78,7 @@ | |
14 | static regex_t Err414, Err500, Err501, Err503, MaxRequest, HeadRemove, RewriteLocation, RewriteDestination; | |
15 | static regex_t Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr; | |
16 | static regex_t Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale; | |
17 | -static regex_t ClientCert, AddHeader, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11; | |
18 | +static regex_t ClientCert, AddHeader, DisableSSLv2, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11; | |
19 | static regex_t Grace, Include, ConnTO, IgnoreCase, HTTPS, HTTPSCert, Disabled, Threads, CNName; | |
20 | ||
21 | static regmatch_t matches[5]; | |
22 | @@ -167,6 +169,53 @@ | |
23 | } | |
24 | } | |
25 | ||
26 | +unsigned char ** | |
27 | +get_subjectaltnames(X509 *x509, unsigned int *count) | |
28 | +{ | |
29 | + *count = 0; | |
30 | + unsigned int local_count = 0; | |
31 | + unsigned char **result = NULL; | |
32 | + | |
33 | + STACK_OF(GENERAL_NAME) *san_stack = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL); | |
34 | + | |
35 | + unsigned char *temp[sk_GENERAL_NAME_num(san_stack)]; | |
36 | + | |
37 | + GENERAL_NAME *name = NULL; | |
38 | + while(sk_GENERAL_NAME_num(san_stack) > 0) | |
39 | + { | |
40 | + name = sk_GENERAL_NAME_pop(san_stack); | |
41 | + | |
42 | + switch(name->type) | |
43 | + { | |
44 | + case GEN_DNS: | |
45 | + temp[local_count] = strndup(ASN1_STRING_data(name->d.dNSName), ASN1_STRING_length(name->d.dNSName)+1); | |
46 | + if(temp[local_count] == NULL) { conf_err("out of memory"); } | |
47 | + local_count++; | |
48 | + break; | |
49 | + default: | |
50 | + logmsg(LOG_INFO, "unsupported subjectAltName type encountered: %i", name->type); | |
51 | + } | |
52 | + | |
53 | + GENERAL_NAME_free(name); | |
54 | + } | |
55 | + | |
56 | + result = (unsigned char**)malloc(sizeof(unsigned char*)*local_count); | |
57 | + if(result == NULL) { conf_err("out of memory"); } | |
58 | + int i; | |
59 | + for(i = 0;i < local_count; i++) | |
60 | + { | |
61 | + result[i] = strndup(temp[i], strlen(temp[i])+1); | |
62 | + if(result[i] == NULL) { conf_err("out of memory"); } | |
63 | + | |
64 | + free(temp[i]); | |
65 | + } | |
66 | + *count = local_count; | |
67 | + | |
68 | + sk_GENERAL_NAME_pop_free(san_stack, GENERAL_NAME_free); | |
69 | + | |
70 | + return result; | |
71 | +} | |
72 | + | |
73 | /* | |
74 | * parse a back-end | |
75 | */ | |
76 | @@ -289,9 +338,12 @@ | |
77 | } else if(!regexec(&HTTPS, lin, 4, matches, 0)) { | |
78 | if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) | |
79 | conf_err("SSL_CTX_new failed - aborted"); | |
80 | + SSL_CTX_set_app_data(res->ctx, res); | |
81 | SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL); | |
82 | SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY); | |
83 | SSL_CTX_set_options(res->ctx, SSL_OP_ALL); | |
84 | + SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); | |
85 | + SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT); | |
86 | sprintf(lin, "%d-Pound-%ld", getpid(), random()); | |
87 | SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin)); | |
88 | SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback); | |
89 | @@ -299,6 +351,7 @@ | |
90 | } else if(!regexec(&HTTPSCert, lin, 4, matches, 0)) { | |
91 | if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) | |
92 | conf_err("SSL_CTX_new failed - aborted"); | |
93 | + SSL_CTX_set_app_data(res->ctx, res); | |
94 | lin[matches[1].rm_eo] = '\0'; | |
95 | if(SSL_CTX_use_certificate_chain_file(res->ctx, lin + matches[1].rm_so) != 1) | |
96 | conf_err("SSL_CTX_use_certificate_chain_file failed - aborted"); | |
97 | @@ -309,6 +362,8 @@ | |
98 | SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL); | |
99 | SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY); | |
100 | SSL_CTX_set_options(res->ctx, SSL_OP_ALL); | |
101 | + SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); | |
102 | + SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT); | |
103 | sprintf(lin, "%d-Pound-%ld", getpid(), random()); | |
104 | SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin)); | |
105 | SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback); | |
106 | @@ -805,13 +860,23 @@ | |
107 | /* logmsg(LOG_DEBUG, "Received SSL SNI Header for servername %s", servername); */ | |
108 | ||
109 | SSL_set_SSL_CTX(ssl, NULL); | |
110 | - for(pc = ctx; pc; pc = pc->next) | |
111 | + for(pc = ctx; pc; pc = pc->next) { | |
112 | if(fnmatch(pc->server_name, server_name, 0) == 0) { | |
113 | /* logmsg(LOG_DEBUG, "Found cert for %s", servername); */ | |
114 | SSL_set_SSL_CTX(ssl, pc->ctx); | |
115 | return SSL_TLSEXT_ERR_OK; | |
116 | } | |
117 | - | |
118 | + else if(pc->subjectAltNameCount > 0 && pc->subjectAltNames != NULL) { | |
119 | + int i; | |
120 | + for(i = 0; i < pc->subjectAltNameCount; i++) { | |
121 | + if(fnmatch(pc->subjectAltNames[i], server_name, 0) == 0) { | |
122 | + SSL_set_SSL_CTX(ssl, pc->ctx); | |
123 | + return SSL_TLSEXT_ERR_OK; | |
124 | + } | |
125 | + } | |
126 | + } | |
127 | + } | |
128 | + | |
129 | /* logmsg(LOG_DEBUG, "No match for %s, default used", server_name); */ | |
130 | SSL_set_SSL_CTX(ssl, ctx->ctx); | |
131 | return SSL_TLSEXT_ERR_OK; | |
132 | @@ -829,11 +894,15 @@ | |
133 | SERVICE *svc; | |
134 | MATCHER *m; | |
135 | int has_addr, has_port, has_other; | |
136 | + long ssl_op_enable, ssl_op_disable; | |
137 | struct hostent *host; | |
138 | struct sockaddr_in in; | |
139 | struct sockaddr_in6 in6; | |
140 | POUND_CTX *pc; | |
141 | ||
142 | + ssl_op_enable = SSL_OP_ALL; | |
143 | + ssl_op_disable = SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL_OP_LEGACY_SERVER_CONNECT; | |
144 | + | |
145 | if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL) | |
146 | conf_err("ListenHTTPS config: out of memory - aborted"); | |
147 | memset(res, 0, sizeof(LISTENER)); | |
148 | @@ -844,6 +913,8 @@ | |
149 | res->err500 = "An internal server error occurred. Please try again later."; | |
150 | res->err501 = "This method may not be used."; | |
151 | res->err503 = "The service is not available. Please try again later."; | |
152 | + res->allow_client_reneg = 0; | |
153 | + res->disable_ssl_v2 = 0; | |
154 | res->log_level = log_level; | |
155 | if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED)) | |
156 | conf_err("xHTTP bad default pattern - aborted"); | |
157 | @@ -959,6 +1030,9 @@ | |
158 | fclose(fcert); | |
159 | memset(server_name, '\0', MAXBUF); | |
160 | X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1); | |
161 | + pc->subjectAltNameCount = 0; | |
162 | + pc->subjectAltNames = NULL; | |
163 | + pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount)); | |
164 | X509_free(x509); | |
165 | if(!regexec(&CNName, server_name, 4, matches, 0)) { | |
166 | server_name[matches[1].rm_eo] = '\0'; | |
167 | @@ -1029,6 +1103,25 @@ | |
168 | strcat(res->add_head, "\r\n"); | |
169 | strcat(res->add_head, lin + matches[1].rm_so); | |
170 | } | |
171 | + } else if(!regexec(&DisableSSLv2, lin, 4, matches, 0)) { | |
172 | + res->disable_ssl_v2 = 1; | |
173 | + } else if(!regexec(&SSLAllowClientRenegotiation, lin, 4, matches, 0)) { | |
174 | + res->allow_client_reneg = atoi(lin + matches[1].rm_so); | |
175 | + if (res->allow_client_reneg == 2) { | |
176 | + ssl_op_enable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; | |
177 | + ssl_op_disable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; | |
178 | + } else { | |
179 | + ssl_op_disable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; | |
180 | + ssl_op_enable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; | |
181 | + } | |
182 | + } else if(!regexec(&SSLHonorCipherOrder, lin, 4, matches, 0)) { | |
183 | + if (atoi(lin + matches[1].rm_so)) { | |
184 | + ssl_op_enable |= SSL_OP_CIPHER_SERVER_PREFERENCE; | |
185 | + ssl_op_disable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE; | |
186 | + } else { | |
187 | + ssl_op_disable |= SSL_OP_CIPHER_SERVER_PREFERENCE; | |
188 | + ssl_op_enable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE; | |
189 | + } | |
190 | } else if(!regexec(&Ciphers, lin, 4, matches, 0)) { | |
191 | has_other = 1; | |
192 | if(res->ctx == NULL) | |
193 | @@ -1105,12 +1198,19 @@ | |
194 | conf_err("ListenHTTPS: can't set SNI callback"); | |
195 | #endif | |
196 | for(pc = res->ctx; pc; pc = pc->next) { | |
197 | + SSL_CTX_set_app_data(pc->ctx, res); | |
198 | SSL_CTX_set_mode(pc->ctx, SSL_MODE_AUTO_RETRY); | |
199 | - SSL_CTX_set_options(pc->ctx, SSL_OP_ALL); | |
200 | + SSL_CTX_set_options(pc->ctx, ssl_op_enable); | |
201 | + SSL_CTX_clear_options(pc->ctx, ssl_op_disable); | |
202 | + if (res->disable_ssl_v2 == 1) | |
203 | + { | |
204 | + SSL_CTX_set_options(pc->ctx, SSL_OP_NO_SSLv2); | |
205 | + } | |
206 | sprintf(lin, "%d-Pound-%ld", getpid(), random()); | |
207 | SSL_CTX_set_session_id_context(pc->ctx, (unsigned char *)lin, strlen(lin)); | |
208 | SSL_CTX_set_tmp_rsa_callback(pc->ctx, RSA_tmp_callback); | |
209 | SSL_CTX_set_tmp_dh_callback(pc->ctx, DH_tmp_callback); | |
210 | + SSL_CTX_set_info_callback(pc->ctx, SSLINFO_callback); | |
211 | } | |
212 | return res; | |
213 | } else { | |
214 | @@ -1305,6 +1405,9 @@ | |
215 | || regcomp(&DynScale, "^[ \t]*DynScale[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
216 | || regcomp(&ClientCert, "^[ \t]*ClientCert[ \t]+([0-3])[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
217 | || regcomp(&AddHeader, "^[ \t]*AddHeader[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
218 | + || regcomp(&SSLAllowClientRenegotiation, "^[ \t]*SSLAllowClientRenegotiation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
219 | + || regcomp(&DisableSSLv2, "^[ \t]*DisableSSLv2[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
220 | + || regcomp(&SSLHonorCipherOrder, "^[ \t]*SSLHonorCipherOrder[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
221 | || regcomp(&Ciphers, "^[ \t]*Ciphers[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
222 | || regcomp(&CAlist, "^[ \t]*CAlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
223 | || regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) | |
224 | @@ -1463,6 +1566,9 @@ | |
225 | regfree(&DynScale); | |
226 | regfree(&ClientCert); | |
227 | regfree(&AddHeader); | |
228 | + regfree(&SSLAllowClientRenegotiation); | |
229 | + regfree(&DisableSSLv2); | |
230 | + regfree(&SSLHonorCipherOrder); | |
231 | regfree(&Ciphers); | |
232 | regfree(&CAlist); | |
233 | regfree(&VerifyList); | |
234 | diff -Naur Pound-2.6.orig/http.c Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c | |
235 | --- Pound-2.6.orig/http.c 2011-12-28 14:57:45.000000000 +0100 | |
236 | +++ Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c 2012-02-15 21:44:46.000000000 +0100 | |
237 | @@ -246,6 +246,11 @@ | |
238 | ||
239 | static int err_to = -1; | |
240 | ||
241 | +typedef struct { | |
242 | + int timeout; | |
243 | + RENEG_STATE *reneg_state; | |
244 | +} BIO_ARG; | |
245 | + | |
246 | /* | |
247 | * Time-out for client read/gets | |
248 | * the SSL manual says not to do it, but it works well enough anyway... | |
249 | @@ -253,18 +258,32 @@ | |
250 | static long | |
251 | bio_callback(BIO *const bio, const int cmd, const char *argp, int argi, long argl, long ret) | |
252 | { | |
253 | + BIO_ARG *bio_arg; | |
254 | struct pollfd p; | |
255 | int to, p_res, p_err; | |
256 | ||
257 | if(cmd != BIO_CB_READ && cmd != BIO_CB_WRITE) | |
258 | return ret; | |
259 | ||
260 | + //logmsg(LOG_NOTICE, "bio callback"); | |
261 | /* a time-out already occured */ | |
262 | - if((to = *((int *)BIO_get_callback_arg(bio)) * 1000) < 0) { | |
263 | + if((bio_arg = (BIO_ARG*)BIO_get_callback_arg(bio))==NULL) return ret; | |
264 | + if((to = bio_arg->timeout * 1000) < 0) { | |
265 | errno = ETIMEDOUT; | |
266 | return -1; | |
267 | } | |
268 | ||
269 | + /* Renegotiations */ | |
270 | + //logmsg(LOG_NOTICE, "RENEG STATE %d", bio_arg->reneg_state==NULL?-1:*bio_arg->reneg_state); | |
271 | + if (bio_arg->reneg_state != NULL && *bio_arg->reneg_state == RENEG_ABORT) { | |
272 | + logmsg(LOG_NOTICE, "REJECTING renegotiated session"); | |
273 | + errno = ECONNABORTED; | |
274 | + return -1; | |
275 | + } | |
276 | + | |
277 | + //logmsg(LOG_NOTICE, "TO %d", to); | |
278 | + if (to == 0) return ret; | |
279 | + | |
280 | for(;;) { | |
281 | memset(&p, 0, sizeof(p)); | |
282 | BIO_get_fd(bio, &p.fd); | |
283 | @@ -299,7 +318,7 @@ | |
284 | return -1; | |
285 | case 0: | |
286 | /* timeout - mark the BIO as unusable for the future */ | |
287 | - BIO_set_callback_arg(bio, (char *)&err_to); | |
288 | + bio_arg->timeout = err_to; | |
289 | #ifdef EBUG | |
290 | logmsg(LOG_WARNING, "(%lx) CALLBACK timeout poll after %d secs: %s", | |
291 | pthread_self(), to / 1000, strerror(p_err)); | |
292 | @@ -503,7 +522,14 @@ | |
293 | regmatch_t matches[4]; | |
294 | struct linger l; | |
295 | double start_req, end_req; | |
296 | + RENEG_STATE reneg_state; | |
297 | + BIO_ARG ba1, ba2; | |
298 | ||
299 | + reneg_state = RENEG_INIT; | |
300 | + ba1.reneg_state = &reneg_state; | |
301 | + ba2.reneg_state = &reneg_state; | |
302 | + ba1.timeout = 0; | |
303 | + ba2.timeout = 0; | |
304 | from_host = ((thr_arg *)arg)->from_host; | |
305 | memcpy(&from_host_addr, from_host.ai_addr, from_host.ai_addrlen); | |
306 | from_host.ai_addr = (struct sockaddr *)&from_host_addr; | |
307 | @@ -512,6 +538,8 @@ | |
308 | free(((thr_arg *)arg)->from_host.ai_addr); | |
309 | free(arg); | |
310 | ||
311 | + if(lstn->allow_client_reneg) reneg_state = RENEG_ALLOW; | |
312 | + | |
313 | n = 1; | |
314 | setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&n, sizeof(n)); | |
315 | l.l_onoff = 1; | |
316 | @@ -535,10 +563,11 @@ | |
317 | close(sock); | |
318 | return; | |
319 | } | |
320 | - if(lstn->to > 0) { | |
321 | - BIO_set_callback_arg(cl, (char *)&lstn->to); | |
322 | + //if(lstn->to > 0) { | |
323 | + ba1.timeout = lstn->to; | |
324 | + BIO_set_callback_arg(cl, (char *)&ba1); | |
325 | BIO_set_callback(cl, bio_callback); | |
326 | - } | |
327 | + //} | |
328 | ||
329 | if(lstn->ctx != NULL) { | |
330 | if((ssl = SSL_new(lstn->ctx->ctx)) == NULL) { | |
331 | @@ -547,6 +576,7 @@ | |
332 | BIO_free_all(cl); | |
333 | return; | |
334 | } | |
335 | + SSL_set_app_data(ssl, &reneg_state); | |
336 | SSL_set_bio(ssl, cl, cl); | |
337 | if((bb = BIO_new(BIO_f_ssl())) == NULL) { | |
338 | logmsg(LOG_WARNING, "(%lx) BIO_new(Bio_f_ssl()) failed", pthread_self()); | |
339 | @@ -848,7 +878,8 @@ | |
340 | } | |
341 | BIO_set_close(be, BIO_CLOSE); | |
342 | if(backend->to > 0) { | |
343 | - BIO_set_callback_arg(be, (char *)&backend->to); | |
344 | + ba2.timeout = backend->to; | |
345 | + BIO_set_callback_arg(be, (char *)&ba2); | |
346 | BIO_set_callback(be, bio_callback); | |
347 | } | |
348 | if(backend->ctx != NULL) { | |
349 | diff -Naur Pound-2.6.orig/pound.8 Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8 | |
350 | --- Pound-2.6.orig/pound.8 2011-12-28 14:57:45.000000000 +0100 | |
351 | +++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8 2012-02-15 21:44:46.000000000 +0100 | |
352 | @@ -501,6 +501,19 @@ | |
353 | and | |
354 | .I SSL_CTX_set_cipher_list(3). | |
355 | .TP | |
356 | +\fBSSLHonorCipherOrder\fR 0|1 | |
357 | +If this value is 1, the server will broadcast a preference to use \fBCiphers\fR in the | |
358 | +order supplied in the \fBCiphers\fR directive. If the value is 0, the server will treat | |
359 | +the Ciphers list as the list of Ciphers it will accept, but no preference will be | |
360 | +indicated. Default value is 0. | |
361 | +.TP | |
362 | +\fBSSLAllowClientRenegotiation\fR 0|1|2 | |
363 | +If this value is 0, client initiated renegotiation will be disabled. This will mitigate | |
364 | +DoS exploits based on client renegotiation, regardless of the patch status of clients and | |
365 | +servers related to "Secure renegotiation". If the value is 1, secure renegotiation is | |
366 | +supported. If the value is 2, insecure renegotiation is supported, with unpatched | |
367 | +clients. /fBThis can lead to a DoS and a Man in the Middle attack!/fR Default value is 0. | |
368 | +.TP | |
369 | \fBCAlist\fR "CAcert_file" | |
370 | Set the list of "trusted" CA's for this server. The CAcert_file is a file containing | |
371 | a sequence of CA certificates (PEM format). The names of the defined CA certificates | |
372 | diff -Naur Pound-2.6.orig/pound.h Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h | |
373 | --- Pound-2.6.orig/pound.h 2011-12-28 14:57:45.000000000 +0100 | |
374 | +++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h 2012-02-15 21:49:39.000000000 +0100 | |
375 | @@ -380,6 +380,8 @@ | |
376 | SSL_CTX *ctx; | |
377 | char *server_name; | |
378 | struct _pound_ctx *next; | |
379 | + unsigned int subjectAltNameCount; | |
380 | + unsigned char **subjectAltNames; | |
381 | } POUND_CTX; | |
382 | ||
383 | /* Listener definition */ | |
384 | @@ -404,6 +406,8 @@ | |
385 | int rewr_dest; /* rewrite destination header */ | |
386 | int disabled; /* true if the listener is disabled */ | |
387 | int log_level; /* log level for this listener */ | |
388 | + int allow_client_reneg; /* Allow Client SSL Renegotiation */ | |
389 | + int disable_ssl_v2; /* Disable SSL version 2 */ | |
390 | SERVICE *services; | |
391 | struct _listener *next; | |
392 | } LISTENER; | |
393 | @@ -419,6 +423,9 @@ | |
394 | struct _thr_arg *next; | |
395 | } thr_arg; /* argument to processing threads: socket, origin */ | |
396 | ||
397 | +/* Track SSL handshare/renegotiation so we can reject client-renegotiations. */ | |
398 | +typedef enum { RENEG_INIT=0, RENEG_REJECT, RENEG_ALLOW, RENEG_ABORT } RENEG_STATE; | |
399 | + | |
400 | /* Header types */ | |
401 | #define HEADER_ILLEGAL -1 | |
402 | #define HEADER_OTHER 0 | |
403 | @@ -591,6 +598,11 @@ | |
404 | extern DH *DH_tmp_callback(SSL *, int, int); | |
405 | ||
406 | /* | |
407 | + * Renegotiation callback | |
408 | + */ | |
409 | +extern void SSLINFO_callback(const SSL *s, int where, int rc); | |
410 | + | |
411 | +/* | |
412 | * expiration stuff | |
413 | */ | |
414 | #ifndef EXPIRE_TO | |
415 | diff -Naur Pound-2.6.orig/svc.c Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c | |
416 | --- Pound-2.6.orig/svc.c 2011-12-28 14:57:45.000000000 +0100 | |
417 | +++ Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c 2012-02-15 21:44:46.000000000 +0100 | |
418 | @@ -1797,3 +1797,34 @@ | |
419 | close(ctl); | |
420 | } | |
421 | } | |
422 | + | |
423 | +void | |
424 | +SSLINFO_callback(const SSL *ssl, int where, int rc) | |
425 | +{ | |
426 | + RENEG_STATE *reneg_state; | |
427 | + | |
428 | + /* Get our thr_arg where we're tracking this connection info */ | |
429 | + if ((reneg_state = (RENEG_STATE *)SSL_get_app_data(ssl)) == NULL) return; | |
430 | + | |
431 | + /* If we're rejecting renegotiations, move to ABORT if Client Hello is being read. */ | |
432 | + if ((where & SSL_CB_ACCEPT_LOOP) && *reneg_state == RENEG_REJECT) { | |
433 | + int state = SSL_get_state(ssl); | |
434 | + | |
435 | + if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) { | |
436 | + *reneg_state = RENEG_ABORT; | |
437 | + logmsg(LOG_WARNING,"rejecting client initiated renegotiation"); | |
438 | + } | |
439 | + } | |
440 | + else if (where & SSL_CB_HANDSHAKE_DONE && *reneg_state == RENEG_INIT) { | |
441 | + // Reject any followup renegotiations | |
442 | + *reneg_state = RENEG_REJECT; | |
443 | + } | |
444 | + | |
445 | + //if (where & SSL_CB_HANDSHAKE_START) logmsg(LOG_DEBUG, "handshake start"); | |
446 | + //else if (where & SSL_CB_HANDSHAKE_DONE) logmsg(LOG_DEBUG, "handshake done"); | |
447 | + //else if (where & SSL_CB_LOOP) logmsg(LOG_DEBUG, "loop"); | |
448 | + //else if (where & SSL_CB_READ) logmsg(LOG_DEBUG, "read"); | |
449 | + //else if (where & SSL_CB_WRITE) logmsg(LOG_DEBUG, "write"); | |
450 | + //else if (where & SSL_CB_ALERT) logmsg(LOG_DEBUG, "alert"); | |
451 | +} | |
452 | + |