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

📄 ne_auth.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
		    NE_DEBUG(NE_DBG_HTTPAUTH, "Digesting qop-value [%s:].\n", 			     qop_value);		    ne_md5_process_bytes(qop_value, strlen(qop_value), 					 &sess->stored_rdig);		    ne_md5_process_bytes(":", 1, &sess->stored_rdig);		}		/* Digest ":" H(A2) */		ne_md5_process_bytes(a2_md5_ascii, 32, &sess->stored_rdig);		/* All done */		ne_md5_finish_ctx(&sess->stored_rdig, rdig_md5);		ne_md5_to_ascii(rdig_md5, rdig_md5_ascii);		NE_DEBUG(NE_DBG_HTTPAUTH, "Calculated response-digest of: "			 "[%s]\n", rdig_md5_ascii);		NE_DEBUG(NE_DBG_HTTPAUTH, "Given response-digest of:      "			 "[%s]\n", rspauth);		/* And... do they match? */		okay = (strcasecmp(rdig_md5_ascii, rspauth) == 0)?0:-1;		NE_DEBUG(NE_DBG_HTTPAUTH, "Matched: %s\n", okay?"nope":"YES!");	    }	}    } else {	NE_DEBUG(NE_DBG_HTTPAUTH, "No qop directive, auth okay.\n");	okay = 0;    }    /* Check for a nextnonce */    if (nextnonce != NULL) {	NE_DEBUG(NE_DBG_HTTPAUTH, "Found nextnonce of [%s].\n", nextnonce);	if (sess->nonce != NULL)	    ne_free(sess->nonce);	sess->nonce = ne_strdup(nextnonce);    }    ne_free(hdr);    return okay;}/* Passed the value of a "(Proxy,WWW)-Authenticate: " header field. * Returns 0 if valid challenge was accepted; non-zero if no valid * challenge was found. */static int auth_challenge(auth_session *sess, const char *value) {    char *pnt, *key, *val, *hdr;    struct auth_challenge *chall = NULL, *challenges = NULL;    int success;    pnt = hdr = ne_strdup(value);     NE_DEBUG(NE_DBG_HTTPAUTH, "Got new auth challenge: %s\n", value);    /* The header value may be made up of one or more challenges.  We     * split it down into attribute-value pairs, then search for     * schemes in the pair keys. */    while (!tokenize(&pnt, &key, &val, 1)) {	if (val == NULL) {	    /* We have a new challenge */	    NE_DEBUG(NE_DBG_HTTPAUTH, "New challenge for scheme [%s]\n", key);	    chall = ne_calloc(sizeof *chall);	    chall->next = challenges;	    challenges = chall;	    /* Initialize the challenge parameters */	    /* Which auth-scheme is it (case-insensitive matching) */	    if (strcasecmp(key, "basic") == 0) {		NE_DEBUG(NE_DBG_HTTPAUTH, "Basic scheme.\n");		chall->scheme = auth_scheme_basic;	    } else if (strcasecmp(key, "digest") == 0) {		NE_DEBUG(NE_DBG_HTTPAUTH, "Digest scheme.\n");		chall->scheme = auth_scheme_digest;#ifdef HAVE_GSSAPI			    } else if (strcasecmp(key, "negotiate") == 0) {		NE_DEBUG(NE_DBG_HTTPAUTH, "GSSAPI scheme.\n");		chall->scheme = auth_scheme_gssapi;#endif	    } else {		NE_DEBUG(NE_DBG_HTTPAUTH, "Unknown scheme.\n");		ne_free(chall);		challenges = NULL;		break;	    }	    continue;	} else if (chall == NULL) {	    /* If we haven't got an auth-scheme, and we're	     * haven't yet found a challenge, skip this pair.	     */	    continue;	}	/* Strip quotes off value. */	val = ne_shave(val, "\"'");	NE_DEBUG(NE_DBG_HTTPAUTH, "Got pair: [%s] = [%s]\n", key, val);	if (strcasecmp(key, "realm") == 0) {	    chall->realm = val;	} else if (strcasecmp(key, "nonce") == 0) {	    chall->nonce = val;	} else if (strcasecmp(key, "opaque") == 0) {	    chall->opaque = val;	} else if (strcasecmp(key, "stale") == 0) {	    /* Truth value */	    chall->stale = (strcasecmp(val, "true") == 0);	} else if (strcasecmp(key, "algorithm") == 0) {	    if (strcasecmp(val, "md5") == 0) {		chall->alg = auth_alg_md5;	    } else if (strcasecmp(val, "md5-sess") == 0) {		chall->alg = auth_alg_md5_sess;	    } else {		chall->alg = auth_alg_unknown;	    }	} else if (strcasecmp(key, "qop") == 0) {            /* iterate over each token in the value */            do {                const char *tok = ne_shave(ne_token(&val, ','), " \t");                                if (strcasecmp(tok, "auth") == 0) {                    chall->qop_auth = 1;                } else if (strcasecmp(tok, "auth-int") == 0 ) {                    chall->qop_auth_int = 1;                }            } while (val);                        chall->got_qop = chall->qop_auth || chall->qop_auth_int;	}    }    NE_DEBUG(NE_DBG_HTTPAUTH, "Finished parsing parameters.\n");    /* Did we find any challenges */    if (challenges == NULL) {	ne_free(hdr);	return -1;    }        success = 0;#ifdef HAVE_GSSAPI    if (strcmp(ne_get_scheme(sess->sess), "https") == 0) {        NE_DEBUG(NE_DBG_HTTPAUTH, "Looking for GSSAPI.\n");        /* Try a GSSAPI challenge */        for (chall = challenges; chall != NULL; chall = chall->next) {            if (chall->scheme == auth_scheme_gssapi) {	    if (!gssapi_challenge(sess, chall)) {		success = 1;		break;	    }            }        }    }#endif    /* Try a digest challenge */    if (!success) {        NE_DEBUG(NE_DBG_HTTPAUTH, "Looking for Digest challenges.\n");        for (chall = challenges; chall != NULL; chall = chall->next) {        	if (chall->scheme == auth_scheme_digest) {        	    if (!digest_challenge(sess, chall)) {        		success = 1;        		break;        	    }        	}        }    }    if (!success) {	NE_DEBUG(NE_DBG_HTTPAUTH, 		 "No good Digest challenges, looking for Basic.\n");	for (chall = challenges; chall != NULL; chall = chall->next) {	    if (chall->scheme == auth_scheme_basic) {		if (!basic_challenge(sess, chall)) {		    success = 1;		    break;		}	    }	}	if (!success) {	    /* No good challenges - record this in the session state */	    NE_DEBUG(NE_DBG_HTTPAUTH, "Did not understand any challenges.\n");	}    }        /* Remember whether we can now supply the auth details */    sess->can_handle = success;    while (challenges != NULL) {	chall = challenges->next;	ne_free(challenges);	challenges = chall;    }    ne_free(hdr);    return !success;}/* The body reader callback. */static void auth_body_reader(void *cookie, const char *block, size_t length){    struct ne_md5_ctx *ctx = cookie;    NE_DEBUG(NE_DBG_HTTPAUTH, 	     "Digesting %" NE_FMT_SIZE_T " bytes of response body.\n", length);    ne_md5_process_bytes(block, length, ctx);}static void ah_create(ne_request *req, void *session, const char *method,		      const char *uri){    auth_session *sess = session;    int is_connect = strcmp(method, "CONNECT") == 0;    if (sess->context == AUTH_ANY ||        (is_connect && sess->context == AUTH_CONNECT) ||        (!is_connect && sess->context == AUTH_NOTCONNECT)) {        struct auth_request *areq = ne_calloc(sizeof *areq);                NE_DEBUG(NE_DBG_HTTPAUTH, "ah_create, for %s\n", sess->spec->resp_hdr);                areq->method = method;        areq->uri = uri;        areq->request = req;                ne_add_response_header_handler(req, sess->spec->resp_hdr,                                       ne_duplicate_header, &areq->auth_hdr);        	        ne_add_response_header_handler(req, sess->spec->resp_info_hdr,                                       ne_duplicate_header,                                        &areq->auth_info_hdr);                sess->attempt = 0;                ne_set_request_private(req, sess->spec->id, areq);    }}static void ah_pre_send(ne_request *r, void *cookie, ne_buffer *request){    auth_session *sess = cookie;    struct auth_request *req = ne_get_request_private(r, sess->spec->id);    if (!sess->can_handle || !req) {	NE_DEBUG(NE_DBG_HTTPAUTH, "Not handling session.\n");    } else {	char *value;	NE_DEBUG(NE_DBG_HTTPAUTH, "Handling.");	req->will_handle = 1;	if (sess->qop == auth_qop_auth_int) {	    /* Digest mode / qop=auth-int: take an MD5 digest of the	     * response body. */	    ne_md5_init_ctx(&req->response_body);	    ne_add_response_body_reader(req->request, ne_accept_always, 					auth_body_reader, &req->response_body);	}		switch(sess->scheme) {	case auth_scheme_basic:	    value = request_basic(sess);	    break;	case auth_scheme_digest:	    value = request_digest(sess, req);	    break;#ifdef HAVE_GSSAPI	    	case auth_scheme_gssapi:	    value = request_gssapi(sess);	    break;#endif	default:	    value = NULL;	    break;	}	if (value != NULL) {	    ne_buffer_concat(request, sess->spec->req_hdr, ": ", value, NULL);	    ne_free(value);	}    }}#define SAFELY(x) ((x) != NULL?(x):"null")static int ah_post_send(ne_request *req, void *cookie, const ne_status *status){    auth_session *sess = cookie;    struct auth_request *areq = ne_get_request_private(req, sess->spec->id);    int ret = NE_OK;    if (!areq) return NE_OK;    NE_DEBUG(NE_DBG_HTTPAUTH, 	     "ah_post_send (#%d), code is %d (want %d), %s is %s\n",	     sess->attempt, status->code, sess->spec->status_code, 	     sess->spec->resp_hdr, SAFELY(areq->auth_hdr));    if (areq->auth_info_hdr != NULL && 	verify_response(areq, sess, areq->auth_info_hdr)) {	NE_DEBUG(NE_DBG_HTTPAUTH, "Response authentication invalid.\n");	ne_set_error(sess->sess, "%s", _(sess->spec->fail_msg));	ret = NE_ERROR;    } else if ((status->code == sess->spec->status_code ||                (status->code == 401 && sess->context == AUTH_CONNECT)) &&	       areq->auth_hdr != NULL) {        /* note above: allow a 401 in response to a CONNECT request         * from a proxy since some buggy proxies send that. */	NE_DEBUG(NE_DBG_HTTPAUTH, "Got challenge with code %d.\n", status->code);	if (!auth_challenge(sess, areq->auth_hdr)) {	    ret = NE_RETRY;	} else {	    clean_session(sess);	    ret = sess->spec->fail_code;	}    }    NE_FREE(areq->auth_info_hdr);    NE_FREE(areq->auth_hdr);        return ret;}static void ah_destroy(ne_request *req, void *session){    auth_session *sess = session;    struct auth_request *areq = ne_get_request_private(req, sess->spec->id);    if (areq) ne_free(areq);}static void free_auth(void *cookie){    auth_session *sess = cookie;    clean_session(sess);    ne_free(sess);}static void auth_register(ne_session *sess, int isproxy,			  const struct auth_class *ahc, const char *id, 			  ne_auth_creds creds, void *userdata) {    auth_session *ahs = ne_calloc(sizeof *ahs);    ahs->creds = creds;    ahs->userdata = userdata;    ahs->sess = sess;    ahs->spec = ahc;    if (strcmp(ne_get_scheme(sess), "https") == 0)        ahs->context = isproxy ? AUTH_CONNECT : AUTH_NOTCONNECT;    else        ahs->context = AUTH_ANY;        /* Register hooks */    ne_hook_create_request(sess, ah_create, ahs);    ne_hook_pre_send(sess, ah_pre_send, ahs);    ne_hook_post_send(sess, ah_post_send, ahs);    ne_hook_destroy_request(sess, ah_destroy, ahs);    ne_hook_destroy_session(sess, free_auth, ahs);    ne_set_session_private(sess, id, ahs);}void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userdata){    auth_register(sess, 0, &ah_server_class, HOOK_SERVER_ID, creds, userdata);}void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata){    auth_register(sess, 1, &ah_proxy_class, HOOK_PROXY_ID, creds, userdata);}void ne_forget_auth(ne_session *sess){    auth_session *as;    if ((as = ne_get_session_private(sess, HOOK_SERVER_ID)) != NULL)	clean_session(as);    if ((as = ne_get_session_private(sess, HOOK_PROXY_ID)) != NULL)	clean_session(as);}

⌨️ 快捷键说明

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