Browse Source

[core] config match w/ arbitrary HTTP request hdrs (fixes #1556)

x-ref:
  "Allow matching against any arbitrary HTTP header in the configuration file regexps"
  https://redmine.lighttpd.net/issues/1556
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
2ac2911b9a
  1. 6
      src/array.h
  2. 32
      src/configfile-glue.c
  3. 24
      src/configparser.y
  4. 5
      src/data_config.c
  5. 1
      src/response.c

6
src/array.h

@ -76,14 +76,15 @@ typedef enum {
COMP_SERVER_SOCKET,
COMP_HTTP_URL,
COMP_HTTP_HOST,
COMP_HTTP_REFERER,
COMP_HTTP_REFERER, /*(subsumed by COMP_HTTP_REQUEST_HEADER)*/
COMP_HTTP_USER_AGENT,
COMP_HTTP_LANGUAGE,
COMP_HTTP_COOKIE,
COMP_HTTP_COOKIE, /*(subsumed by COMP_HTTP_REQUEST_HEADER)*/
COMP_HTTP_REMOTE_IP,
COMP_HTTP_QUERY_STRING,
COMP_HTTP_SCHEME,
COMP_HTTP_REQUEST_METHOD,
COMP_HTTP_REQUEST_HEADER,
COMP_LAST_ELEMENT
} comp_key_t;
@ -101,6 +102,7 @@ struct data_config {
array *value;
buffer *comp_tag;
buffer *comp_key;
comp_key_t comp;

32
src/configfile-glue.c

@ -489,28 +489,9 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
l = srv_sock->srv_token;
break;
case COMP_HTTP_REFERER: {
case COMP_HTTP_REQUEST_HEADER: {
data_string *ds;
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
l = ds->value;
} else {
l = srv->empty_string;
}
break;
}
case COMP_HTTP_COOKIE: {
data_string *ds;
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
l = ds->value;
} else {
l = srv->empty_string;
}
break;
}
case COMP_HTTP_USER_AGENT: {
data_string *ds;
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) {
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, dc->comp_tag->ptr))) {
l = ds->value;
} else {
l = srv->empty_string;
@ -528,15 +509,6 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
break;
}
case COMP_HTTP_LANGUAGE: {
data_string *ds;
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Language"))) {
l = ds->value;
} else {
l = srv->empty_string;
}
break;
}
default:
return COND_RESULT_FALSE;
}

24
src/configparser.y

@ -552,11 +552,11 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
{ COMP_SERVER_SOCKET, CONST_STR_LEN("SERVER[\"socket\"]" ) },
{ COMP_HTTP_URL, CONST_STR_LEN("HTTP[\"url\"]" ) },
{ COMP_HTTP_HOST, CONST_STR_LEN("HTTP[\"host\"]" ) },
{ COMP_HTTP_REFERER, CONST_STR_LEN("HTTP[\"referer\"]" ) },
{ COMP_HTTP_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"referer\"]" ) },
{ COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) },
{ COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"user-agent\"]" ) },
{ COMP_HTTP_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"user-agent\"]" ) },
{ COMP_HTTP_LANGUAGE, CONST_STR_LEN("HTTP[\"language\"]" ) },
{ COMP_HTTP_COOKIE, CONST_STR_LEN("HTTP[\"cookie\"]" ) },
{ COMP_HTTP_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"cookie\"]" ) },
{ COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) },
{ COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remote-ip\"]" ) },
{ COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"querystring\"]") },
@ -571,6 +571,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
buffer_copy_buffer(dc->key, b);
buffer_copy_buffer(dc->op, op);
buffer_copy_buffer(dc->comp_tag, C);
buffer_copy_buffer(dc->comp_key, B);
buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\""));
buffer_append_string_buffer(dc->comp_key, C);
@ -585,8 +586,21 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
}
}
if (COMP_UNSET == dc->comp) {
fprintf(stderr, "error comp_key %s", dc->comp_key->ptr);
ctx->ok = 0;
if (buffer_is_equal_string(B, CONST_STR_LEN("REQUEST_HEADER"))) {
dc->comp = COMP_HTTP_REQUEST_HEADER;
}
else {
fprintf(stderr, "error comp_key %s", dc->comp_key->ptr);
ctx->ok = 0;
}
}
else if (COMP_HTTP_LANGUAGE == dc->comp) {
dc->comp = COMP_HTTP_REQUEST_HEADER;
buffer_copy_string_len(dc->comp_tag, CONST_STR_LEN("Accept-Language"));
}
else if (COMP_HTTP_USER_AGENT == dc->comp) {
dc->comp = COMP_HTTP_REQUEST_HEADER;
buffer_copy_string_len(dc->comp_tag, CONST_STR_LEN("User-Agent"));
}
else if (COMP_HTTP_REMOTE_IP == dc->comp
&& (dc->cond == CONFIG_COND_EQ || dc->cond == CONFIG_COND_NE)) {

5
src/data_config.c

@ -10,7 +10,9 @@ static data_unset *data_config_copy(const data_unset *s) {
data_config *src = (data_config *)s;
data_config *ds = data_config_init();
ds->comp = src->comp;
buffer_copy_buffer(ds->key, src->key);
buffer_copy_buffer(ds->comp_tag, src->comp_tag);
buffer_copy_buffer(ds->comp_key, src->comp_key);
array_free(ds->value);
ds->value = array_init_array(src->value);
@ -22,6 +24,7 @@ static void data_config_free(data_unset *d) {
buffer_free(ds->key);
buffer_free(ds->op);
buffer_free(ds->comp_tag);
buffer_free(ds->comp_key);
array_free(ds->value);
@ -41,6 +44,7 @@ static void data_config_reset(data_unset *d) {
/* reused array elements */
buffer_reset(ds->key);
buffer_reset(ds->comp_tag);
buffer_reset(ds->comp_key);
array_reset(ds->value);
}
@ -130,6 +134,7 @@ data_config *data_config_init(void) {
ds->key = buffer_init();
ds->op = buffer_init();
ds->comp_tag = buffer_init();
ds->comp_key = buffer_init();
ds->value = array_init();
vector_config_weak_init(&ds->children);

1
src/response.c

@ -237,6 +237,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
con->conditional_is_valid[COMP_HTTP_REQUEST_METHOD] = 1; /* REQUEST_METHOD */
con->conditional_is_valid[COMP_HTTP_URL] = 1; /* HTTPurl */
con->conditional_is_valid[COMP_HTTP_QUERY_STRING] = 1; /* HTTPqs */
con->conditional_is_valid[COMP_HTTP_REQUEST_HEADER] = 1; /* HTTP request header */
config_patch_connection(srv, con);
/* do we have to downgrade to 1.0 ? */

Loading…
Cancel
Save