⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_auth_digest.c

📁 最新apache的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            return HTTP_BAD_REQUEST;        }        if (d_uri.hostname) {            ap_unescape_url(d_uri.hostname);        }        if (d_uri.path) {            ap_unescape_url(d_uri.path);        }        if (d_uri.query) {            ap_unescape_url(d_uri.query);        }        else if (r_uri.query) {            /* MSIE compatibility hack.  MSIE has some RFC issues - doesn't              * include the query string in the uri Authorization component             * or when computing the response component.  the second part             * works out ok, since we can hash the header and get the same             * result.  however, the uri from the request line won't match             * the uri Authorization component since the header lacks the              * query string, leaving us incompatable with a (broken) MSIE.             *              * the workaround is to fake a query string match if in the proper             * environment - BrowserMatch MSIE, for example.  the cool thing             * is that if MSIE ever fixes itself the simple match ought to              * work and this code won't be reached anyway, even if the             * environment is set.             */                        if (apr_table_get(r->subprocess_env,                               "AuthDigestEnableQueryStringHack")) {                d_uri.query = r_uri.query;            }        }        if (r->method_number == M_CONNECT) {            if (!r_uri.hostinfo || strcmp(resp->uri, r_uri.hostinfo)) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                              "Digest: uri mismatch - <%s> does not match "                              "request-uri <%s>", resp->uri, r_uri.hostinfo);                return HTTP_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 && 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_ERR, 0, r,                          "Digest: uri mismatch - <%s> does not match "                          "request-uri <%s>", resp->uri, resp->raw_request_uri);            return HTTP_BAD_REQUEST;        }    }    if (resp->opaque && resp->opaque_num == 0) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "Digest: received invalid opaque - got `%s'",                      resp->opaque);        note_digest_auth_failure(r, conf, resp, 0);        return HTTP_UNAUTHORIZED;    }    if (strcmp(resp->realm, conf->realm)) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "Digest: realm mismatch - got `%s' but expected `%s'",                      resp->realm, conf->realm);        note_digest_auth_failure(r, conf, resp, 0);        return HTTP_UNAUTHORIZED;    }    if (resp->algorithm != NULL        && strcasecmp(resp->algorithm, "MD5")        && strcasecmp(resp->algorithm, "MD5-sess")) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "Digest: unknown algorithm `%s' received: %s",                      resp->algorithm, r->uri);        note_digest_auth_failure(r, conf, resp, 0);        return HTTP_UNAUTHORIZED;    }    if (!conf->pwfile) {        return DECLINED;    }    if (!(conf->ha1 = get_hash(r, r->user, conf->realm, conf->pwfile))) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "Digest: user `%s' in realm `%s' not found: %s",                      r->user, conf->realm, r->uri);        note_digest_auth_failure(r, conf, resp, 0);        return HTTP_UNAUTHORIZED;    }        if (resp->message_qop == NULL) {        /* old (rfc-2069) style digest */        if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Digest: user %s: password mismatch: %s", r->user,                          r->uri);            note_digest_auth_failure(r, conf, resp, 0);            return HTTP_UNAUTHORIZED;        }    }    else {        const char *exp_digest;        int match = 0, idx;        for (idx = 0; conf->qop_list[idx] != NULL; idx++) {            if (!strcasecmp(conf->qop_list[idx], resp->message_qop)) {                match = 1;                break;            }        }        if (!match            && !(conf->qop_list[0] == NULL                 && !strcasecmp(resp->message_qop, "auth"))) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Digest: invalid qop `%s' received: %s",                          resp->message_qop, r->uri);            note_digest_auth_failure(r, conf, resp, 0);            return HTTP_UNAUTHORIZED;        }        exp_digest = new_digest(r, resp, conf);        if (!exp_digest) {            /* we failed to allocate a client struct */            return HTTP_INTERNAL_SERVER_ERROR;        }        if (strcmp(resp->digest, exp_digest)) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Digest: user %s: password mismatch: %s", r->user,                          r->uri);            note_digest_auth_failure(r, conf, resp, 0);            return HTTP_UNAUTHORIZED;        }    }    if (check_nc(r, resp, conf) != OK) {        note_digest_auth_failure(r, conf, resp, 0);        return HTTP_UNAUTHORIZED;    }    /* Note: this check is done last so that a "stale=true" can be       generated if the nonce is old */    if ((res = check_nonce(r, resp, conf))) {        return res;    }    return OK;}/* * Checking ID */static apr_table_t *groups_for_user(request_rec *r, const char *user,                                    const char *grpfile){    ap_configfile_t *f;    apr_table_t *grps = apr_table_make(r->pool, 15);    apr_pool_t *sp;    char l[MAX_STRING_LEN];    const char *group_name, *ll, *w;    apr_status_t sts;    if ((sts = ap_pcfg_openfile(&f, r->pool, grpfile)) != APR_SUCCESS) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, sts, r,                      "Digest: Could not open group file: %s", grpfile);        return NULL;    }    if (apr_pool_create(&sp, r->pool) != APR_SUCCESS) {        return NULL;    }    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {        if ((l[0] == '#') || (!l[0])) {            continue;        }        ll = l;        apr_pool_clear(sp);        group_name = ap_getword(sp, &ll, ':');        while (ll[0]) {            w = ap_getword_conf(sp, &ll);            if (!strcmp(w, user)) {                apr_table_setn(grps, apr_pstrdup(r->pool, group_name), "in");                break;            }        }    }    ap_cfg_closefile(f);    apr_pool_destroy(sp);    return grps;}static int digest_check_auth(request_rec *r){    const digest_config_rec *conf =                (digest_config_rec *) ap_get_module_config(r->per_dir_config,                                                           &auth_digest_module);    const char *user = r->user;    int m = r->method_number;    int method_restricted = 0;    register int x;    const char *t, *w;    apr_table_t *grpstatus;    const apr_array_header_t *reqs_arr;    require_line *reqs;    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest")) {        return DECLINED;    }    reqs_arr = ap_requires(r);    /* If there is no "requires" directive, then any user will do.     */    if (!reqs_arr) {        return OK;    }    reqs = (require_line *) reqs_arr->elts;    if (conf->grpfile) {        grpstatus = groups_for_user(r, user, conf->grpfile);    }    else {        grpstatus = NULL;    }    for (x = 0; x < reqs_arr->nelts; x++) {        if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {            continue;        }        method_restricted = 1;        t = reqs[x].requirement;        w = ap_getword_white(r->pool, &t);        if (!strcasecmp(w, "valid-user")) {            return OK;        }        else if (!strcasecmp(w, "user")) {            while (t[0]) {                w = ap_getword_conf(r->pool, &t);                if (!strcmp(user, w)) {                    return OK;                }            }        }        else if (!strcasecmp(w, "group")) {            if (!grpstatus) {                return DECLINED;            }            while (t[0]) {                w = ap_getword_conf(r->pool, &t);                if (apr_table_get(grpstatus, w)) {                    return OK;                }            }        }        else {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Digest: access to %s failed, reason: unknown "                          "require directive \"%s\"",                          r->uri, reqs[x].requirement);            return DECLINED;        }    }    if (!method_restricted) {        return OK;    }    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                  "Digest: access to %s failed, reason: user %s not "                  "allowed access", r->uri, user);    note_digest_auth_failure(r, conf,        (digest_header_rec *) ap_get_module_config(r->request_config,                                                   &auth_digest_module),        0);    return HTTP_UNAUTHORIZED;}/* * Authorization-Info header code */#ifdef SEND_DIGESTstatic const char *hdr(const apr_table_t *tbl, const char *name){    const char *val = apr_table_get(tbl, name);    if (val) {        return val;    }    else {        return "";    }}#endifstatic int add_auth_info(request_rec *r){    const digest_config_rec *conf =                (digest_config_rec *) ap_get_module_config(r->per_dir_config,                                                           &auth_digest_module);    digest_header_rec *resp =                (digest_header_rec *) ap_get_module_config(r->request_config,                                                           &auth_digest_module);    const char *ai = NULL, *digest = NULL, *nextnonce = "";    if (resp == NULL || !resp->needed_auth || conf == NULL) {        return OK;    }    /* rfc-2069 digest     */    if (resp->message_qop == NULL) {        /* old client, so calc rfc-2069 digest */#ifdef SEND_DIGEST        /* most of this totally bogus because the handlers don't set the         * headers until the final handler phase (I wonder why this phase         * is called fixup when there's almost nothing you can fix up...)         *         * Because it's basically impossible to get this right (e.g. the         * Content-length is never set yet when we get here, and we can't         * calc the entity hash) it's best to just leave this #def'd out.         */        char date[APR_RFC822_DATE_LEN];        apr_rfc822_date(date, r->request_time);        char *entity_info =            ap_md5(r->pool,                   (unsigned char *) apr_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 : "", ":",                       hdr(r->headers_out, "Last-Modified"), ":",                       r->no_cache && !apr_table_get(r->headers_out, "Expires") ?                            date :                            hdr(r->headers_out, "Expires"),                       NULL));        digest =            ap_md5(r->pool,                   (unsigned char *)apr_pstrcat(r->pool, conf->ha1, ":",                                               resp->nonce, ":",                                               r->method, ":",                                               date, ":",                                               entity_info, ":",                                               ap_md5(r->pool, (unsigned char *) ""), /* H(entity) - TBD */                                               NULL));#endif    }    /* setup nextnonce     */    if (conf->nonce_lifetime > 0) {        /* send nextnonce if current nonce will expire in less than 30 secs */        if ((r->request_time - resp->nonce_time) > (conf->nonce_lifetime-NEXTNONCE_DELTA)) {            nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"",                                   gen_nonce(r->pool, r->request_time,                                             resp->opaque, r->server, conf),                                   "\"", NULL);            if (resp->client)                resp->client->nonce_count = 0;        }    }    else if (conf->nonce_lifetime == 0 && resp->client) {        const char *nonce = gen_nonce(r->pool, 0, resp->opaque, r->server,   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -