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

📄 auth_digest.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 4 页
字号:
		digest_request->nc, digest_request->cnonce, digest_request->qop,		RequestMethodStr[METHOD_GET], digest_request->uri, HA2, Response);	    if (strcasecmp(digest_request->response, Response)) {		digest_request->flags.credentials_ok = 3;		safe_free(auth_user_request->message);		auth_user_request->message = xstrdup("Incorrect password");		return;	    } else {		const char *useragent = httpHeaderGetStr(&request->header, HDR_USER_AGENT);		static struct in_addr last_broken_addr;		static int seen_broken_client = 0;		if (!seen_broken_client) {		    last_broken_addr = no_addr;		    seen_broken_client = 1;		}		if (memcmp(&last_broken_addr, &request->client_addr, sizeof(last_broken_addr)) != 0) {		    debug(29, 1) ("\nDigest POST bug detected from %s using '%s'. Please upgrade browser. See Bug #630 for details.\n", inet_ntoa(request->client_addr), useragent ? useragent : "-");		    last_broken_addr = request->client_addr;		}	    }	} else {	    digest_request->flags.credentials_ok = 3;	    safe_free(auth_user_request->message);	    auth_user_request->message = xstrdup("Incorrect password");	    return;	}    }    /* check for stale nonce */    if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc)) {	debug(29, 3) ("authenticateDigestAuthenticateuser: user '%s' validated OK but nonce stale\n",	    digest_user->username);	digest_request->flags.nonce_stale = 1;	digest_request->flags.credentials_ok = 3;	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup("Stale nonce");	return;    }    /* password was checked and did match */    digest_request->flags.credentials_ok = 1;    debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n",	digest_user->username);    /* auth_user is now linked, we reset these values     * after external auth occurs anyway */    auth_user->expiretime = current_time.tv_sec;    return;}static intauthenticateDigestDirection(auth_user_request_t * auth_user_request){    digest_request_h *digest_request = auth_user_request->scheme_data;    if (!digest_request)	return -2;    switch (digest_request->flags.credentials_ok) {    case 0:			/* not checked */	return -1;    case 1:			/* checked & ok */	return 0;    case 2:			/* partway through checking. */	return -1;    case 3:			/* authentication process failed. */	if (digest_request->flags.nonce_stale)	    /* nonce is stale, send new challenge */	    return 1;	return -2;    }    return -2;}/* add the [proxy]authorisation header */static voidauthDigestAddHeader(auth_user_request_t * auth_user_request, HttpReply * rep, int accel){    int type;    digest_request_h *digest_request;    if (!auth_user_request)	return;    digest_request = auth_user_request->scheme_data;    if (!digest_request)	return;    /* don't add to authentication error pages */    if ((!accel && rep->sline.status == HTTP_PROXY_AUTHENTICATION_REQUIRED)	|| (accel && rep->sline.status == HTTP_UNAUTHORIZED))	return;    type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;#if WAITING_FOR_TE    /* test for http/1.1 transfer chunked encoding */    if (chunkedtest)	return;#endif    if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) {	digest_request->flags.authinfo_sent = 1;	debug(29, 9) ("authDigestAddHead: Sending type:%d header: 'nextnonce=\"%s\"", type, authenticateDigestNonceNonceb64(digest_request->nonce));	httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(digest_request->nonce));    }}#if WAITING_FOR_TE/* add the [proxy]authorisation header */static voidauthDigestAddTrailer(auth_user_request_t * auth_user_request, HttpReply * rep, int accel){    int type;    digest_request_h *digest_request;    if (!auth_user_request)	return;    digest_request = auth_user_request->scheme_data;    /* has the header already been send? */    if (digest_request->flags.authinfo_sent)	return;    /* don't add to authentication error pages */    if ((!accel && rep->sline.status == HTTP_PROXY_AUTHENTICATION_REQUIRED)	|| (accel && rep->sline.status == HTTP_UNAUTHORIZED))	return;    type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;    if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) {	debug(29, 9) ("authDigestAddTrailer: Sending type:%d header: 'nextnonce=\"%s\"", type, authenticateDigestNonceNonceb64(digest_request->nonce));	httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(digest_request->nonce));    }}#endif/* add the [www-|Proxy-]authenticate header on a 407 or 401 reply */voidauthenticateDigestFixHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, request_t * request){    digest_request_h *digest_request;    int stale = 0;    digest_nonce_h *nonce = authenticateDigestNonceNew();    if (auth_user_request && auth_user_request->scheme_data) {	digest_request = auth_user_request->scheme_data;	stale = digest_request->flags.nonce_stale;    }    if (digestConfig->authenticate) {	debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");	/* in the future, for WWW auth we may want to support the domain entry */	httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s", digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");    }}static voidauthenticateDigestUserFree(auth_user_t * auth_user){    digest_user_h *digest_user = auth_user->scheme_data;    dlink_node *link, *tmplink;    debug(29, 9) ("authenticateDigestFreeUser: Clearing Digest scheme data\n");    if (!digest_user)	return;    safe_free(digest_user->username);    link = digest_user->nonces.head;    while (link) {	tmplink = link;	link = link->next;	dlinkDelete(tmplink, &digest_user->nonces);	authDigestNoncePurge(tmplink->data);	authDigestNonceUnlink(tmplink->data);	dlinkNodeDelete(tmplink);    }    memPoolFree(digest_user_pool, auth_user->scheme_data);    auth_user->scheme_data = NULL;}static voidauthenticateDigestHandleReply(void *data, char *reply){    authenticateStateData *r = data;    auth_user_request_t *auth_user_request;    digest_request_h *digest_request;    digest_user_h *digest_user;    int valid;    char *t = NULL;    debug(29, 9) ("authenticateDigestHandleReply: {%s}\n", reply ? reply : "<NULL>");    if (reply) {	if ((t = strchr(reply, ' ')))	    *t++ = '\0';	if (*reply == '\0' || *reply == '\n')	    reply = NULL;    }    assert(r->auth_user_request != NULL);    auth_user_request = r->auth_user_request;    assert(auth_user_request->scheme_data != NULL);    digest_request = auth_user_request->scheme_data;    digest_user = auth_user_request->auth_user->scheme_data;    if (reply && (strncasecmp(reply, "ERR", 3) == 0)) {	digest_request->flags.credentials_ok = 3;	safe_free(auth_user_request->message);	if (t && *t)	    auth_user_request->message = xstrdup(t);    } else if (reply) {	CvtBin(reply, digest_user->HA1);	digest_user->HA1created = 1;    }    valid = cbdataValid(r->data);    if (valid)	r->handler(r->data, NULL);    cbdataUnlock(r->data);    authenticateStateFree(r);}/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */static voidauthDigestInit(authScheme * scheme){    static int init = 0;    if (digestConfig->authenticate) {	authDigestUserSetup();	authDigestRequestSetup();	authenticateDigestNonceSetup();	authdigest_initialised = 1;	if (digestauthenticators == NULL)	    digestauthenticators = helperCreate("digestauthenticator");	digestauthenticators->cmdline = digestConfig->authenticate;	digestauthenticators->n_to_start = digestConfig->authenticateChildren;	digestauthenticators->concurrency = digestConfig->authenticateConcurrency;	digestauthenticators->ipc_type = IPC_STREAM;	helperOpenServers(digestauthenticators);	if (!init) {	    cachemgrRegister("digestauthenticator",		"Digest User Authenticator Stats",		authenticateDigestStats, 0, 1);	    init++;	}	CBDATA_INIT_TYPE(authenticateStateData);    }}/* free any allocated configuration details */voidauthDigestFreeConfig(authScheme * scheme){    if (digestConfig == NULL)	return;    assert(digestConfig == scheme->scheme_data);    if (digestConfig->authenticate)	wordlistDestroy(&digestConfig->authenticate);    if (digestConfig->digestAuthRealm)	safe_free(digestConfig->digestAuthRealm);    xfree(digestConfig);    digestConfig = NULL;}static voidauthDigestParse(authScheme * scheme, int n_configured, char *param_str){    if (scheme->scheme_data == NULL) {	assert(digestConfig == NULL);	/* this is the first param to be found */	scheme->scheme_data = xmalloc(sizeof(auth_digest_config));	memset(scheme->scheme_data, 0, sizeof(auth_digest_config));	digestConfig = scheme->scheme_data;	digestConfig->authenticateChildren = 5;	digestConfig->digestAuthRealm = xstrdup("Squid proxy-caching web server");	/* 5 minutes */	digestConfig->nonceGCInterval = 5 * 60;	/* 30 minutes */	digestConfig->noncemaxduration = 30 * 60;	/* 50 requests */	digestConfig->noncemaxuses = 50;	/* Not strict nonce count behaviour */	digestConfig->NonceStrictness = 0;	/* Verify nonce count */	digestConfig->CheckNonceCount = 1;	digestConfig->PostWorkaround = 0;    }    digestConfig = scheme->scheme_data;    if (strcasecmp(param_str, "program") == 0) {	if (digestConfig->authenticate)	    wordlistDestroy(&digestConfig->authenticate);	parse_wordlist(&digestConfig->authenticate);    } else if (strcasecmp(param_str, "children") == 0) {	parse_int(&digestConfig->authenticateChildren);    } else if (strcasecmp(param_str, "concurrency") == 0) {	parse_int(&digestConfig->authenticateConcurrency);    } else if (strcasecmp(param_str, "realm") == 0) {	parse_eol(&digestConfig->digestAuthRealm);    } else if (strcasecmp(param_str, "nonce_garbage_interval") == 0) {	parse_time_t(&digestConfig->nonceGCInterval);    } else if (strcasecmp(param_str, "nonce_max_duration") == 0) {	parse_time_t(&digestConfig->noncemaxduration);    } else if (strcasecmp(param_str, "nonce_max_count") == 0) {	parse_int(&digestConfig->noncemaxuses);    } else if (strcasecmp(param_str, "nonce_strictness") == 0) {	parse_onoff(&digestConfig->NonceStrictness);    } else if (strcasecmp(param_str, "check_nonce_count") == 0) {	parse_onoff(&digestConfig->CheckNonceCount);    } else if (strcasecmp(param_str, "post_workaround") == 0) {	parse_onoff(&digestConfig->PostWorkaround);    } else {	debug(29, 0) ("unrecognised digest auth scheme parameter '%s'\n", param_str);    }}static voidauthDigestCheckConfig(authScheme * scheme){    auth_digest_config *config = scheme->scheme_data;    requirePathnameExists("authparam digest program", config->authenticate->key);}static voidauthenticateDigestStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "Digest Authenticator Statistics:\n");    helperStats(sentry, digestauthenticators);}/* NonceUserUnlink: remove the reference to auth_user and unlink the node from the list */static voidauthDigestNonceUserUnlink(digest_nonce_h * nonce){    digest_user_h *digest_user;    dlink_node *link, *tmplink;    if (!nonce)	return;    if (!nonce->auth_user)	return;    digest_user = nonce->auth_user->scheme_data;    /* unlink from the user list. Yes we're crossing structures but this is the only      * time this code is needed     */    link = digest_user->nonces.head;    while (link) {	tmplink = link;	link = link->next;	if (tmplink->data == nonce) {	    dlinkDelete(tmplink, &digest_user->nonces);	    authDigestNonceUnlink(tmplink->data);	    dlinkNodeDelete(tmplink);	    link = NULL;	}    }    /* this reference to auth_user was not locked because freeeing the auth_user frees     * the nonce too.      */    nonce->auth_user = NULL;}/* authDigestUserLinkNonce: add a nonce to a given user's struct */static voidauthDigestUserLinkNonce(auth_user_t * auth_user, digest_nonce_h * nonce){    dlink_node *node;    digest_user_h *digest_user;    if (!auth_user || !nonce)	return;    if (!auth_user->scheme_data)	return;    digest_user = auth_user->scheme_data;

⌨️ 快捷键说明

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