]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/civetweb/src/civetweb.c
update sources to v12.2.3
[ceph.git] / ceph / src / civetweb / src / civetweb.c
index bc647469b8f13b4ae19b9ead7b3d295b07c9a7c8..26f1edb0634ad4d9fed685ceea12839ded14195d 100644 (file)
@@ -1070,6 +1070,7 @@ enum {
        CGI_INTERPRETER,
        PROTECT_URI,
        AUTHENTICATION_DOMAIN,
+       ENABLE_AUTH_DOMAIN_CHECK,
        SSI_EXTENSIONS,
        THROTTLE,
        ACCESS_LOG_FILE,
@@ -1138,6 +1139,7 @@ static struct mg_option config_options[] = {
     {"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},
@@ -11763,16 +11765,18 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
        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);
@@ -11811,6 +11815,8 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
                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) {
@@ -11826,10 +11832,38 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
                }
        }
 
-       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;
@@ -11921,7 +11955,12 @@ getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
                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);
@@ -11937,10 +11976,6 @@ getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
                        }
                        /* 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")) {