]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/auth/Acl.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / auth / Acl.cc
index b8665c2b08895f29410d44b08877fb9e94e19ad3..ceb1e2eb97fdea09d04cbda41b602d75d1b59634 100644 (file)
@@ -1,78 +1,90 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
 #include "squid.h"
 #include "acl/Acl.h"
 #include "acl/FilledChecklist.h"
-#include "auth/UserRequest.h"
 #include "auth/Acl.h"
 #include "auth/AclProxyAuth.h"
+#include "auth/UserRequest.h"
+#include "client_side.h"
+#include "fatal.h"
+#include "http/Stream.h"
 #include "HttpRequest.h"
 
-/** retval -1 user not authenticated (authentication error?)
-    retval  0 user not authorized OR user authentication is in pgrogress
-    retval +1 user authenticated and authorized */
-int
+/**
+ * \retval ACCESS_AUTH_REQUIRED credentials missing. challenge required.
+ * \retval ACCESS_DENIED        user not authenticated (authentication error?)
+ * \retval ACCESS_DUNNO         user authentication is in progress
+ * \retval ACCESS_DENIED        user not authorized
+ * \retval ACCESS_ALLOWED       user authenticated and authorized
+ */
+allow_t
 AuthenticateAcl(ACLChecklist *ch)
 {
-       ACLFilledChecklist *checklist = Filled(ch);
-       HttpRequest *request = checklist->request;
-    http_hdr_type headertype;
+    ACLFilledChecklist *checklist = Filled(ch);
+    HttpRequest *request = checklist->request;
+    Http::HdrType headertype;
 
     if (NULL == request) {
         fatal ("requiresRequest SHOULD have been true for this ACL!!");
-        return 0;
+        return ACCESS_DENIED;
+    } else if (request->flags.sslBumped) {
+        debugs(28, 5, "SslBumped request: It is an encapsulated request do not authenticate");
+        checklist->auth_user_request = checklist->conn() != NULL ? checklist->conn()->getAuth() : request->auth_user_request;
+        if (checklist->auth_user_request != NULL)
+            return ACCESS_ALLOWED;
+        else
+            return ACCESS_DENIED;
     } else if (request->flags.accelerated) {
         /* WWW authorization on accelerated requests */
-        headertype = HDR_AUTHORIZATION;
-    } else if (request->flags.intercepted || request->flags.spoof_client_ip) {
-        debugs(28, DBG_IMPORTANT, HERE << " authentication not applicable on intercepted requests.");
-        return -1;
+        headertype = Http::HdrType::AUTHORIZATION;
+    } else if (request->flags.intercepted || request->flags.interceptTproxy) {
+        debugs(28, DBG_IMPORTANT, "NOTICE: Authentication not applicable on intercepted requests.");
+        return ACCESS_DENIED;
     } else {
         /* Proxy authorization on proxy requests */
-        headertype = HDR_PROXY_AUTHORIZATION;
+        headertype = Http::HdrType::PROXY_AUTHORIZATION;
     }
 
     /* get authed here */
     /* Note: this fills in auth_user_request when applicable */
-    /*
-     * DPW 2007-05-08
-     * tryToAuthenticateAndSetAuthUser used to try to lock and
-     * unlock auth_user_request on our behalf, but it was too
-     * ugly and hard to follow.  Now we do our own locking here.
-     *
-     * I'm not sure what tryToAuthenticateAndSetAuthUser does when
-     * auth_user_request is set before calling.  I'm tempted to
-     * unlock and set it to NULL, but it seems safer to save the
-     * pointer before calling and unlock it afterwards.  If the
-     * pointer doesn't change then its a no-op.
-     */
-    AuthUserRequest *old_auth_user_request = checklist->auth_user_request;
-    const auth_acl_t result = AuthUserRequest::tryToAuthenticateAndSetAuthUser(
-        &checklist->auth_user_request, headertype, request, 
-        checklist->conn(), checklist->src_addr);
-    if (checklist->auth_user_request)
-        AUTHUSERREQUESTLOCK(checklist->auth_user_request, "ACLAuth::authenticated");
-    AUTHUSERREQUESTUNLOCK(old_auth_user_request, "old ACLAuth");
+    const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser(
+                                    &checklist->auth_user_request, headertype, request,
+                                    checklist->conn(), checklist->src_addr, checklist->al);
     switch (result) {
 
     case AUTH_ACL_CANNOT_AUTHENTICATE:
-        debugs(28, 4, HERE << "returning  0 user authenticated but not authorised.");
-        return 0;
+        debugs(28, 4, HERE << "returning " << ACCESS_DENIED << " user authenticated but not authorised.");
+        return ACCESS_DENIED;
 
     case AUTH_AUTHENTICATED:
-        return 1;
+        return ACCESS_ALLOWED;
         break;
 
     case AUTH_ACL_HELPER:
-        debugs(28, 4, HERE << "returning 0 sending credentials to helper.");
-        checklist->changeState(ProxyAuthLookup::Instance());
-        return 0;
+        if (checklist->goAsync(ProxyAuthLookup::Instance()))
+            debugs(28, 4, "returning " << ACCESS_DUNNO << " sending credentials to helper.");
+        else
+            debugs(28, 2, "cannot go async; returning " << ACCESS_DUNNO);
+        return ACCESS_DUNNO; // XXX: break this down into DUNNO, EXPIRED_OK, EXPIRED_BAD states
 
     case AUTH_ACL_CHALLENGE:
-        debugs(28, 4, HERE << "returning 0 sending authentication challenge.");
-        checklist->changeState (ProxyAuthNeeded::Instance());
-        return 0;
+        debugs(28, 4, HERE << "returning " << ACCESS_AUTH_REQUIRED << " sending authentication challenge.");
+        /* Client is required to resend the request with correct authentication
+         * credentials. (This may be part of a stateful auth protocol.)
+         * The request is denied.
+         */
+        return ACCESS_AUTH_REQUIRED;
 
     default:
         fatal("unexpected authenticateAuthenticate reply\n");
-        return 0;
+        return ACCESS_DENIED;
     }
 }
+