You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ro...@hyperreal.org on 1999/12/09 06:21:03 UTC

cvs commit: apache-1.3/src/modules/experimental mod_auth_digest.c

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 <mo...@us.ibm.com>]
   
  
  
  
  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) {