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

📄 auth_digest.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 4 页
字号:
    node = digest_user->nonces.head;    while (node && (node->data != nonce))	node = node->next;    if (node)	return;    node = dlinkNodeNew();    dlinkAddTail(nonce, node, &digest_user->nonces);    authDigestNonceLink(nonce);    /* ping this nonce to this auth user */    assert((nonce->auth_user == NULL) || (nonce->auth_user = auth_user));    /* we don't lock this reference because removing the auth_user removes the      * hash too. Of course if that changes we're stuffed so read the code huh?     */    nonce->auth_user = auth_user;}/* authenticateDigestUsername: return a pointer to the username in the */static char *authenticateDigestUsername(auth_user_t * auth_user){    digest_user_h *digest_user = auth_user->scheme_data;    if (digest_user)	return digest_user->username;    return NULL;}/* setup the necessary info to log the username */static voidauthDigestLogUsername(auth_user_request_t * auth_user_request, char *username){    auth_user_t *auth_user;    digest_user_h *digest_user;    dlink_node *node;    /* log the username */    debug(29, 9) ("authDigestLogUsername: Creating new user for logging '%s'\n", username);    /* new auth_user */    auth_user = authenticateAuthUserNew("digest");    /* new scheme data */    digest_user = authDigestUserNew();    /* save the credentials */    digest_user->username = username;    /* link the scheme data in */    auth_user->scheme_data = digest_user;    /* set the auth_user type */    auth_user->auth_type = AUTH_BROKEN;    /* link the request to the user */    auth_user_request->auth_user = auth_user;    /* lock for the auth_user_request link */    authenticateAuthUserLock(auth_user);    node = dlinkNodeNew();    dlinkAdd(auth_user_request, node, &auth_user->requests);}/* * Decode a Digest [Proxy-]Auth string, placing the results in the passed * Auth_user structure. */static voidauthenticateDigestDecodeAuth(auth_user_request_t * auth_user_request, const char *proxy_auth){    String temp;    const char *item;    const char *p;    const char *pos = NULL;    char *username = NULL;    digest_nonce_h *nonce;    int ilen;    digest_request_h *digest_request;    digest_user_h *digest_user;    auth_user_t *auth_user;    dlink_node *node;    debug(29, 9) ("authenticateDigestDecodeAuth: beginning\n");    assert(auth_user_request != NULL);    digest_request = authDigestRequestNew();    /* trim DIGEST from string */    while (xisgraph(*proxy_auth))	proxy_auth++;    /* Trim leading whitespace before decoding */    while (xisspace(*proxy_auth))	proxy_auth++;    stringInit(&temp, proxy_auth);    while (strListGetItem(&temp, ',', &item, &ilen, &pos)) {	if ((p = strchr(item, '=')) && (p - item < ilen))	    ilen = p++ - item;	if (!strncmp(item, "username", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    username = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found Username '%s'\n", username);	} else if (!strncmp(item, "realm", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    digest_request->realm = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found realm '%s'\n", digest_request->realm);	} else if (!strncmp(item, "qop", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    if (*p == '\"')		/* quote mark */		p++;	    digest_request->qop = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);	    debug(29, 9) ("authDigestDecodeAuth: Found qop '%s'\n", digest_request->qop);	} else if (!strncmp(item, "algorithm", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    if (*p == '\"')		/* quote mark */		p++;	    digest_request->algorithm = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);	    debug(29, 9) ("authDigestDecodeAuth: Found algorithm '%s'\n", digest_request->algorithm);	} else if (!strncmp(item, "uri", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    digest_request->uri = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found uri '%s'\n", digest_request->uri);	} else if (!strncmp(item, "nonce", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    digest_request->nonceb64 = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found nonce '%s'\n", digest_request->nonceb64);	} else if (!strncmp(item, "nc", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    xstrncpy(digest_request->nc, p, 9);	    debug(29, 9) ("authDigestDecodeAuth: Found noncecount '%s'\n", digest_request->nc);	} else if (!strncmp(item, "cnonce", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    digest_request->cnonce = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found cnonce '%s'\n", digest_request->cnonce);	} else if (!strncmp(item, "response", ilen)) {	    /* white space */	    while (xisspace(*p))		p++;	    /* quote mark */	    p++;	    digest_request->response = xstrndup(p, strchr(p, '"') + 1 - p);	    debug(29, 9) ("authDigestDecodeAuth: Found response '%s'\n", digest_request->response);	}    }    stringClean(&temp);    /* now we validate the data given to us */    /*     * TODO: on invalid parameters we should return 400, not 407.     * Find some clean way of doing this. perhaps return a valid     * struct, and set the direction to clientwards combined with     * a change to the clientwards handling code (ie let the     * clientwards call set the error type (but limited to known     * correct values - 400/401/407     */    /* first the NONCE count */    if (digest_request->cnonce && strlen(digest_request->nc) != 8) {	debug(29, 4) ("authenticateDigestDecode: nonce count length invalid\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* now the nonce */    nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);    if (!nonce) {	/* we couldn't find a matching nonce! */	debug(29, 4) ("authenticateDigestDecode: Unexpected or invalid nonce recieved\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    digest_request->nonce = nonce;    authDigestNonceLink(nonce);    /* check the qop is what we expected. Note that for compatability with      * RFC 2069 we should support a missing qop. Tough. */    if (!digest_request->qop || strcmp(digest_request->qop, QOP_AUTH)) {	/* we recieved a qop option we didn't send */	debug(29, 4) ("authenticateDigestDecode: Invalid qop option recieved\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* we can't check the URI just yet. We'll check it in the     * authenticate phase */    /* is the response the correct length? */    if (!digest_request->response || strlen(digest_request->response) != 32) {	debug(29, 4) ("authenticateDigestDecode: Response length invalid\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* do we have a username ? */    if (!username || username[0] == '\0') {	debug(29, 4) ("authenticateDigestDecode: Empty or not present username\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* check that we're not being hacked / the username hasn't changed */    if (nonce->auth_user && strcmp(username, authenticateUserUsername(nonce->auth_user))) {	debug(29, 4) ("authenticateDigestDecode: Username for the nonce does not equal the username for the request\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* if we got a qop, did we get a cnonce or did we get a cnonce wihtout a qop? */    if ((digest_request->qop && !digest_request->cnonce)	|| (!digest_request->qop && digest_request->cnonce)) {	debug(29, 4) ("authenticateDigestDecode: qop without cnonce, or vice versa!\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* check the algorithm is present and supported */    if (!digest_request->algorithm)	digest_request->algorithm = xstrndup("MD5", 4);    else if (strcmp(digest_request->algorithm, "MD5")	&& strcmp(digest_request->algorithm, "MD5-sess")) {	debug(29, 4) ("authenticateDigestDecode: invalid algorithm specified!\n");	authDigestLogUsername(auth_user_request, username);	/* we don't need the scheme specific data anymore */	authDigestRequestDelete(digest_request);	auth_user_request->scheme_data = NULL;	return;    }    /* the method we'll check at the authenticate step as well */    /* we don't send or parse opaques. Ok so we're flexable ... */    /* find the user */    if ((auth_user = authDigestUserFindUsername(username)) == NULL) {	/* the user doesn't exist in the username cache yet */	debug(29, 9) ("authDigestDecodeAuth: Creating new digest user '%s'\n", username);	/* new auth_user */	auth_user = authenticateAuthUserNew("digest");	/* new scheme user data */	digest_user = authDigestUserNew();	/* save the username */	digest_user->username = username;	/* link the primary struct in */	auth_user->scheme_data = digest_user;	/* set the user type */	auth_user->auth_type = AUTH_DIGEST;	/* this auth_user struct is the one to get added to the	 * username cache */	/* store user in hash's */	authenticateUserNameCacheAdd(auth_user);	/* 	 * Add the digest to the user so we can tell if a hacking	 * or spoofing attack is taking place. We do this by assuming	 * the user agent won't change user name without warning.	 */	authDigestUserLinkNonce(auth_user, nonce);    } else {	debug(29, 9) ("authDigestDecodeAuth: Found user '%s' in the user cache as '%p'\n", username, auth_user);	digest_user = auth_user->scheme_data;	xfree(username);    }    /*link the request and the user */    auth_user_request->auth_user = auth_user;    auth_user_request->scheme_data = digest_request;    /* lock for the request link */    authenticateAuthUserLock(auth_user);    node = dlinkNodeNew();    dlinkAdd(auth_user_request, node, &auth_user->requests);    debug(29, 9) ("username = '%s'\nrealm = '%s'\nqop = '%s'\nalgorithm = '%s'\nuri = '%s'\nnonce = '%s'\nnc = '%s'\ncnonce = '%s'\nresponse = '%s'\ndigestnonce = '%p'\n",	digest_user->username, digest_request->realm,	digest_request->qop, digest_request->algorithm,	digest_request->uri, digest_request->nonceb64,	digest_request->nc, digest_request->cnonce, digest_request->response, nonce);    return;}/* send the initial data to a digest authenticator module */static voidauthenticateDigestStart(auth_user_request_t * auth_user_request, RH * handler, void *data){    authenticateStateData *r = NULL;    char buf[8192];    digest_request_h *digest_request;    digest_user_h *digest_user;    assert(auth_user_request);    assert(handler);    assert(auth_user_request->auth_user->auth_type == AUTH_DIGEST);    assert(auth_user_request->auth_user->scheme_data != NULL);    assert(auth_user_request->scheme_data != NULL);    digest_request = auth_user_request->scheme_data;    digest_user = auth_user_request->auth_user->scheme_data;    debug(29, 9) ("authenticateStart: '\"%s\":\"%s\"'\n", digest_user->username,	digest_request->realm);    if (digestConfig->authenticate == NULL) {	handler(data, NULL);	return;    }    r = cbdataAlloc(authenticateStateData);    r->handler = handler;    cbdataLock(data);    r->data = data;    r->auth_user_request = auth_user_request;    authenticateAuthUserRequestLock(r->auth_user_request);    snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username, digest_request->realm);    helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r);}

⌨️ 快捷键说明

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