Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/* 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;
}