CGI_INTERPRETER,
PROTECT_URI,
AUTHENTICATION_DOMAIN,
+ ENABLE_AUTH_DOMAIN_CHECK,
SSI_EXTENSIONS,
THROTTLE,
ACCESS_LOG_FILE,
{"cgi_interpreter", CONFIG_TYPE_FILE, NULL},
{"protect_uri", CONFIG_TYPE_STRING, NULL},
{"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"},
+ {"enable_auth_domain_check", CONFIG_TYPE_BOOLEAN, "yes"},
{"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
{"throttle", CONFIG_TYPE_STRING, NULL},
{"access_log_file", CONFIG_TYPE_FILE, NULL},
size_t server_domain_len;
size_t request_domain_len = 0;
unsigned long port = 0;
- int i;
+ int i, auth_domain_check_enabled;
const char *hostbegin = NULL;
const char *hostend = NULL;
const char *portbegin;
char *portend;
+ auth_domain_check_enabled =
+ !strcmp(conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK],"yes");
/* DNS is case insensitive, so use case insensitive string compare here
*/
server_domain = conn->ctx->config[AUTHENTICATION_DOMAIN];
- if (!server_domain) {
+ if (!server_domain && auth_domain_check_enabled) {
return 0;
}
server_domain_len = strlen(server_domain);
return 0;
}
+/* Check if the request is directed to a different server. */
+/* First check if the port is the same (IPv4 and IPv6). */
#if defined(USE_IPV6)
if (conn->client.lsa.sa.sa_family == AF_INET6) {
if (ntohs(conn->client.lsa.sin6.sin6_port) != port) {
}
}
- if ((request_domain_len != server_domain_len)
- || (0 != memcmp(server_domain, hostbegin, server_domain_len))) {
- /* Request is directed to another server */
- return 0;
+ /* Finally check if the server corresponds to the authentication
+ * domain of the server (the server domain).
+ * Allow full matches (like http://mydomain.com/path/file.ext), and
+ * allow subdomain matches (like http://www.mydomain.com/path/file.ext),
+ * but do not allow substrings (like http://notmydomain.com/path/file.ext
+ * or http://mydomain.com.fake/path/file.ext).
+ */
+ if (auth_domain_check_enabled) {
+ if ((request_domain_len == server_domain_len)
+ && (!memcmp(server_domain, hostbegin, server_domain_len))) {
+ /* Request is directed to this server - full name match. */
+ } else {
+ if (request_domain_len < (server_domain_len + 2)) {
+ /* Request is directed to another server: The server name is longer
+ * than
+ * the request name. Drop this case here to avoid overflows in the
+ * following checks. */
+ return 0;
+ }
+ if (hostbegin[request_domain_len - server_domain_len - 1] != '.') {
+ /* Request is directed to another server: It could be a substring
+ * like notmyserver.com */
+ return 0;
+ }
+ if (0 != memcmp(server_domain,
+ hostbegin + request_domain_len - server_domain_len,
+ server_domain_len)) {
+ /* Request is directed to another server:
+ * The server name is different. */
+ return 0;
+ }
+ }
}
return hostend;
return 0;
} else {
/* Message is a valid request or response */
- if ((cl = get_header(&conn->request_info, "Content-Length")) != NULL) {
+ if ((cl = get_header(&conn->request_info, "Transfer-Encoding"))
+ != NULL
+ && !mg_strcasecmp(cl, "chunked")) {
+ conn->is_chunked = 1;
+ conn->content_len = 0;
+ } else if ((cl = get_header(&conn->request_info, "Content-Length")) != NULL) {
/* Request/response has content length set */
char *endptr = NULL;
conn->content_len = strtoll(cl, &endptr, 10);
}
/* Publish the content length back to the request info. */
conn->request_info.content_length = conn->content_len;
- } else if ((cl = get_header(&conn->request_info, "Transfer-Encoding"))
- != NULL
- && !mg_strcasecmp(cl, "chunked")) {
- conn->is_chunked = 1;
} else if (!mg_strcasecmp(conn->request_info.request_method, "POST")
|| !mg_strcasecmp(conn->request_info.request_method,
"PUT")) {