static void authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request) { int i = 0; assert(proxy_auth != NULL); assert(auth_user_request != NULL); /* we need this created for us. */ debug(29, 9) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth); if (authenticateAuthSchemeConfigured(proxy_auth)) { /* we're configured to use this scheme - but is it active ? */ if ((i = authenticateAuthSchemeId(proxy_auth)) != -1) { authscheme_list[i].decodeauth(auth_user_request, proxy_auth); if (auth_user_request->auth_user) { auth_user_request->auth_user->auth_module = i + 1; } else { debug(29, 1) ("authenticateDecodeAuth: Invalid proxy-auth header, '%s'\n", proxy_auth); } return; } } debug(29, 1) ("authenticateDecodeAuth: Unsupported or unconfigured proxy-auth scheme, '%s'\n", proxy_auth); return; }
auth_user_t * authenticateAuthUserNew(const char *scheme) { auth_user_t *temp_auth; temp_auth = memAllocate(MEM_AUTH_USER_T); assert(temp_auth != NULL); memset(temp_auth, '\0', sizeof(auth_user_t)); temp_auth->auth_type = AUTH_UNKNOWN; temp_auth->references = 0; temp_auth->auth_module = authenticateAuthSchemeId(scheme) + 1; temp_auth->usernamehash = NULL; return temp_auth; }
/* returns one of * AUTH_ACL_CHALLENGE, * AUTH_ACL_HELPER, * AUTH_ACL_CANNOT_AUTHENTICATE, * AUTH_AUTHENTICATED * * How to use: In your proxy-auth dependent acl code, use the following * construct: * int rv; * if ((rv = AuthenticateAuthenticate()) != AUTH_AUTHENTICATED) * return rv; * * when this code is reached, the request/connection is authenticated. * * if you have non-acl code, but want to force authentication, you need a * callback mechanism like the acl testing routines that will send a 40[1|7] to * the client when rv==AUTH_ACL_CHALLENGE, and will communicate with * the authenticateStart routine for rv==AUTH_ACL_HELPER */ auth_acl_t authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t * request, ConnStateData * conn, struct in_addr src_addr) { const char *proxy_auth; assert(headertype != 0); proxy_auth = httpHeaderGetStr(&request->header, headertype); /* * a note on proxy_auth logix here: * proxy_auth==NULL -> unauthenticated request || already * authenticated connection so we test for an authenticated * connection when we recieve no authentication header. */ if (((proxy_auth == NULL) && (!authenticateUserAuthenticated(authTryGetUser(auth_user_request, conn, request)))) || (conn && conn->auth_type == AUTH_BROKEN)) { /* no header or authentication failed/got corrupted - restart */ if (conn) conn->auth_type = AUTH_UNKNOWN; debug(29, 4) ("authenticateAuthenticate: broken auth or no proxy_auth header. Requesting auth header.\n"); /* something wrong with the AUTH credentials. Force a new attempt */ if (conn && conn->auth_user_request) { authenticateAuthUserRequestUnlock(conn->auth_user_request); conn->auth_user_request = NULL; } if (*auth_user_request) { /* unlock the ACL lock */ authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; } return AUTH_ACL_CHALLENGE; } #if 0 /* * Is this an already authenticated connection with a new auth header? * No check for function required in the if: its compulsory for conn based * auth modules */ if (proxy_auth && conn && conn->auth_user_request && authenticateUserAuthenticated(conn->auth_user_request) && strcmp(proxy_auth, authscheme_list[conn->auth_user_request->auth_user->auth_module - 1].authConnLastHeader(conn->auth_user_request))) { debug(29, 2) ("authenticateAuthenticate: DUPLICATE AUTH - authentication header on already authenticated connection!. AU %p, Current user '%s' proxy_auth %s\n", conn->auth_user_request, authenticateUserRequestUsername(conn->auth_user_request), proxy_auth); /* remove this request struct - the link is already authed and it can't be to * reauth. */ /* This should _only_ ever occur on the first pass through * authenticateAuthenticate */ assert(*auth_user_request == NULL); /* unlock the conn lock on the auth_user_request */ authenticateAuthUserRequestUnlock(conn->auth_user_request); /* mark the conn as non-authed. */ conn->auth_user_request = NULL; /* Set the connection auth type */ conn->auth_type = AUTH_UNKNOWN; } #endif /* we have a proxy auth header and as far as we know this connection has * not had bungled connection oriented authentication happen on it. */ debug(29, 9) ("authenticateAuthenticate: header %s.\n", proxy_auth ? proxy_auth : NULL); if (*auth_user_request == NULL) { debug(29, 9) ("authenticateAuthenticate: This is a new checklist test on FD:%d\n", conn ? conn->fd : -1); if (proxy_auth && !request->auth_user_request && conn && conn->auth_user_request) { int id = authenticateAuthSchemeId(proxy_auth) + 1; if (!conn->auth_user_request->auth_user || conn->auth_user_request->auth_user->auth_module != id) { debug(29, 1) ("authenticateAuthenticate: Unexpected change of authentication scheme from '%s' to '%s' (client %s)\n", authscheme_list[conn->auth_user_request->auth_user->auth_module - 1].typestr, proxy_auth, inet_ntoa(src_addr)); authenticateAuthUserRequestUnlock(conn->auth_user_request); conn->auth_user_request = NULL; conn->auth_type = AUTH_UNKNOWN; } } if ((!request->auth_user_request) && (!conn || conn->auth_type == AUTH_UNKNOWN)) { /* beginning of a new request check */ debug(29, 4) ("authenticateAuthenticate: no connection authentication type\n"); if (!authenticateValidateUser(*auth_user_request = authenticateGetAuthUser(proxy_auth))) { /* the decode might have left a username for logging, or a message to * the user */ if (authenticateUserRequestUsername(*auth_user_request)) { /* lock the user for the request structure link */ authenticateAuthUserRequestLock(*auth_user_request); request->auth_user_request = *auth_user_request; } /* unlock the ACL reference granted by ...GetAuthUser. */ authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; return AUTH_ACL_CHALLENGE; } /* the user_request comes prelocked for the caller to GetAuthUser (us) */ } else if (request->auth_user_request) { *auth_user_request = request->auth_user_request; /* lock the user request for this ACL processing */ authenticateAuthUserRequestLock(*auth_user_request); } else { assert(conn); if (conn->auth_user_request != NULL) { *auth_user_request = conn->auth_user_request; /* lock the user request for this ACL processing */ authenticateAuthUserRequestLock(*auth_user_request); } else { /* failed connection based authentication */ debug(29, 4) ("authenticateAuthenticate: Auth user request %p conn-auth user request %p conn type %d authentication failed.\n", *auth_user_request, conn->auth_user_request, conn->auth_type); if (*auth_user_request) { authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; } return AUTH_ACL_CHALLENGE; } } } if (!authenticateUserAuthenticated(*auth_user_request)) { /* User not logged in. Log them in */ authenticateAuthenticateUser(*auth_user_request, request, conn, headertype); switch (authenticateDirection(*auth_user_request)) { case 1: if (!request->auth_user_request) { /* lock the user for the request structure link */ authenticateAuthUserRequestLock(*auth_user_request); request->auth_user_request = *auth_user_request; } /* fallthrough to -2 */ case -2: /* this ACL check is finished. Unlock. */ authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; return AUTH_ACL_CHALLENGE; case -1: /* we are partway through authentication within squid, * the *auth_user_request variables stores the auth_user_request * for the callback to here - Do not Unlock */ return AUTH_ACL_HELPER; } /* on 0 the authentication is finished - fallthrough */ /* See if user authentication failed for some reason */ if (!authenticateUserAuthenticated(*auth_user_request)) { if ((authenticateUserRequestUsername(*auth_user_request))) { if (!request->auth_user_request) { /* lock the user for the request structure link */ authenticateAuthUserRequestLock(*auth_user_request); request->auth_user_request = *auth_user_request; } } /* this ACL check is finished. Unlock. */ authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; return AUTH_ACL_CHALLENGE; } } /* copy username to request for logging on client-side */ /* the credentials are correct at this point */ if (!request->auth_user_request) { /* lock the user for the request structure link */ authenticateAuthUserRequestLock(*auth_user_request); request->auth_user_request = *auth_user_request; authenticateAuthUserRequestSetIp(*auth_user_request, src_addr, request); } /* Unlock the request - we've authenticated it */ authenticateAuthUserRequestUnlock(*auth_user_request); *auth_user_request = NULL; return AUTH_AUTHENTICATED; }