Project

General

Profile

Feature #1288 » lighty-clientvalidation-trunk.patch

fixing segfault, wrong patch location (see further comments) - nmaier, 2007-08-13 20:06

View differences:

src/base.h (Arbeitskopie)
298 298
	/* server wide */
299 299
	buffer *ssl_pemfile;
300 300
	buffer *ssl_ca_file;
301
	unsigned short ssl_verifyclient;
302
	unsigned short ssl_verifyclient_enforce;
303
	unsigned short ssl_verifyclient_depth;
304
	buffer *ssl_verifyclient_username;
305
	
301 306
	unsigned short use_ipv6;
302 307
	unsigned short is_ssl;
303 308
	unsigned short allow_http11;
src/network.c (Arbeitskopie)
497 497
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
498 498
				return -1;
499 499
			}
500
			if (s->ssl_verifyclient) { 
501
				STACK_OF(X509_NAME) *certs = SSL_load_client_CA_file(s->ssl_ca_file->ptr);
502
				if (!certs) {
503
					log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
504
							ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
505
				}
506
				if (SSL_CTX_set_session_id_context(s->ssl_ctx, (unsigned const char*)CONST_BUF_LEN(host_token)) != 1) { 
507
					log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
508
						ERR_error_string(ERR_get_error(), NULL)); 
509
					return -1; 
510
				}				
511
				SSL_CTX_set_client_CA_list(s->ssl_ctx, certs);
512
				SSL_CTX_set_verify(
513
					s->ssl_ctx,
514
					SSL_VERIFY_PEER | (s->ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
515
					NULL
516
				); 
517
				SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verifyclient_depth);
518
			}
519
		} else if (s->ssl_verifyclient) {
520
			log_error_write(
521
				srv, __FILE__, __LINE__, "s",
522
				"SSL: You specified ssl.verifyclient.activate but no ca_file"
523
			);
500 524
		}
501 525

  
502 526
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
src/configfile.c (Arbeitskopie)
97 97
		{ "server.max-read-threads",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 49 */
98 98
		{ "server.max-connection-idle",  NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 50 */
99 99
		{ "debug.log-timing",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 51 */
100
		
101
		{ "ssl.verifyclient.activate",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */
102
		{ "ssl.verifyclient.enforce",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 53 */
103
		{ "ssl.verifyclient.depth",      NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER }, /* 54 */
104
		{ "ssl.verifyclient.username",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 55 */
100 105

  
101 106
		{ "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
102 107
		{ "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
......
180 185
		s->global_kbytes_per_second = 0;
181 186
		s->global_bytes_per_second_cnt = 0;
182 187
		s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
188
		
189
		s->ssl_verifyclient = 0;
190
		s->ssl_verifyclient_enforce = 1;
191
		s->ssl_verifyclient_username = buffer_init();
192
		s->ssl_verifyclient_depth = 9;
183 193

  
184 194
		cv[2].destination = s->errorfile_prefix;
185 195

  
......
219 229
		cv[40].destination = &(s->range_requests);
220 230

  
221 231
		cv[50].destination = &(s->max_connection_idle);
232
		
233
		/* ssl.verify */
234
		cv[52].destination = &(s->ssl_verifyclient);
235
		cv[53].destination = &(s->ssl_verifyclient_enforce);
236
		cv[54].destination = &(s->ssl_verifyclient_depth);
237
		cv[55].destination = s->ssl_verifyclient_username;
222 238

  
223 239
		srv->config_storage[i] = s;
224 240

  
......
289 305

  
290 306
	PATCH(ssl_pemfile);
291 307
	PATCH(ssl_ca_file);
308

  
309
	PATCH(ssl_verifyclient);
310
	PATCH(ssl_verifyclient_enforce);
311
	PATCH(ssl_verifyclient_depth);
312
	PATCH(ssl_verifyclient_username);
313

  
292 314
	return 0;
293 315
}
294 316

  
......
370 392
				PATCH(global_kbytes_per_second);
371 393
				PATCH(global_bytes_per_second_cnt);
372 394
				con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
395
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.activate"))) {
396
				PATCH(ssl_verifyclient);
397
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.enforce"))) {
398
				PATCH(ssl_verifyclient_enforce);
399
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.depth"))) {
400
				PATCH(ssl_verifyclient_depth);
401
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.username"))) {
402
				PATCH(ssl_verifyclient_username);
373 403
			}
374 404
		}
375 405
	}
src/response.c (Arbeitskopie)
132 132
	return 0;
133 133
}
134 134

  
135
#ifdef USE_OPENSSL
136
static void response_add_ssl_entries(connection *con) {
137
	X509 *xs;
138
	X509_NAME *xn;
139
	X509_NAME_ENTRY *xe;
140
	if (
141
		SSL_get_verify_result(con->sock->ssl) != X509_V_OK
142
		|| !(xs = SSL_get_peer_certificate(con->sock->ssl))
143
	) {
144
		return;
145
	}
146
	
147
	xn = X509_get_subject_name(xs);
148
	for (int i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
149
		int xobjnid;
150
		const char * xobjsn;
151
		data_string *envds;
152
		
153
		if (!(xe = X509_NAME_get_entry(xn, i))) {
154
			continue;
155
		}
156
		xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
157
		xobjsn = OBJ_nid2sn(xobjnid);
158
		if (!xobjsn) {
159
			continue;
160
		}
161
		
162
		if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
163
			envds = data_string_init();
164
		}
165
		buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
166
		buffer_append_string(envds->key, xobjsn);
167
		buffer_copy_string(
168
			envds->value,
169
			(const char *)xe->value->data
170
		);
171
		if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
172
			buffer_copy_string_buffer(con->authed_user, envds->value);
173
		}
174
		array_insert_unique(con->environment, (data_unset *)envds);
175
	}
176
	X509_free(xs);
177
}
178
#endif
135 179

  
136

  
137 180
handler_t handle_get_backend(server *srv, connection *con) {
138 181
	handler_t r;
139 182

  
......
232 275
		if (srv->sockets_disabled) {
233 276
			con->keep_alive = 0;
234 277
		}
278
		
279
		/* handle client cert validation */
280
#ifdef USE_OPENSSL
281
		if (con->conf.is_ssl && con->conf.ssl_verifyclient) {
282
			response_add_ssl_entries(con);
283
		}
284
#endif
235 285

  
236 286

  
237 287
		/**
src/server.c (Arbeitskopie)
294 294
			buffer_free(s->error_handler);
295 295
			buffer_free(s->errorfile_prefix);
296 296
			array_free(s->mimetypes);
297
			buffer_free(s->ssl_verifyclient_username);
297 298

  
298 299
			free(s);
299 300
		}
(2-2/12)