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

📄 auth_ntlm.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (auth_user_request->scheme_data)	authNTLMRequestFree((ntlm_request_t *) auth_user_request->scheme_data);    auth_user_request->scheme_data = NULL;}static voidauthenticateNTLMFreeUser(auth_user_t * auth_user){    ntlm_user_t *ntlm_user = auth_user->scheme_data;    debug(29, 5) ("authenticateNTLMFreeUser: Clearing NTLM scheme data\n");    safe_free(ntlm_user->username);    memPoolFree(ntlm_user_pool, ntlm_user);    auth_user->scheme_data = NULL;}/* clear the NTLM helper of being reserved for future requests */static voidauthenticateNTLMReleaseServer(ntlm_request_t * ntlm_request){    helper_stateful_server *server = ntlm_request->authserver;    if (!server)	return;    debug(29, 9) ("authenticateNTLMReleaseServer: releasing server '%p'\n", server);    ntlm_request->authserver = NULL;    helperStatefulReleaseServer(server);}static voidauthenticateNTLMHandleReply(void *data, void *srv, char *reply){    authenticateStateData *r = data;    int valid;    auth_user_request_t *auth_user_request;    auth_user_t *auth_user;    ntlm_user_t *ntlm_user;    ntlm_request_t *ntlm_request;    char *blob;    debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%p' {%s}\n", srv, reply ? reply : "<NULL>");    valid = cbdataValid(r->data);    if (!valid) {	debug(29, 2) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%p'.\n", srv);	ntlm_request = r->auth_user_request->scheme_data;	if (ntlm_request != NULL) {	    if (ntlm_request->authserver == NULL)		ntlm_request->authserver = srv;	    authenticateNTLMReleaseServer(ntlm_request);	}	cbdataUnlock(r->data);	authenticateStateFree(r);	return;    }    if (!reply) {	debug(29, 1) ("AuthenticateNTLMHandleReply: Helper '%p' crashed!.\n", srv);	reply = (char *) "BH Internal error";    }    auth_user_request = r->auth_user_request;    ntlm_request = auth_user_request->scheme_data;    assert(ntlm_request != NULL);    assert(ntlm_request->waiting);    ntlm_request->waiting = 0;    safe_free(ntlm_request->client_blob);    auth_user = auth_user_request->auth_user;    assert(auth_user != NULL);    assert(auth_user->auth_type == AUTH_NEGOTIATE);    ntlm_user = auth_user_request->auth_user->scheme_data;    if (ntlm_request->authserver == NULL)	ntlm_request->authserver = srv;    else	assert(ntlm_request->authserver == srv);    /* seperate out the useful data */    blob = strchr(reply, ' ');    if (blob) {	blob++;    }    if (strncasecmp(reply, "TT ", 3) == 0) {	/* we have been given a blob to send to the client */	safe_free(ntlm_request->server_blob);	ntlm_request->server_blob = xstrdup(blob);	ntlm_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE;	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup("Authentication in progress");	debug(29, 4) ("authenticateNTLMHandleReply: Need to challenge the client with a server blob '%s'\n", blob);    } else if (strncasecmp(reply, "AF ", 3) == 0) {	/* we're finished, release the helper */	safe_free(ntlm_user->username);	ntlm_user->username = xstrdup(blob);	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup("Login successful");	debug(29, 4) ("authenticateNTLMHandleReply: Successfully validated user via NTLM. Username '%s'\n", blob);	authenticateNTLMReleaseServer(ntlm_request);	ntlm_request->auth_state = AUTHENTICATE_STATE_FINISHED;    } else if (strncasecmp(reply, "NA ", 3) == 0) {	safe_free(auth_user_request->message);	auth_user_request->message = xstrdup(blob);	ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED;	authenticateNTLMReleaseServer(ntlm_request);	debug(29, 4) ("authenticateNTLMHandleReply: Failed validating user via NTLM. Error returned '%s'\n", blob);    } 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 NTLM 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);	ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED;	safe_free(ntlm_request->server_blob);	authenticateNTLMReleaseServer(ntlm_request);	debug(29, 1) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply);    } else {	fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply);    }    r->handler(r->data, NULL);    cbdataUnlock(r->data);    authenticateStateFree(r);}static voidauthenticateNTLMStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "NTLM Authenticator Statistics:\n");    helperStatefulStats(sentry, ntlmauthenticators);}/* send the initial data to a stateful ntlm authenticator module */static voidauthenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, void *data){    authenticateStateData *r = NULL;    char buf[8192];    char *sent_string = NULL;    ntlm_user_t *ntlm_user;    ntlm_request_t *ntlm_request;    auth_user_t *auth_user;    assert(auth_user_request);    auth_user = auth_user_request->auth_user;    ntlm_user = auth_user->scheme_data;    ntlm_request = auth_user_request->scheme_data;    assert(ntlm_user);    assert(ntlm_request);    assert(handler);    assert(data);    assert(auth_user->auth_type == AUTH_NEGOTIATE);    debug(29, 9) ("authenticateNTLMStart: auth state '%d'\n", ntlm_request->auth_state);    sent_string = ntlm_request->client_blob;    debug(29, 9) ("authenticateNTLMStart: state '%d'\n", ntlm_request->auth_state);    debug(29, 9) ("authenticateNTLMStart: '%s'\n", sent_string);    if (ntlmConfig->authenticate == NULL) {	debug(29, 0) ("authenticateNTLMStart: no NTLM 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 (ntlm_request->auth_state == AUTHENTICATE_STATE_INITIAL) {	snprintf(buf, 8192, "YR %s\n", sent_string);    } else {	snprintf(buf, 8192, "KK %s\n", sent_string);    }    ntlm_request->waiting = 1;    safe_free(ntlm_request->client_blob);    helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authserver);}/* clear any connection related authentication details */static voidauthenticateNTLMOnCloseConnection(ConnStateData * conn){    ntlm_request_t *ntlm_request;    assert(conn != NULL);    if (conn->auth_user_request != NULL) {	assert(conn->auth_user_request->scheme_data != NULL);	ntlm_request = conn->auth_user_request->scheme_data;	assert(ntlm_request->conn == conn);	if (ntlm_request->authserver != NULL)	    authenticateNTLMReleaseServer(ntlm_request);	/* unlock the connection based lock */	debug(29, 9) ("authenticateNTLMOnCloseConnection: 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 *authenticateNTLMUsername(auth_user_t * auth_user){    ntlm_user_t *ntlm_user = auth_user->scheme_data;    if (ntlm_user)	return ntlm_user->username;    return NULL;}/* * Called on the initial request only, to set things up for later processing */static voidauthenticateDecodeNTLMAuth(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("ntlm");    auth_user_request->auth_user->auth_type = AUTH_NEGOTIATE;    auth_user_request->auth_user->scheme_data = memPoolAlloc(ntlm_user_pool);    auth_user_request->scheme_data = memPoolAlloc(ntlm_request_pool);    memset(auth_user_request->scheme_data, '\0', sizeof(ntlm_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     * authenticateNTLMAuthenticateUser */    debug(29, 9) ("authenticateDecodeNTLMAuth: NTLM authentication\n");    return;}static intauthenticateNTLMcmpUsername(ntlm_user_t * u1, ntlm_user_t * u2){    return strcmp(u1->username, u2->username);}static intauthNTLMAuthenticated(auth_user_request_t * auth_user_request){    ntlm_request_t *ntlm_request = auth_user_request->scheme_data;    if (ntlm_request->auth_state == AUTHENTICATE_STATE_FINISHED)	return 1;    debug(29, 9) ("User not fully authenticated.\n");    return 0;}static voidauthenticateNTLMAuthenticateUser(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;    ntlm_request_t *ntlm_request;    ntlm_user_t *ntlm_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);    ntlm_user = auth_user->scheme_data;    ntlm_request = auth_user_request->scheme_data;    /* Check that we are in the client side, where we can generate     * auth challenges */    if (!conn) {	ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED;	debug(29, 1) ("authenticateNTLMAuthenticateUser: attempt to perform authentication without a connection!\n");	return;    }    if (ntlm_request->waiting) {	debug(29, 1) ("authenticateNTLMAuthenticateUser: waiting for helper reply!\n");	return;    }    if (ntlm_request->server_blob) {	debug(29, 2) ("authenticateNTLMAuthenticateUser: need to challenge client '%s'!\n", ntlm_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 (ntlm_request->auth_state) {    case AUTHENTICATE_STATE_NONE:	/* we've recieved a ntlm request. pass to a helper */	debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n", proxy_auth);	ntlm_request->auth_state = AUTHENTICATE_STATE_INITIAL;	safe_free(ntlm_request->client_blob);	ntlm_request->client_blob = xstrdup(blob);	conn->auth_type = AUTH_NEGOTIATE;	conn->auth_user_request = auth_user_request;	ntlm_request->conn = conn;	/* and lock for the connection duration */	debug(29, 9) ("authenticateNTLMAuthenticateUser: Locking auth_user from the connection.\n");	authenticateAuthUserRequestLock(auth_user_request);	return;	break;    case AUTHENTICATE_STATE_INITIAL:	debug(29, 1) ("authenticateNTLMAuthenticateUser: 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) ("authenticateNTLMAuthenticateUser: auth state challenge with header %s.\n", proxy_auth);	/* do a cache lookup here. If it matches it's a successful ntlm 	 * challenge - release the helper and use the existing auth_user 	 * details. */	safe_free(ntlm_request->client_blob);	ntlm_request->client_blob = xstrdup(blob);	return;	break;    case AUTHENTICATE_STATE_FINISHED:	/* this connection is authenticated */	debug(29, 4) ("authenticated user %s\n", ntlm_user->username);	/* see if this is an existing user with a different proxy_auth 	 * string */	usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username);	if (usernamehash) {	    while (usernamehash && (usernamehash->auth_user->auth_type != auth_user->auth_type || authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_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;	authenticateNTLMReleaseServer(ntlm_request);	ntlm_request->auth_state = AUTHENTICATE_STATE_DONE;	return;    case AUTHENTICATE_STATE_DONE:	fatal("authenticateNTLMAuthenticateUser: 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) ("authenticateNTLMAuthenticateUser: auth state ntlm failed. %s\n", proxy_auth);	return;    }    return;}

⌨️ 快捷键说明

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