Browse Source

[ssl] Fix $HTTP["scheme"] conditional, could be "http" for ssl connections if the ssl $SERVER["socket"] conditional was nested (fixes #2501)

con->conf.is_ssl got removed and replaced by:
 * con->conf.ssl_enabled for the config var "ssl.engine" - it is only
   used to determine which server-sockets should use ssl. (usually not
   needed as it is mandatory and enough to set ssl.pemfile anyway)
 * con->srv_socket->is_ssl to detect the actual ssl status of the
   bound socket, which is the same as the ssl status of the connection
 * con->uri.scheme for the actual $HTTP["scheme"] value, also used for
   the CGI "HTTPS=ON" variable. This defaults to "https" if the
   connection uses ssl, but can be changed for example by mod_extforward
   if X-Forwarded-Proto: is set to either "http" or "https" (other values
   are ignored right now)

Also removed the broken srv_socket->is_proxy_ssl as it was a connection
value in a server_socket struct...

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2887 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.33
Stefan Bühler 8 years ago
parent
commit
05858f6cf2
  1. 1
      NEWS
  2. 7
      src/base.h
  3. 6
      src/buffer.c
  4. 1
      src/buffer.h
  5. 12
      src/configfile.c
  6. 13
      src/connections.c
  7. 20
      src/http-header-glue.c
  8. 8
      src/mod_cgi.c
  9. 13
      src/mod_extforward.c
  10. 2
      src/mod_fastcgi.c
  11. 2
      src/mod_proxy.c
  12. 2
      src/mod_scgi.c
  13. 4
      src/network.c
  14. 5
      src/response.c

1
NEWS

@ -23,6 +23,7 @@ NEWS
* [core] recognize more http methods to forward to backends (fixes #2346)
* [ssl] use DH only if openssl supports it (fixes #2479)
* [network] use constants available at compile time for maximum number of chunks for writev instead of calling sysconf (fixes #2470)
* [ssl] Fix $HTTP["scheme"] conditional, could be "http" for ssl connections if the ssl $SERVER["socket"] conditional was nested (fixes #2501)
- 1.4.32 - 2012-11-21
* Code cleanup with clang/sparse (fixes #2437, thx kibi)

7
src/base.h

@ -289,7 +289,7 @@ typedef struct {
unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */
unsigned short defer_accept;
unsigned short is_ssl;
unsigned short ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
unsigned short allow_http11;
unsigned short etag_use_inode;
unsigned short etag_use_mtime;
@ -432,7 +432,7 @@ typedef struct {
int error_handler_saved_status;
int in_error_handler;
void *srv_socket; /* reference to the server-socket (typecast to server_socket) */
struct server_socket *srv_socket; /* reference to the server-socket */
#ifdef USE_OPENSSL
SSL *ssl;
@ -525,7 +525,7 @@ typedef struct {
unsigned short reject_expect_100_with_417;
} server_config;
typedef struct {
typedef struct server_socket {
sock_addr addr;
int fd;
int fde_ndx;
@ -545,7 +545,6 @@ typedef struct {
#ifdef USE_OPENSSL
SSL_CTX *ssl_ctx;
#endif
unsigned short is_proxy_ssl;
} server_socket;
typedef struct {

6
src/buffer.c

@ -538,6 +538,12 @@ int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
return buffer_is_equal(a, &b);
}
/* buffer_is_equal_caseless_string(b, CONST_STR_LEN("value")) */
int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len) {
if (a->used != b_len + 1) return 0;
return (0 == strcasecmp(a->ptr, s));
}
int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
size_t const len = (a_len < b_len) ? a_len : b_len;

1
src/buffer.h

@ -82,6 +82,7 @@ int buffer_is_empty(buffer *b);
int buffer_is_equal(buffer *a, buffer *b);
int buffer_is_equal_right_len(buffer *a, buffer *b, size_t len);
int buffer_is_equal_string(buffer *a, const char *s, size_t b_len);
int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len);
int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);
typedef enum {

12
src/configfile.c

@ -177,7 +177,7 @@ static int config_insert(server *srv) {
s->max_read_idle = 60;
s->max_write_idle = 360;
s->use_xattr = 0;
s->is_ssl = 0;
s->ssl_enabled = 0;
s->ssl_honor_cipher_order = 1;
s->ssl_use_sslv2 = 0;
s->ssl_use_sslv3 = 1;
@ -231,7 +231,7 @@ static int config_insert(server *srv) {
cv[27].destination = &(s->use_xattr);
cv[28].destination = s->mimetypes;
cv[29].destination = s->ssl_pemfile;
cv[30].destination = &(s->is_ssl);
cv[30].destination = &(s->ssl_enabled);
cv[31].destination = &(s->log_file_not_found);
cv[32].destination = &(s->log_request_handling);
@ -332,7 +332,7 @@ int config_setup_connection(server *srv, connection *con) {
PATCH(range_requests);
PATCH(force_lowercase_filenames);
PATCH(is_ssl);
PATCH(ssl_enabled);
PATCH(ssl_pemfile);
#ifdef USE_OPENSSL
@ -418,7 +418,7 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.cipher-list"))) {
PATCH(ssl_cipher_list);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) {
PATCH(is_ssl);
PATCH(ssl_enabled);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.dh-file"))) {
PATCH(ssl_dh_file);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ec-curve"))) {
@ -1306,7 +1306,7 @@ int config_set_defaults(server *srv) {
}
if (srv->srvconf.port == 0) {
srv->srvconf.port = s->is_ssl ? 443 : 80;
srv->srvconf.port = s->ssl_enabled ? 443 : 80;
}
if (srv->srvconf.event_handler->used == 0) {
@ -1344,7 +1344,7 @@ int config_set_defaults(server *srv) {
}
}
if (s->is_ssl) {
if (s->ssl_enabled) {
if (buffer_is_empty(s->ssl_pemfile)) {
/* PEM file is require */

13
src/connections.c

@ -200,7 +200,7 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
int r, ssl_err, len, count = 0, read_offset, toread;
buffer *b = NULL;
if (!con->conf.is_ssl) return -1;
if (!con->srv_socket->is_ssl) return -1;
ERR_clear_error();
do {
@ -334,7 +334,7 @@ static int connection_handle_read(server *srv, connection *con) {
buffer *b;
int toread, read_offset;
if (con->conf.is_ssl) {
if (con->srv_socket->is_ssl) {
return connection_handle_read_ssl(srv, con);
}
@ -1174,7 +1174,7 @@ static handler_t connection_handle_fdevent(server *srv, void *context, int reven
joblist_append(srv, con);
if (con->conf.is_ssl) {
if (con->srv_socket->is_ssl) {
/* ssl may read and write for both reads and writes */
if (revents & (FDEVENT_IN | FDEVENT_OUT)) {
con->is_readable = 1;
@ -1345,7 +1345,6 @@ connection *connection_accept(server *srv, server_socket *srv_socket) {
con->renegotiations = 0;
SSL_set_app_data(con->ssl, con);
SSL_set_accept_state(con->ssl);
con->conf.is_ssl=1;
if (1 != (SSL_set_fd(con->ssl, cnt))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
@ -1390,12 +1389,6 @@ int connection_state_machine(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_READ);
/* patch con->conf.is_ssl if the connection is a ssl-socket already */
#ifdef USE_OPENSSL
con->conf.is_ssl = srv_sock->is_ssl;
#endif
break;
case CON_STATE_REQUEST_END: /* transient */
if (srv->srvconf.log_state_handling) {

20
src/http-header-glue.c

@ -123,11 +123,8 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
o = buffer_init();
if (con->conf.is_ssl) {
buffer_copy_string_len(o, CONST_STR_LEN("https://"));
} else {
buffer_copy_string_len(o, CONST_STR_LEN("http://"));
}
buffer_copy_string_buffer(o, con->uri.scheme);
buffer_append_string_len(o, CONST_STR_LEN("://"));
if (con->uri.authority->used) {
buffer_append_string_buffer(o, con->uri.authority);
} else {
@ -193,10 +190,15 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
return -1;
}
if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
(con->conf.is_ssl == 1 && srv->srvconf.port == 443))) {
buffer_append_string_len(o, CONST_STR_LEN(":"));
buffer_append_long(o, srv->srvconf.port);
{
unsigned short default_port = 80;
if (buffer_is_equal_caseless_string(con->uri.scheme, CONST_STR_LEN("https"))) {
default_port = 443;
}
if (default_port != srv->srvconf.port) {
buffer_append_string_len(o, CONST_STR_LEN(":"));
buffer_append_long(o, srv->srvconf.port);
}
}
}
buffer_append_string_buffer(o, con->uri.path);

8
src/mod_cgi.c

@ -923,11 +923,9 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
CONST_BUF_LEN(con->authed_user));
}
#ifdef USE_OPENSSL
if (srv_sock->is_ssl) {
cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
}
#endif
if (buffer_is_equal_caseless_string(con->uri.scheme, CONST_STR_LEN("https"))) {
cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
}
/* request.content_length < SSIZE_MAX, see request.c */
LI_ltostr(buf, con->request.content_length);

13
src/mod_extforward.c

@ -423,17 +423,18 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
if (real_remote_addr != NULL) { /* parsed */
sock_addr sock;
server_socket *srv_sock = con->srv_socket;
data_string *forwarded_proto = (data_string *)array_get_element(con->request.headers, "X-Forwarded-Proto");
if (forwarded_proto && !strcmp(forwarded_proto->value->ptr, "https")) {
srv_sock->is_proxy_ssl = 1;
} else {
srv_sock->is_proxy_ssl = 0;
if (NULL != forwarded_proto) {
if (buffer_is_equal_caseless_string(forwarded_proto->value, CONST_STR_LEN("https"))) {
buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https"));
} else if (buffer_is_equal_caseless_string(forwarded_proto->value, CONST_STR_LEN("http"))) {
buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
}
}
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "ss", "using address:", real_remote_addr);
log_error_write(srv, __FILE__, __LINE__, "ss", "using address:", real_remote_addr);
}
#ifdef HAVE_IPV6
ipstr_to_sockaddr(srv, real_remote_addr, &sock);

2
src/mod_fastcgi.c

@ -2032,7 +2032,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
s = get_http_version_name(con->request.http_version);
FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)),con)
if (srv_sock->is_ssl || srv_sock->is_proxy_ssl) {
if (buffer_is_equal_caseless_string(con->uri.scheme, CONST_STR_LEN("https"))) {
FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")),con)
}

2
src/mod_proxy.c

@ -463,7 +463,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
!buffer_is_empty(con->request.http_host)) {
proxy_set_header(con, "X-Host", con->request.http_host->ptr);
}
proxy_set_header(con, "X-Forwarded-Proto", con->conf.is_ssl ? "https" : "http");
proxy_set_header(con, "X-Forwarded-Proto", con->uri.scheme->ptr);
/* request header */
for (i = 0; i < con->request.headers->used; i++) {

2
src/mod_scgi.c

@ -1614,7 +1614,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
#ifdef USE_OPENSSL
if (srv_sock->is_ssl) {
if (buffer_is_equal_caseless_string(con->uri.scheme, CONST_STR_LEN("https"))) {
scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
}
#endif

4
src/network.c

@ -391,7 +391,7 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
goto error_free_socket;
}
if (s->is_ssl) {
if (s->ssl_enabled) {
#ifdef USE_OPENSSL
if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
@ -425,7 +425,7 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
#endif
}
srv_socket->is_ssl = s->is_ssl;
srv_socket->is_ssl = s->ssl_enabled;
if (srv->srv_sockets.size == 0) {
srv->srv_sockets.size = 4;

5
src/response.c

@ -264,7 +264,8 @@ handler_t http_response_prepare(server *srv, connection *con) {
*
*/
if (con->conf.is_ssl) {
/* initial scheme value. can be overwritten for example by mod_extforward later */
if (con->srv_socket->is_ssl) {
buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https"));
} else {
buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
@ -351,7 +352,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
}
#ifdef USE_OPENSSL
if (con->conf.is_ssl && con->conf.ssl_verifyclient) {
if (con->srv_socket->is_ssl && con->conf.ssl_verifyclient) {
https_add_ssl_entries(con);
}
#endif

Loading…
Cancel
Save