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

📄 auth_negotiate.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 2 页
字号:
	debug(29, 9) ("authenticateNegotiateRequestFree: releasing server '%p'\n", negotiate_request->authserver);	authenticateNegotiateReleaseServer(negotiate_request);    }    memPoolFree(negotiate_request_pool, negotiate_request);}static voidauthNegotiateAURequestFree(auth_user_request_t * auth_user_request){    if (auth_user_request->scheme_data)	authNegotiateRequestFree((negotiate_request_t *) auth_user_request->scheme_data);    auth_user_request->scheme_data = NULL;}static voidauthenticateNegotiateFreeUser(auth_user_t * auth_user){    negotiate_user_t *negotiate_user = auth_user->scheme_data;    debug(29, 5) ("authenticateNegotiateFreeUser: Clearing Negotiate scheme data\n");    safe_free(negotiate_user->username);    memPoolFree(negotiate_user_pool, negotiate_user);    auth_user->scheme_data = NULL;}/* clear the Negotiate helper of being reserved for future requests */static voidauthenticateNegotiateReleaseServer(negotiate_request_t * negotiate_request){    helper_stateful_server *server = negotiate_request->authserver;    if (!server)	return;    debug(29, 9) ("authenticateNegotiateReleaseServer: releasing server '%p'\n", server);    negotiate_request->authserver = NULL;    helperStatefulReleaseServer(server);}static voidauthenticateNegotiateHandleReply(void *data, void *srv, char *reply){    authenticateStateData *r = data;    int valid;    auth_user_request_t *auth_user_request;    auth_user_t *auth_user;    negotiate_user_t *negotiate_user;    negotiate_request_t *negotiate_request;    char *blob, *arg;    debug(29, 9) ("authenticateNegotiateHandleReply: Helper: '%p' {%s}\n", srv, reply ? reply : "<NULL>");    valid = cbdataValid(r->data);    if (!valid) {	debug(29, 2) ("AuthenticateNegotiateHandleReply: invalid callback data. Releasing helper '%p'.\n", srv);	negotiate_request = r->auth_user_request->scheme_data;	if (negotiate_request != NULL) {	    if (negotiate_request->authserver == NULL)		negotiate_request->authserver = srv;	    authenticateNegotiateReleaseServer(negotiate_request);	}	cbdataUnlock(r->data);	authenticateStateFree(r);	return;    }    if (!reply) {	debug(29, 1) ("AuthenticateNegotiateHandleReply: Helper '%p' crashed!.\n", srv);	reply = (char *) "BH Internal error";    }    auth_user_request = r->auth_user_request;    negotiate_request = auth_user_request->scheme_data;    assert(negotiate_request != NULL);    assert(negotiate_request->waiting);    negotiate_request->waiting = 0;    safe_free(negotiate_request->client_blob);    auth_user = auth_user_request->auth_user;    assert(auth_user != NULL);    assert(auth_user->auth_type == AUTH_NEGOTIATE);    negotiate_user = auth_user_request->auth_user->scheme_data;    if (negotiate_request->authserver == NULL)	negotiate_request->authserver = srv;    else	assert(negotiate_request->authserver == srv);    /* seperate out the useful data */    blob = strchr(reply, ' ');    if (blob) {	blob++;	arg = strchr(blob + 1, ' ');    } else {	arg = NULL;    }    if (strncasecmp(reply, "TT ", 3) == 0) {	/* we have been given a blob to send to the client */	if (arg)	    *arg++ = '\0';	safe_free(negotiate_request->server_blob);	negotiate_request->server_blob = xstrdup(blob);	negotiate_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE;	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup("Authentication in progress");	debug(29, 4) ("authenticateNegotiateHandleReply: Need to challenge the client with a server blob '%s'\n", blob);    } else if (strncasecmp(reply, "AF ", 3) == 0 && arg != NULL) {	/* we're finished, release the helper */	if (arg)	    *arg++ = '\0';	safe_free(negotiate_user->username);	negotiate_user->username = xstrdup(arg);	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup("Login successful");	safe_free(negotiate_request->server_blob);	negotiate_request->server_blob = xstrdup(blob);	debug(29, 4) ("authenticateNegotiateHandleReply: Successfully validated user via Negotiate. Username '%s'\n", arg);	authenticateNegotiateReleaseServer(negotiate_request);	negotiate_request->auth_state = AUTHENTICATE_STATE_FINISHED;    } else if (strncasecmp(reply, "NA ", 3) == 0 && arg != NULL) {	if (arg)	    *arg++ = '\0';	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup(arg);	negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED;	safe_free(negotiate_request->server_blob);	negotiate_request->server_blob = xstrdup(blob);	authenticateNegotiateReleaseServer(negotiate_request);	debug(29, 4) ("authenticateNegotiateHandleReply: Failed validating user via Negotiate. Error returned '%s'\n", arg);    } else if (strncasecmp(reply, "BH ", 3) == 0) {	/* TODO kick off a refresh process. This can occur after a YR or after	 * a KK. If after a YR release the helper and resubmit the request via 	 * Authenticate Negotiate start. 	 * If after a KK deny the user's request w/ 407 and mark the helper as 	 * Needing YR. */	auth_user_request->message = xstrdup(blob);	negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED;	safe_free(negotiate_request->server_blob);	authenticateNegotiateReleaseServer(negotiate_request);	debug(29, 1) ("authenticateNegotiateHandleReply: Error validating user via Negotiate. Error returned '%s'\n", reply);    } else {	fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply);    }    r->handler(r->data, NULL);    cbdataUnlock(r->data);    authenticateStateFree(r);}static voidauthenticateNegotiateStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "Negotiate Authenticator Statistics:\n");    helperStatefulStats(sentry, negotiateauthenticators);}/* send the initial data to a stateful negotiate authenticator module */static voidauthenticateNegotiateStart(auth_user_request_t * auth_user_request, RH * handler, void *data){    authenticateStateData *r = NULL;    char buf[8192];    char *sent_string = NULL;    negotiate_user_t *negotiate_user;    negotiate_request_t *negotiate_request;    auth_user_t *auth_user;    assert(auth_user_request);    auth_user = auth_user_request->auth_user;    negotiate_user = auth_user->scheme_data;    negotiate_request = auth_user_request->scheme_data;    assert(negotiate_user);    assert(negotiate_request);    assert(handler);    assert(data);    assert(auth_user->auth_type == AUTH_NEGOTIATE);    debug(29, 9) ("authenticateNegotiateStart: auth state '%d'\n", negotiate_request->auth_state);    sent_string = negotiate_request->client_blob;    debug(29, 9) ("authenticateNegotiateStart: state '%d'\n", negotiate_request->auth_state);    debug(29, 9) ("authenticateNegotiateStart: '%s'\n", sent_string);    if (negotiateConfig->authenticate == NULL) {	debug(29, 0) ("authenticateNegotiateStart: no Negotiate program specified:'%s'\n", sent_string);	handler(data, NULL);	return;    }    /* Send blob to helper */    r = cbdataAlloc(authenticateStateData);    r->handler = handler;    cbdataLock(data);    r->data = data;    r->auth_user_request = auth_user_request;    authenticateAuthUserRequestLock(r->auth_user_request);    if (negotiate_request->auth_state == AUTHENTICATE_STATE_INITIAL)	snprintf(buf, 8192, "YR %s\n", sent_string);    else	snprintf(buf, 8192, "KK %s\n", sent_string);    negotiate_request->waiting = 1;    safe_free(negotiate_request->client_blob);    helperStatefulSubmit(negotiateauthenticators, buf, authenticateNegotiateHandleReply, r, negotiate_request->authserver);}/* clear any connection related authentication details */static voidauthenticateNegotiateOnCloseConnection(ConnStateData * conn){    negotiate_request_t *negotiate_request;    assert(conn != NULL);    if (conn->auth_user_request != NULL) {	assert(conn->auth_user_request->scheme_data != NULL);	negotiate_request = conn->auth_user_request->scheme_data;	assert(negotiate_request->conn == conn);	if (negotiate_request->authserver != NULL)	    authenticateNegotiateReleaseServer(negotiate_request);	/* unlock the connection based lock */	debug(29, 9) ("authenticateNegotiateOnCloseConnection: Unlocking auth_user from the connection.\n");	/* minor abstraction break here: FIXME */	/* Ensure that the auth user request will be getting closed */	/* IFF we start persisting the struct after the conn closes - say for logging	 * then this test may become invalid	 */	assert(conn->auth_user_request->references == 1);	authenticateAuthUserRequestUnlock(conn->auth_user_request);	conn->auth_user_request = NULL;    }}/* authenticateUserUsername: return a pointer to the username in the */static char *authenticateNegotiateUsername(auth_user_t * auth_user){    negotiate_user_t *negotiate_user = auth_user->scheme_data;    if (negotiate_user)	return negotiate_user->username;    return NULL;}/* * Called on the initial request only, to set things up for later processing */static voidauthenticateDecodeNegotiateAuth(auth_user_request_t * auth_user_request, const char *proxy_auth){    dlink_node *node;    assert(auth_user_request->auth_user == NULL);    auth_user_request->auth_user = authenticateAuthUserNew("negotiate");    auth_user_request->auth_user->auth_type = AUTH_NEGOTIATE;    auth_user_request->auth_user->scheme_data = memPoolAlloc(negotiate_user_pool);    auth_user_request->scheme_data = memPoolAlloc(negotiate_request_pool);    memset(auth_user_request->scheme_data, '\0', sizeof(negotiate_request_t));    /* lock for the auth_user_request link */    authenticateAuthUserLock(auth_user_request->auth_user);    node = dlinkNodeNew();    dlinkAdd(auth_user_request, node, &auth_user_request->auth_user->requests);    /* the helper does the rest, with data collected in     * authenticateNegotiateAuthenticateUser */    debug(29, 9) ("authenticateDecodeNegotiateAuth: Negotiate authentication\n");    return;}static intauthenticateNegotiatecmpUsername(negotiate_user_t * u1, negotiate_user_t * u2){    return strcmp(u1->username, u2->username);}static intauthNegotiateAuthenticated(auth_user_request_t * auth_user_request){    negotiate_request_t *negotiate_request = auth_user_request->scheme_data;    if (negotiate_request->auth_state == AUTHENTICATE_STATE_FINISHED)	return 1;    debug(29, 9) ("User not fully authenticated.\n");    return 0;}static voidauthenticateNegotiateAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type){    const char *proxy_auth, *blob;    auth_user_hash_pointer *usernamehash;    auth_user_t *auth_user;    negotiate_request_t *negotiate_request;    negotiate_user_t *negotiate_user;    auth_user = auth_user_request->auth_user;    assert(auth_user);    assert(auth_user->auth_type == AUTH_NEGOTIATE);    assert(auth_user->scheme_data != NULL);    assert(auth_user_request->scheme_data != NULL);    negotiate_user = auth_user->scheme_data;    negotiate_request = auth_user_request->scheme_data;    /* Check that we are in the client side, where we can generate     * auth challenges */    if (!conn) {	negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED;	debug(29, 1) ("authenticateNegotiateAuthenticateUser: attempt to perform authentication without a connection!\n");	return;    }    if (negotiate_request->waiting) {	debug(29, 1) ("authenticateNegotiateAuthenticateUser: waiting for helper reply!\n");	return;    }    if (negotiate_request->server_blob) {	debug(29, 2) ("authenticateNegotiateAuthenticateUser: need to challenge client '%s'!\n", negotiate_request->server_blob);	return;    }    /* get header */    proxy_auth = httpHeaderGetStr(&request->header, type);    blob = proxy_auth;    while (xisspace(*blob) && *blob)	blob++;    while (!xisspace(*blob) && *blob)	blob++;    while (xisspace(*blob) && *blob)	blob++;    switch (negotiate_request->auth_state) {    case AUTHENTICATE_STATE_NONE:	/* we've recieved a negotiate request. pass to a helper */	debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state negotiate none. %s\n", proxy_auth);	negotiate_request->auth_state = AUTHENTICATE_STATE_INITIAL;	safe_free(negotiate_request->client_blob);	negotiate_request->client_blob = xstrdup(blob);	conn->auth_type = AUTH_NEGOTIATE;	conn->auth_user_request = auth_user_request;	negotiate_request->conn = conn;	/* and lock for the connection duration */	debug(29, 9) ("authenticateNegotiateAuthenticateUser: Locking auth_user from the connection.\n");	authenticateAuthUserRequestLock(auth_user_request);	return;	break;    case AUTHENTICATE_STATE_INITIAL:	debug(29, 1) ("authenticateNegotiateAuthenticateUser: need to ask helper!\n");	return;	break;    case AUTHENTICATE_STATE_NEGOTIATE:	/* we should have recieved a blob from the clien. pass it to the same 	 * helper process */	debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state challenge with header %s.\n", proxy_auth);	/* do a cache lookup here. If it matches it's a successful negotiate 	 * challenge - release the helper and use the existing auth_user 	 * details. */	safe_free(negotiate_request->client_blob);	negotiate_request->client_blob = xstrdup(blob);	return;	break;    case AUTHENTICATE_STATE_FINISHED:	/* this connection is authenticated */	debug(29, 4) ("authenticated user %s\n", negotiate_user->username);	/* see if this is an existing user with a different proxy_auth 	 * string */	usernamehash = hash_lookup(proxy_auth_username_cache, negotiate_user->username);	if (usernamehash) {	    while (usernamehash && (usernamehash->auth_user->auth_type != auth_user->auth_type || authenticateNegotiatecmpUsername(usernamehash->auth_user->scheme_data, negotiate_user) != 0))		usernamehash = usernamehash->next;	}	if (usernamehash) {	    /* we can't seamlessly recheck the username due to the 	     * challenge nature of the protocol. Just free the 	     * temporary auth_user */	    authenticateAuthUserMerge(auth_user, usernamehash->auth_user);	    auth_user = usernamehash->auth_user;	    auth_user_request->auth_user = auth_user;	} else {	    /* store user in hash's */	    authenticateUserNameCacheAdd(auth_user);	}	/* set these to now because this is either a new login from an 	 * existing user or a new user */	auth_user->expiretime = current_time.tv_sec;	authenticateNegotiateReleaseServer(negotiate_request);	negotiate_request->auth_state = AUTHENTICATE_STATE_DONE;	return;    case AUTHENTICATE_STATE_DONE:	fatal("authenticateNegotiateAuthenticateUser: unexpect auth state DONE! Report a bug to the squid developers.\n");	break;    case AUTHENTICATE_STATE_FAILED:	/* we've failed somewhere in authentication */	debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state negotiate failed. %s\n", proxy_auth);	return;    }    return;}

⌨️ 快捷键说明

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