ronald      99/12/08 21:21:02

  Modified:    src      CHANGES
               src/modules/experimental mod_auth_digest.c
  Log:
  mod_auth_digest fixes:
  - better comparing of request-uri with uri parameter in Authorization
    header
  - added a check for a MUST condition in the spec
  - fixed SEGV
  
  Revision  Changes    Path
  1.1475    +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1474
  retrieving revision 1.1475
  diff -u -r1.1474 -r1.1475
  --- CHANGES   1999/12/08 23:01:46     1.1474
  +++ CHANGES   1999/12/09 05:20:52     1.1475
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3.10
   
  +  *) more fixes to mod_auth_digest:
  +     - better comparing of request-uri with uri parameter in Authorization
  +       header
  +     - added a check for a MUST condition in the spec
  +     - fixed SEGV
  +     [Ronald Tschalär]
  +
     *) mod_proxy now works on TPF.
        [Joe Moenich <[EMAIL PROTECTED]>]
   
  
  
  
  1.12      +81 -28    apache-1.3/src/modules/experimental/mod_auth_digest.c
  
  Index: mod_auth_digest.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/experimental/mod_auth_digest.c,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- mod_auth_digest.c 1999/11/28 12:41:59     1.11
  +++ mod_auth_digest.c 1999/12/09 05:21:00     1.12
  @@ -212,7 +212,8 @@
       /* the following fields are not (directly) from the header */
       time_t                nonce_time;
       enum hdr_sts          auth_hdr_sts;
  -    uri_components       *request_uri;
  +    const char           *raw_request_uri;
  +    uri_components       *psd_request_uri;
       int                   needed_auth;
       client_entry         *client;
   } digest_header_rec;
  @@ -498,9 +499,9 @@
        * and directives outside a virtual host section)
        */
       ap_SHA1Init(&conf->nonce_ctx);
  +    ap_SHA1Update_binary(&conf->nonce_ctx, secret, sizeof(secret));
       ap_SHA1Update_binary(&conf->nonce_ctx, (const unsigned char *) realm,
                         strlen(realm));
  -    ap_SHA1Update_binary(&conf->nonce_ctx, secret, sizeof(secret));
   
       return DECLINE_CMD;
   }
  @@ -911,7 +912,8 @@
       }
   
       if (!resp->username || !resp->realm || !resp->nonce || !resp->uri
  -     || !resp->digest) {
  +     || !resp->digest
  +     || (resp->message_qop && (!resp->cnonce || !resp->nonce_count))) {
        resp->auth_hdr_sts = INVALID;
        return !OK;
       }
  @@ -944,7 +946,8 @@
        return DECLINED;
   
       resp = ap_pcalloc(r->pool, sizeof(digest_header_rec));
  -    resp->request_uri = &r->parsed_uri;
  +    resp->raw_request_uri = r->unparsed_uri;
  +    resp->psd_request_uri = &r->parsed_uri;
       resp->needed_auth = 0;
       ap_set_module_config(r->request_config, &digest_auth_module, resp);
   
  @@ -1273,7 +1276,7 @@
        domain = conf->uri_list;
       else {
        /* They didn't specify any domain, so let's guess at it */
  -     domain = guess_domain(r->pool, resp->request_uri->path, r->filename,
  +     domain = guess_domain(r->pool, resp->psd_request_uri->path, r->filename,
                              conf->dir_name);
        if (domain[0] == '/' && domain[1] == '\0')
            domain = NULL;      /* "/" is the default, so no need to send it */
  @@ -1460,6 +1463,36 @@
   }
   
   
  +static void copy_uri_components(uri_components *dst, uri_components *src,
  +                             request_rec *r) {
  +    if (src->scheme && src->scheme[0] != '\0')
  +     dst->scheme = src->scheme;
  +    else
  +     dst->scheme = (char *) "http";
  +
  +    if (src->hostname && src->hostname[0] != '\0') {
  +     dst->hostname = ap_pstrdup(r->pool, src->hostname);
  +     ap_unescape_url(dst->hostname);
  +    }
  +    else
  +     dst->hostname = (char *) ap_get_server_name(r);
  +
  +    if (src->port_str && src->port_str[0] != '\0')
  +     dst->port = src->port;
  +    else
  +     dst->port = ap_get_server_port(r);
  +
  +    if (src->path && src->path[0] != '\0') {
  +     dst->path = ap_pstrdup(r->pool, src->path);
  +     ap_unescape_url(dst->path);
  +    }
  +
  +    if (src->query && src->query[0] != '\0') {
  +     dst->query = ap_pstrdup(r->pool, src->query);
  +     ap_unescape_url(dst->query);
  +    }
  +}
  +
   /* These functions return 0 if client is OK, and proper error status
    * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
    * SERVER_ERROR, if things are so totally confused that we couldn't
  @@ -1521,8 +1554,9 @@
                          "`%s': %s", resp->scheme, r->uri);
        else if (resp->auth_hdr_sts == INVALID)
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  -                       "Digest: missing user, realm, nonce, uri, or digest "
  -                       "in authorization header: %s", r->uri);
  +                       "Digest: missing user, realm, nonce, uri, digest, "
  +                       "cnonce, or nonce_count in authorization header: %s",
  +                       r->uri);
        /* else (resp->auth_hdr_sts == NO_HEADER) */
        note_digest_auth_failure(r, conf, resp, 0);
        return AUTH_REQUIRED;
  @@ -1534,10 +1568,13 @@
   
       /* check the auth attributes */
   
  -    if (strcmp(resp->uri, resp->request_uri->path)) {
  -     uri_components *r_uri = resp->request_uri, d_uri;
  -     int port;
  +    if (strcmp(resp->uri, resp->raw_request_uri)) {
  +     /* Hmm, the simple match didn't work (probably a proxy modified the
  +      * request-uri), so lets do a more sophisticated match
  +      */
  +     uri_components r_uri, d_uri;
   
  +     copy_uri_components(&r_uri, resp->psd_request_uri, r);
        if (ap_parse_uri_components(r->pool, resp->uri, &d_uri) != HTTP_OK) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                          "Digest: invalid uri <%s> in Authorization header",
  @@ -1551,24 +1588,40 @@
            ap_unescape_url(d_uri.path);
        if (d_uri.query)
            ap_unescape_url(d_uri.query);
  -     if (r_uri->query)
  -         ap_unescape_url(r_uri->query);
  -     port = ap_get_server_port(r);
  -
  -     if ((d_uri.hostname && d_uri.hostname[0] != '\0'
  -          && strcasecmp(d_uri.hostname, ap_get_server_name(r)))
  -         || (d_uri.port_str && d_uri.port != port)
  +
  +     if (r->method_number == M_CONNECT) {
  +         if (strcmp(resp->uri, r_uri.hostinfo)) {
  +             ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  +                           "Digest: uri mismatch - <%s> does not match "
  +                           "request-uri <%s>", resp->uri, r_uri.hostinfo);
  +             return BAD_REQUEST;
  +         }
  +     }
  +     else if (
  +         /* check hostname matches, if present */
  +         (d_uri.hostname && d_uri.hostname[0] != '\0'
  +           && strcasecmp(d_uri.hostname, r_uri.hostname))
  +         /* check port matches, if present */
  +         || (d_uri.port_str && d_uri.port != r_uri.port)
  +         /* check that server-port is default port if no port present */
            || (d_uri.hostname && d_uri.hostname[0] != '\0'
  -             && !d_uri.port_str && port != ap_default_port(r))
  -         || !d_uri.path || strcmp(d_uri.path, r_uri->path)
  -         || (d_uri.query != r_uri->query
  -             && (!d_uri.query || !r_uri->query
  -                 || strcmp(d_uri.query, r_uri->query)))
  +             && !d_uri.port_str && r_uri.port != ap_default_port(r))
  +         /* check that path matches */
  +         || (d_uri.path != r_uri.path
  +             /* either exact match */
  +             && (!d_uri.path || !r_uri.path
  +                 || strcmp(d_uri.path, r_uri.path))
  +             /* or '*' matches empty path in scheme://host */
  +             && !(d_uri.path && !r_uri.path && 
resp->psd_request_uri->hostname
  +                 && d_uri.path[0] == '*' && d_uri.path[1] == '\0'))
  +         /* check that query matches */
  +         || (d_uri.query != r_uri.query
  +             && (!d_uri.query || !r_uri.query
  +                 || strcmp(d_uri.query, r_uri.query)))
            ) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                          "Digest: uri mismatch - <%s> does not match "
  -                       "request-uri <%s>", resp->uri,
  -                       ap_unparse_uri_components(r->pool, r_uri, 0));
  +                       "request-uri <%s>", resp->uri, resp->raw_request_uri);
            return BAD_REQUEST;
        }
       }
  @@ -1831,9 +1884,8 @@
         */
        char *entity_info =
            ap_md5(r->pool,
  -                (unsigned char *) ap_pstrcat(r->pool,
  -                    ap_unparse_uri_components(r->pool,
  -                                              resp->request_uri, 0), ":",
  +                (unsigned char *) ap_pstrcat(r->pool, resp->raw_request_uri,
  +                    ":",
                       r->content_type ? r->content_type : ap_default_type(r), 
":",
                       hdr(r->headers_out, "Content-Length"), ":",
                       r->content_encoding ? r->content_encoding : "", ":",
  @@ -1864,7 +1916,8 @@
                                   gen_nonce(r->pool, r->request_time,
                                             resp->opaque, r->server, conf),
                                   "\"", NULL);
  -         resp->client->nonce_count = 0;
  +         if (resp->client)
  +             resp->client->nonce_count = 0;
        }
       }
       else if (conf->nonce_lifetime == 0 && resp->client) {
  
  
  

Reply via email to