?? auth_negotiate.c
字號:
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->request->flags.must_keepalive = 1; if (negotiate_request->request->flags.proxy_keepalive) { 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 { negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; safe_free(auth_user_request->message); auth_user_request->message = xstrdup("NTLM authentication requires a persistent connection"); } } else if (strncasecmp(reply, "AF ", 3) == 0 && arg != NULL) { auth_user_hash_pointer *usernamehash; /* 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); /* 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; } 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); } requestUnlink(negotiate_request->request); negotiate_request->request = NULL; 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_DONE) 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_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 received 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); negotiate_request->request = requestLink(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 received 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); if (negotiate_request->request) requestUnlink(negotiate_request->request); negotiate_request->request = requestLink(request); return; break; 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 + -