summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c')
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c206
1 files changed, 132 insertions, 74 deletions
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
index d8a014c5be6..b417eb227b0 100644
--- a/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
+++ b/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
@@ -12,22 +12,18 @@
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
-#if !(NGX_PCRE)
-
-#define ngx_regex_t void
-
-#endif
-
typedef struct {
ngx_hash_combined_t hash;
#if (NGX_PCRE)
ngx_array_t *regex;
+ ngx_array_t *server_name_regex;
#endif
ngx_flag_t no_referer;
ngx_flag_t blocked_referer;
+ ngx_flag_t server_names;
ngx_hash_keys_arrays_t *keys;
@@ -41,10 +37,14 @@ static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent,
void *child);
static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
- ngx_str_t *value, ngx_str_t *uri);
-static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
- ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
+static ngx_int_t ngx_http_add_referer(ngx_conf_t *cf,
+ ngx_hash_keys_arrays_t *keys, ngx_str_t *value, ngx_str_t *uri);
+static ngx_int_t ngx_http_add_regex_referer(ngx_conf_t *cf,
+ ngx_http_referer_conf_t *rlcf, ngx_str_t *name);
+#if (NGX_PCRE)
+static ngx_int_t ngx_http_add_regex_server_name(ngx_conf_t *cf,
+ ngx_http_referer_conf_t *rlcf, ngx_http_regex_t *regex);
+#endif
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
const void *two);
@@ -117,6 +117,10 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
ngx_uint_t i, key;
ngx_http_referer_conf_t *rlcf;
u_char buf[256];
+#if (NGX_PCRE)
+ ngx_int_t rc;
+ ngx_str_t referer;
+#endif
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
@@ -125,6 +129,7 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
&& rlcf->hash.wc_tail == NULL
#if (NGX_PCRE)
&& rlcf->regex == NULL
+ && rlcf->server_name_regex == NULL
#endif
)
{
@@ -147,10 +152,12 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) {
ref += 7;
+ len -= 7;
goto valid_scheme;
} else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) {
ref += 8;
+ len -= 8;
goto valid_scheme;
}
}
@@ -171,12 +178,12 @@ valid_scheme:
break;
}
- buf[i] = ngx_tolower(*p);
- key = ngx_hash(key, buf[i++]);
-
if (i == 256) {
goto invalid;
}
+
+ buf[i] = ngx_tolower(*p);
+ key = ngx_hash(key, buf[i++]);
}
uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
@@ -187,11 +194,26 @@ valid_scheme:
#if (NGX_PCRE)
- if (rlcf->regex) {
- ngx_int_t rc;
- ngx_str_t referer;
+ if (rlcf->server_name_regex) {
+ referer.len = p - ref;
+ referer.data = buf;
+
+ rc = ngx_regex_exec_array(rlcf->server_name_regex, &referer,
+ r->connection->log);
+
+ if (rc == NGX_OK) {
+ goto valid;
+ }
+
+ if (rc == NGX_ERROR) {
+ return rc;
+ }
+
+ /* NGX_DECLINED */
+ }
- referer.len = len - 7;
+ if (rlcf->regex) {
+ referer.len = len;
referer.data = ref;
rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log);
@@ -251,8 +273,17 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
return NULL;
}
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->hash = { NULL };
+ * conf->server_names = 0;
+ * conf->keys = NULL;
+ */
+
#if (NGX_PCRE)
conf->regex = NGX_CONF_UNSET_PTR;
+ conf->server_name_regex = NGX_CONF_UNSET_PTR;
#endif
conf->no_referer = NGX_CONF_UNSET;
@@ -270,13 +301,18 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_referer_conf_t *prev = parent;
ngx_http_referer_conf_t *conf = child;
- ngx_hash_init_t hash;
+ ngx_uint_t n;
+ ngx_hash_init_t hash;
+ ngx_http_server_name_t *sn;
+ ngx_http_core_srv_conf_t *cscf;
if (conf->keys == NULL) {
conf->hash = prev->hash;
#if (NGX_PCRE)
ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
+ ngx_conf_merge_ptr_value(conf->server_name_regex,
+ prev->server_name_regex, NULL);
#endif
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
@@ -288,6 +324,33 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
+ if (conf->server_names == 1) {
+ cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
+
+ sn = cscf->server_names.elts;
+ for (n = 0; n < cscf->server_names.nelts; n++) {
+
+#if (NGX_PCRE)
+ if (sn[n].regex) {
+
+ if (ngx_http_add_regex_server_name(cf, conf, sn[n].regex)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+#endif
+
+ if (ngx_http_add_referer(cf, conf->keys, &sn[n].name, NULL)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+ }
+
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
&& conf->keys->keys.nelts == 0
&& conf->keys->dns_wc_head.nelts == 0
@@ -366,6 +429,8 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_PCRE)
ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
+ ngx_conf_merge_ptr_value(conf->server_name_regex, prev->server_name_regex,
+ NULL);
#endif
if (conf->no_referer == NGX_CONF_UNSET) {
@@ -389,15 +454,12 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u_char *p;
ngx_str_t *value, uri, name;
- ngx_uint_t i, n;
+ ngx_uint_t i;
ngx_http_variable_t *var;
- ngx_http_server_name_t *sn;
- ngx_http_core_srv_conf_t *cscf;
ngx_str_set(&name, "invalid_referer");
- var = ngx_http_add_variable(cf, &name,
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH);
+ var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
if (var == NULL) {
return NGX_CONF_ERROR;
}
@@ -437,48 +499,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
- ngx_str_null(&uri);
-
if (ngx_strcmp(value[i].data, "server_names") == 0) {
-
- cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
-
- sn = cscf->server_names.elts;
- for (n = 0; n < cscf->server_names.nelts; n++) {
-
-#if (NGX_PCRE)
- if (sn[n].regex) {
-
- if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
- sn[n].regex->regex)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-#endif
-
- if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
+ rlcf->server_names = 1;
continue;
}
if (value[i].data[0] == '~') {
- if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
- {
+ if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) {
return NGX_CONF_ERROR;
}
continue;
}
+ ngx_str_null(&uri);
+
p = (u_char *) ngx_strchr(value[i].data, '/');
if (p) {
@@ -496,20 +531,20 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
-static char *
+static ngx_int_t
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
ngx_str_t *value, ngx_str_t *uri)
{
ngx_int_t rc;
ngx_str_t *u;
- if (uri->len == 0) {
+ if (uri == NULL || uri->len == 0) {
u = NGX_HTTP_REFERER_NO_URI_PART;
} else {
u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
if (u == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*u = *uri;
@@ -518,7 +553,7 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
if (rc == NGX_OK) {
- return NGX_CONF_OK;
+ return NGX_OK;
}
if (rc == NGX_DECLINED) {
@@ -531,13 +566,13 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
"conflicting parameter \"%V\"", value);
}
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-static char *
+static ngx_int_t
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
- ngx_str_t *name, ngx_regex_t *regex)
+ ngx_str_t *name)
{
#if (NGX_PCRE)
ngx_regex_elt_t *re;
@@ -546,26 +581,19 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
if (name->len == 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (rlcf->regex == NGX_CONF_UNSET_PTR) {
rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t));
if (rlcf->regex == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
}
re = ngx_array_push(rlcf->regex);
if (re == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (regex) {
- re->regex = regex;
- re->name = name->data;
-
- return NGX_CONF_OK;
+ return NGX_ERROR;
}
name->len--;
@@ -581,13 +609,13 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
if (ngx_regex_compile(&rc) != NGX_OK) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
re->regex = rc.regex;
re->name = name->data;
- return NGX_CONF_OK;
+ return NGX_OK;
#else
@@ -595,12 +623,42 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
"the using of the regex \"%V\" requires PCRE library",
name);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
#endif
}
+#if (NGX_PCRE)
+
+static ngx_int_t
+ngx_http_add_regex_server_name(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
+ ngx_http_regex_t *regex)
+{
+ ngx_regex_elt_t *re;
+
+ if (rlcf->server_name_regex == NGX_CONF_UNSET_PTR) {
+ rlcf->server_name_regex = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_regex_elt_t));
+ if (rlcf->server_name_regex == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ re = ngx_array_push(rlcf->server_name_regex);
+ if (re == NULL) {
+ return NGX_ERROR;
+ }
+
+ re->regex = regex->regex;
+ re->name = regex->name.data;
+
+ return NGX_OK;
+}
+
+#endif
+
+
static int ngx_libc_cdecl
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
{