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

📄 htaabrow.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
📖 第 1 页 / 共 3 页
字号:
		char * tmplate = make_template(url);		basic = (HTBasic *) HTAA_updateNode(proxy, BASIC_AUTH, rm,						    tmplate, NULL);		/* if the previous authentication failed, then try again */		if (HTRequest_AAretrys (request) > 1 		    && status == HT_NO_ACCESS && basic)		  basic->retry = YES;		HT_FREE(url);		HT_FREE(tmplate);	    }	}	/*	** For some reason the authentication failed so we have to ask the user	** if we should try again. It may be because the user typed the wrong	** user name and password	*/	if (basic && basic->retry) {	    HTAlertCallback * prompt = HTAlert_find(HT_A_CONFIRM);	    /*	    ** Do we have a method registered for prompting the user whether	    ** we should retry	    */	    if (prompt) {		int code = proxy ?		    HT_MSG_RETRY_PROXY_AUTH : HT_MSG_RETRY_AUTHENTICATION;		if ((*prompt)(request, HT_A_CONFIRM, code,			      NULL, NULL, NULL) != YES)		    return HT_ERROR;	    }	}	return HT_OK;    }    HTTRACE(AUTH_TRACE, "Auth........ No challenges found\n");    return HT_ERROR;}/* ------------------------------------------------------------------------- *//*				Digest Authentication                        *//* ------------------------------------------------------------------------- *//***	Prompt the user for username and password.**	Returns	YES if user name was typed in, else NO*/PRIVATE int prompt_digest_user (HTRequest * request, const char * realm,				HTDigest * digest){    HTAlertCallback * cbf = HTAlert_find(HT_A_USER_PW);    /* If no method for prompting the user then we might as well give up */    if (!cbf) return HT_ERROR;    /* Otherwise go ahead and ask the user */    if (request) {	HTAlertPar * reply = HTAlert_newReply();	int msg = digest->proxy ? HT_MSG_PROXY_UID : HT_MSG_UID;	BOOL res = (*cbf)(request, HT_A_USER_PW, msg,			  digest->uid, (char *) realm, reply);	if (res) {	    HT_FREE(digest->uid);	    HT_FREE(digest->pw);	    digest->uid = HTAlert_replyMessage(reply);	    digest->pw = HTAlert_replySecret(reply);	}	HTAlert_deleteReply(reply);	return res ? HT_OK : HT_ERROR;    }    return HT_OK;}PRIVATE HTDigest * HTDigest_new(){    HTDigest * me = NULL;    if ((me = (HTDigest *) HT_CALLOC(1, sizeof(HTDigest))) == NULL)	HT_OUTOFMEM("HTDigest_new");    me->algorithm = HTDaMD5;                   /* use md5 as a default value */    me->retry = YES;			       /* Ask the first time through */    return me;}/*	HTDigest_delete**	--------------**	Deletes a "digest" information object**	A single object may be registered multiple places in the URL tree.**	We keep a simple reference count on the object so that we know**	when to delete the object.*/PUBLIC int HTDigest_delete (void * context){    HTDigest * digest = (HTDigest *) context;    if (digest) {	if (digest->references <= 0) {	    HT_FREE(digest->uid);	    HT_FREE(digest->pw);	    HT_FREE(digest->realm);	    HT_FREE(digest->cnonce);	    HT_FREE(digest->nonce);	    HT_FREE(digest->opaque);	    HT_FREE(digest->qop);	    HT_FREE(digest);	    return YES;	}	else	    digest->references--;    }    return NO;}/*	HTDigest_reset**	--------------**      When digest authentication fails, we simulate a new digest by**      erasing the old one, but keeping the uid and the password. This is**      so that we can take into account the stale nonce protocol, without**      prompting the user for a new password.*/PRIVATE int HTDigest_reset (HTDigest *digest){    if (digest) {	digest->nc = 0l;	digest->stale = 0;	digest->retry = YES;	HT_FREE(digest->cnonce);	HT_FREE(digest->nonce);	HT_FREE(digest->opaque);	HT_FREE(digest->qop);	return YES;    }    else	return NO;}/*	HTDigest_updateInfo**	--------------**      This function updates the digest with whatever new ** 	authentification information the server sent back.*/PUBLIC int HTDigest_updateInfo (HTRequest *request, HTResponse *response,				void * context, int status){    HTAssocList * challenge = HTResponse_challenge(response);    const char * realm =  HTRequest_realm (request);    if (request && challenge && realm) {        BOOL proxy = 0;	char * value = NULL;	char * token = NULL;	char * auth_info = NULL;		HTDigest *digest;	char *url;	/*	** try to find the magic string in the challenge 	*/	HTTRACE(AUTH_TRACE, "Digest Update.. Processing authentication-info\n");	if ((auth_info = HTAssocList_findObject(challenge, DIGEST_AI)))	    proxy = 0;	else if ((auth_info = HTAssocList_findObject(challenge, 						     PROXY_DIGEST_AI)))	    proxy = 1;	else {	    HTTRACE(AUTH_TRACE, "Digest Update.. Didn't find any authentication-info\n");	    return HT_OK;	}    	/* 	** find the digest credentials 	*/	if (proxy) {	    url = HTRequest_proxy(request);	    digest = (HTDigest *) HTAA_updateNode (proxy, DIGEST_AUTH, realm,						   url, NULL);	} else {	    url = HTAnchor_address((HTAnchor *)				   HTRequest_anchor(request));	    digest = (HTDigest *) HTAA_updateNode (proxy, DIGEST_AUTH, realm, 						   url, NULL);	    HT_FREE(url);	}	if (!digest) {	    HTTRACE(AUTH_TRACE, "Digest Update.. Error: received authentication-info without having a local digest\n");		    return HT_ERROR;	}	/*	**  Search through the set of parameters in the Authentication-info	**  header.	*/	while ((token = HTNextField(&auth_info))) {	    if (!strcasecomp(token, "nextnonce")) {		if ((value = HTNextField(&auth_info))) {		    HT_FREE (digest->nonce);		    StrAllocCopy(digest->nonce, value);		} else if (!strcasecomp(token, "qop")) {		    value = HTNextField(&auth_info);		    /* split, process  the qop, report errors */		} else if (!strcasecomp(token, "rspauth")) {		    value = HTNextField(&auth_info);		    /* process rspauth */		} else if (!strcasecomp(token, "cnonce")) {		    value = HTNextField (&auth_info);		    if (value && strcmp (digest->cnonce, value)) {			/* print an alert?, bad cnonce? */		    }			} else if (!strcasecomp(token, "nc")) {		    value = HTNextField(&auth_info);		    /* compare and printo some error? */		}	    }		}    }    return HT_OK;}    /***    Simple function to add a parameter/value pair to a string***/PRIVATE BOOL add_param (char ** dest, char *param, char * value, BOOL quoted){    char *tmp = *dest;    if (!param || *param == '\0' || !value || *value == '\0')	return NO;    /* if there was a previous parameter, we add the next one in the       following line */    if (tmp) 	StrAllocCat(tmp, ",");    /* copy the new parameter and value */    StrAllocCat(tmp, param);    StrAllocCat(tmp, "=");    if (quoted) {    StrAllocCat(tmp, "\"");    StrAllocCat(tmp, value);    StrAllocCat(tmp, "\"");    } else	StrAllocCat(tmp, value);    *dest = tmp;    return YES;}/***  Code derived from draft-ietf-http-authentication-03 starts here*/PRIVATE void CvtHex (HASH Bin, HASHHEX Hex){    unsigned short i;    unsigned char j;    for (i = 0; i < HASHLEN; i++) {	j = (Bin[i] >> 4) & 0xf;	if (j <= 9)	    Hex[i*2] = (j + '0');	else	    Hex[i*2] = (j + 'a' - 10);	j = Bin[i] & 0xf;	if (j <= 9)	    Hex[i*2+1] = (j + '0');	else	    Hex[i*2+1] = (j + 'a' - 10);  }    Hex[HASHHEXLEN] = '\0';}/* calculate H(A1) as per spec */PRIVATE void DigestCalcHA1 (int algorithm, char * pszAlg, char * pszUserName,			    char * pszRealm, char * pszPassword,			    char * pszNonce, char * pszCNonce,			    HASHHEX SessionKey){    HTDigestContext MdCtx;    HASH HA1;    HTDigest_init (&MdCtx, algorithm);    HTDigest_update (&MdCtx, pszUserName, strlen(pszUserName));    HTDigest_update (&MdCtx, ":", 1);    HTDigest_update (&MdCtx, pszRealm, strlen(pszRealm));    HTDigest_update (&MdCtx, ":", 1);    HTDigest_update (&MdCtx, pszPassword, strlen(pszPassword));    HTDigest_final (HA1, &MdCtx);    if (strcasecomp (pszAlg, "md5-sess") == 0) {	HTDigest_init (&MdCtx, algorithm);	HTDigest_update (&MdCtx, HA1, strlen (HA1));	HTDigest_update (&MdCtx, ":", 1);	HTDigest_update (&MdCtx, pszNonce, strlen(pszNonce));	HTDigest_update (&MdCtx, ":", 1);	HTDigest_update (&MdCtx, pszCNonce, strlen(pszCNonce));	HTDigest_final (HA1, &MdCtx);    }    CvtHex (HA1, SessionKey);}/* calculate request-digest/response-digest as per HTTP Digest spec */PRIVATE void DigestCalcResponse (    int    algorithm,      /* message digest algorithm */    HASHHEX HA1,           /* H(A1) */    char * pszNonce,       /* nonce from server */    char * pszNonceCount,  /* 8 hex digits */    char * pszCNonce,      /* client nonce */    char * pszQop,         /* qop-value: "", "auth", "auth-int" */    char * pszMethod,      /* method from the request */    char * pszDigestUri,   /* requested URL */    char * HEntity,        /* H(entity body) if qop="auth-int" */    char * Response        /* request-digest or response-digest */    ){    HTDigestContext MdCtx;    HASH HA2;    HASH RespHash;    HASHHEX HA2Hex;    /* calculate H(A2) */    HTDigest_init (&MdCtx, algorithm);    HTDigest_update (&MdCtx, pszMethod, strlen(pszMethod));    HTDigest_update (&MdCtx, ":", 1);    HTDigest_update (&MdCtx, pszDigestUri, strlen(pszDigestUri));    if (pszQop && strcasecomp (pszQop, "auth-int") == 0) {	HTDigest_update (&MdCtx, ":", 1);	HTDigest_update (&MdCtx, HEntity, HASHHEXLEN);    }    HTDigest_final (HA2, &MdCtx);    CvtHex (HA2, HA2Hex);    /* calculate response */    HTDigest_init (&MdCtx, algorithm);    HTDigest_update (&MdCtx, HA1, HASHHEXLEN);    HTDigest_update (&MdCtx, ":", 1);    HTDigest_update (&MdCtx, pszNonce, strlen(pszNonce));    HTDigest_update (&MdCtx, ":", 1);    if (pszQop && *pszQop) {	HTDigest_update (&MdCtx, pszNonceCount, strlen(pszNonceCount));	HTDigest_update (&MdCtx, ":", 1);	HTDigest_update (&MdCtx, pszCNonce, strlen(pszCNonce));	HTDigest_update (&MdCtx, ":", 1);	HTDigest_update (&MdCtx, pszQop, strlen(pszQop));	HTDigest_update (&MdCtx, ":", 1);    }    HTDigest_update (&MdCtx, HA2Hex, HASHHEXLEN);    HTDigest_final (RespHash, &MdCtx);    CvtHex (RespHash, Response);}	/***  Code derived from draft-ietf-http-authentication-03 ends here*//***	Make digest authentication scheme credentials and register this**	information in the request object as credentials. They will then**	be included in the request header. An example is****                 "Digest nonce:cnonce:blahblahblhah:digest-response"****	The function can both create normal and proxy credentials**	Returns	HT_OK or HT_ERROR*/

⌨️ 快捷键说明

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