]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Add key_extras to proxy authentication schemes.
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 6 Dec 2013 14:59:47 +0000 (16:59 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 6 Dec 2013 14:59:47 +0000 (16:59 +0200)
The key_extras value is a "quoted string" with logformat %macro support. It is
appended to request line for the authentication helper.

Example usage:
   auth_param basic key_extras "thePort:%>lp"
   auth_param digest key_extras "LocalIP=%>la:%lp"

This is a Measurement Factory project.

47 files changed:
src/AccessLogEntry.h
src/FwdState.cc
src/PeerSelectState.h
src/acl/FilledChecklist.h
src/adaptation/AccessCheck.cc
src/auth/Acl.cc
src/auth/AclProxyAuth.cc
src/auth/Config.cc
src/auth/Config.h
src/auth/Gadgets.cc
src/auth/User.cc
src/auth/User.h
src/auth/UserRequest.cc
src/auth/UserRequest.h
src/auth/basic/User.cc
src/auth/basic/User.h
src/auth/basic/UserRequest.cc
src/auth/basic/UserRequest.h
src/auth/basic/auth_basic.cc
src/auth/basic/auth_basic.h
src/auth/digest/User.cc
src/auth/digest/User.h
src/auth/digest/UserRequest.cc
src/auth/digest/UserRequest.h
src/auth/digest/auth_digest.cc
src/auth/digest/auth_digest.h
src/auth/negotiate/User.cc
src/auth/negotiate/User.h
src/auth/negotiate/UserRequest.cc
src/auth/negotiate/UserRequest.h
src/auth/negotiate/auth_negotiate.cc
src/auth/negotiate/auth_negotiate.h
src/auth/ntlm/User.cc
src/auth/ntlm/User.h
src/auth/ntlm/UserRequest.cc
src/auth/ntlm/UserRequest.h
src/auth/ntlm/auth_ntlm.cc
src/auth/ntlm/auth_ntlm.h
src/cf.data.pre
src/client_side.cc
src/client_side_request.cc
src/format/ByteCode.h
src/format/Format.cc
src/format/Token.cc
src/peer_select.cc
src/tests/stub_libauth.cc
src/tunnel.cc

index b302c63bb8f7181468ac51fc41f7e04c98b370f8..73da24e3ea36a1a8ee79f00793c1fe7c415c0c24 100644 (file)
@@ -169,7 +169,7 @@ public:
                 ssluser(NULL),
 #endif
                 port(NULL) {
-            ;
+            caddr.setNoAddr();
         }
 
         Ip::Address caddr;
index 82fb20f04de68d5c9942a1eff74529f61c342d2a..05d8e82ca9161bce6991243bc315632078489832 100644 (file)
@@ -163,7 +163,7 @@ void FwdState::start(Pointer aSelf)
 #endif
 
     // do full route options selection
-    peerSelect(&serverDestinations, request, entry, fwdPeerSelectionCompleteWrapper, this);
+    peerSelect(&serverDestinations, request, al, entry, fwdPeerSelectionCompleteWrapper, this);
 }
 
 #if STRICT_ORIGINAL_DST
index 84634404a747a63f26074cc1b539c6b15118afea..f58885edec8a8386a89bbe9388de553e1489ca5a 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef   SQUID_PEERSELECTSTATE_H
 #define   SQUID_PEERSELECTSTATE_H
 
+#include "AccessLogEntry.h"
 #include "acl/Checklist.h"
 #include "base/Vector.h"
 #include "cbdata.h"
@@ -47,7 +48,7 @@ class ErrorState;
 
 typedef void PSC(Comm::ConnectionList *, ErrorState *, void *);
 
-void peerSelect(Comm::ConnectionList *, HttpRequest *, StoreEntry *, PSC *, void *data);
+void peerSelect(Comm::ConnectionList *, HttpRequest *, AccessLogEntry::Pointer const&, StoreEntry *, PSC *, void *data);
 void peerSelectInit(void);
 
 /**
@@ -79,6 +80,7 @@ public:
     const char * url() const;
 
     HttpRequest *request;
+    AccessLogEntry::Pointer al; ///< info for the future access.log entry
     StoreEntry *entry;
     allow_t always_direct;
     allow_t never_direct;
index 05131181acdac9a1ad484a283dab65b4711a54cd..23b69b4f9ade516f00bfe4a3bfbee10511d38f94 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SQUID_ACLFILLED_CHECKLIST_H
 #define SQUID_ACLFILLED_CHECKLIST_H
 
+#include "AccessLogEntry.h"
 #include "acl/Checklist.h"
 #include "acl/forward.h"
 #include "ip/Address.h"
@@ -75,6 +76,8 @@ public:
     Ssl::X509_Pointer serverCert;
 #endif
 
+    AccessLogEntry::Pointer al; ///< info for the future access.log entry
+
     ExternalACLEntry *extacl_entry;
 
 private:
index fdda1c2336586dee3e675ee458a63d71ba6038c7..10cd0fb917022fb70ce77349638e7313fb284f65 100644 (file)
@@ -126,6 +126,7 @@ Adaptation::AccessCheck::checkCandidates()
             acl_checklist = new ACLFilledChecklist(r->acl, filter.request, dash_str);
             if ((acl_checklist->reply = filter.reply))
                 HTTPMSGLOCK(acl_checklist->reply);
+            acl_checklist->al = filter.al;
             acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this);
             return;
         }
index 5a6736e3d69165dbd6679fd153b0ed0a5aef5544..cde58e641e98d8a91cd7f4236b502cdc617f74bf 100644 (file)
@@ -46,7 +46,7 @@ AuthenticateAcl(ACLChecklist *ch)
     /* Note: this fills in auth_user_request when applicable */
     const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser(
                                     &checklist->auth_user_request, headertype, request,
-                                    checklist->conn(), checklist->src_addr);
+                                    checklist->conn(), checklist->src_addr, checklist->al);
     switch (result) {
 
     case AUTH_ACL_CANNOT_AUTHENTICATE:
index 0c05e5270bf8a8d166ced360452ec14ff2a2f939..91e2bc164764f04d6fe4265eb1da7a3f75d7eaf1 100644 (file)
@@ -145,7 +145,7 @@ ProxyAuthLookup::checkForAsync(ACLChecklist *cl) const
     /* make sure someone created auth_user_request for us */
     assert(checklist->auth_user_request != NULL);
     assert(checklist->auth_user_request->valid());
-    checklist->auth_user_request->start(LookupDone, checklist);
+    checklist->auth_user_request->start(checklist->request, checklist->al, LookupDone, checklist);
 }
 
 void
index d396b42704a7687e7ea3944e8954a9b690d98ba8..dba69a7db633d151eafadb641d0c77c38b37915e 100644 (file)
 #include "squid.h"
 #include "auth/Config.h"
 #include "auth/UserRequest.h"
+#include "cache_cf.h"
+#include "ConfigParser.h"
 #include "Debug.h"
+#include "format/Format.h"
 #include "globals.h"
+#include "Store.h"
 
 Auth::ConfigVector Auth::TheConfig;
 
@@ -46,7 +50,7 @@ Auth::ConfigVector Auth::TheConfig;
  * It may also be NULL reflecting that no user could be created.
  */
 Auth::UserRequest::Pointer
-Auth::Config::CreateAuthUser(const char *proxy_auth)
+Auth::Config::CreateAuthUser(const char *proxy_auth, AccessLogEntry::Pointer &al)
 {
     assert(proxy_auth != NULL);
     debugs(29, 9, HERE << "header = '" << proxy_auth << "'");
@@ -58,8 +62,17 @@ Auth::Config::CreateAuthUser(const char *proxy_auth)
                "Unsupported or unconfigured/inactive proxy-auth scheme, '" << proxy_auth << "'");
         return NULL;
     }
+    static MemBuf rmb;
+    rmb.reset();
+    if (config->keyExtras) {
+        // %credentials and %username, which normally included in
+        // request_format, are - at this time, but that is OK
+        // because user name is added to key explicitly, and we do
+        // not want to store authenticated credentials at all.
+        config->keyExtras->assemble(rmb, al, 0);
+    }
 
-    return config->decode(proxy_auth);
+    return config->decode(proxy_auth, rmb.hasContent() ? rmb.content() : NULL);
 }
 
 Auth::Config *
@@ -76,3 +89,43 @@ Auth::Config::Find(const char *proxy_auth)
 void
 Auth::Config::registerWithCacheManager(void)
 {}
+
+void
+Auth::Config::parse(Auth::Config * scheme, int n_configured, char *param_str)
+{
+    if (strcmp(param_str, "key_extras") == 0) {
+        keyExtrasLine = ConfigParser::NextQuotedToken();
+        Format::Format *nlf =  new ::Format::Format(scheme->type());
+        if (!nlf->parse(keyExtrasLine.termedBuf())) {
+            debugs(29, DBG_CRITICAL, "FATAL: Failed parsing key_extras formatting value");
+            self_destruct();
+            return;
+        }
+        if (keyExtras)
+            delete keyExtras;
+
+        keyExtras = nlf;
+        
+        if (char *t = strtok(NULL, w_space)) {
+               debugs(29, DBG_CRITICAL, "FATAL: Unexpected argument '" << t << "' after request_format specification");
+               self_destruct();
+        }
+    } else {
+        debugs(29, DBG_CRITICAL, "Unrecognised " << scheme->type() << " auth scheme parameter '" << param_str << "'");
+    }
+}
+
+void
+Auth::Config::dump(StoreEntry *entry, const char *name, Auth::Config *scheme)
+{
+    if (keyExtrasLine.size() > 0)
+        storeAppendPrintf(entry, "%s %s key_extras \"%s\"\n", name, scheme->type(), keyExtrasLine.termedBuf());
+}
+
+void
+Auth::Config::done()
+{
+    delete keyExtras;
+    keyExtras = NULL; 
+    keyExtrasLine.clean();
+}
index ec29ed06dc25919de3706eb38924622139628ef9..6f1c981a415b5139b7037905e7ee758fbd00e495 100644 (file)
@@ -32,6 +32,7 @@
 
 #if USE_AUTH
 
+#include "AccessLogEntry.h"
 #include "auth/UserRequest.h"
 #include "HelperChildConfig.h"
 
@@ -43,6 +44,11 @@ class wordlist;
 /* for http_hdr_type parameters-by-value */
 #include "HttpHeader.h"
 
+namespace Format
+{
+    class Format;
+}
+
 namespace Auth
 {
 
@@ -61,10 +67,10 @@ class Config
 {
 
 public:
-    static UserRequest::Pointer CreateAuthUser(const char *proxy_auth);
+    static UserRequest::Pointer CreateAuthUser(const char *proxy_auth, AccessLogEntry::Pointer &al);
 
     static Config *Find(const char *proxy_auth);
-    Config() : authenticateChildren(20), authenticateProgram(NULL) {}
+    Config() : authenticateChildren(20), authenticateProgram(NULL), keyExtras(NULL) {}
 
     virtual ~Config() {}
 
@@ -86,7 +92,7 @@ public:
      \param proxy_auth Login Pattern to parse.
      \retval *         Details needed to authenticate.
      */
-    virtual UserRequest::Pointer decode(char const *proxy_auth) = 0;
+    virtual UserRequest::Pointer decode(char const *proxy_auth, const char *requestRealm) = 0;
 
     /**
      * squid is finished with this config, release any unneeded resources.
@@ -95,7 +101,7 @@ public:
      *
      \todo we need a 'done for reconfigure' and a 'done permanently' concept.
      */
-    virtual void done() = 0;
+    virtual void done();
 
     /**
      * The configured function is used to see if the auth module has been given valid
@@ -117,7 +123,7 @@ public:
      * Responsible for writing to the StoreEntry the configuration parameters that a user
      * would put in a config file to recreate the running configuration.
      */
-    virtual void dump(StoreEntry *, const char *, Config *) = 0;
+    virtual void dump(StoreEntry *, const char *, Config *);
 
     /** add headers as needed when challenging for auth */
     virtual void fixHeader(UserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *) = 0;
@@ -129,7 +135,7 @@ public:
     virtual void registerWithCacheManager(void);
 
     /** parse config options */
-    virtual void parse(Config *, int, char *) = 0;
+    virtual void parse(Config *, int, char *);
 
     /** the http string id */
     virtual const char * type() const = 0;
@@ -137,6 +143,8 @@ public:
 public:
     HelperChildConfig authenticateChildren;
     wordlist *authenticateProgram; ///< Helper program to run, includes all parameters
+    String keyExtrasLine;  ///< The format of the request to the auth helper
+    Format::Format *keyExtras; ///< The compiled request format
 };
 
 typedef Vector<Config *> ConfigVector;
index 8a025dc5a8be6ada9d3c153972f6b4d34d2fd79e..f31c9049cd54d9daa514edc64b545e547d41cb51 100644 (file)
@@ -139,7 +139,7 @@ authenticateReset(void)
 AuthUserHashPointer::AuthUserHashPointer(Auth::User::Pointer anAuth_user):
         auth_user(anAuth_user)
 {
-    key = (void *)anAuth_user->username();
+    key = (void *)anAuth_user->userKey();
     next = NULL;
     hash_join(proxy_auth_username_cache, (hash_link *) this);
 }
index d0938dd5769be3a596604962dbfa6c475e4a53be..739cbc2e24aa616cf092772e703df0de9c15713a 100644 (file)
@@ -49,14 +49,15 @@ CBDATA_TYPE(AuthUserIP);
 
 time_t Auth::User::last_discard = 0;
 
-Auth::User::User(Auth::Config *aConfig) :
+Auth::User::User(Auth::Config *aConfig, const char *aRequestRealm) :
         auth_type(Auth::AUTH_UNKNOWN),
         config(aConfig),
         ipcount(0),
         expiretime(0),
         notes(),
         credentials_state(Auth::Unchecked),
-        username_(NULL)
+        username_(NULL),
+        requestRealm_(aRequestRealm)
 {
     proxy_auth_list.head = proxy_auth_list.tail = NULL;
     proxy_match_cache.head = proxy_match_cache.tail = NULL;
@@ -338,6 +339,14 @@ Auth::User::addIp(Ip::Address ipaddr)
     debugs(29, 2, HERE << "user '" << username() << "' has been seen at a new IP address (" << ipaddr << ")");
 }
 
+SBuf
+Auth::User::BuildUserKey(const char *username, const char *realm)
+{
+    SBuf key;
+    key.Printf("%s:%s", username, realm);
+    return key;
+}
+
 /**
  * Add the Auth::User structure to the username cache.
  */
@@ -390,6 +399,8 @@ Auth::User::username(char const *aString)
     if (aString) {
         assert(!username_);
         username_ = xstrdup(aString);
+        if (!requestRealm_.isEmpty())
+            userKey_ = BuildUserKey(username_, requestRealm_.c_str());
     } else {
         safe_free(username_);
     }
index c6c9b1f19f65302c3bf23a1985fcb0142394e003..74de93cfd83ade3f639b31be864c0bdf27d62c18 100644 (file)
@@ -40,6 +40,7 @@
 #include "dlink.h"
 #include "ip/Address.h"
 #include "Notes.h"
+#include "SBuf.h"
 
 class AuthUserHashPointer;
 class StoreEntry;
@@ -82,12 +83,15 @@ public:
 public:
     static void cacheInit();
     static void CachedACLsReset();
+    static SBuf BuildUserKey(const char *username, const char *realm);
 
     void absorb(Auth::User::Pointer from);
     virtual ~User();
     char const *username() const { return username_; }
     void username(char const *);
 
+    const char *userKey() {return !userKey_.isEmpty() ? userKey_.c_str() : username_;}
+
     /**
      * How long these credentials are still valid for.
      * Negative numbers means already expired.
@@ -117,7 +121,7 @@ private:
     CredentialState credentials_state;
 
 protected:
-    User(Auth::Config *);
+    User(Auth::Config *, const char *requestRealm);
 
 private:
     /**
@@ -133,6 +137,17 @@ private:
      */
     const char *username_;
 
+    /**
+     * A realm for the user depending on request, designed to identify users,
+     * with the same username and different authentication domains.
+     */
+    SBuf requestRealm_;
+
+    /**
+     * A Unique key for the user, consist by username and requestRealm_
+     */
+    SBuf userKey_;
+
     /** what ip addresses has this user been seen at?, plus a list length cache */
     dlink_list ip_list;
 };
index d4bf5e64527cfdbdd83acb125267b101a2616f04..5315c7cb4b6941eed6327ba0d086977cacbe6592 100644 (file)
@@ -43,6 +43,8 @@
 #include "comm/Connection.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "format/Format.h"
+#include "MemBuf.h"
 
 /* Generic Functions */
 
@@ -59,12 +61,12 @@ Auth::UserRequest::username() const
 
 /* send the initial data to an authenticator module */
 void
-Auth::UserRequest::start(AUTHCB * handler, void *data)
+Auth::UserRequest::start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
 {
     assert(handler);
     assert(data);
     debugs(29, 9, HERE << "auth_user_request '" << this << "'");
-    module_start(handler, data);
+    module_start(request, al, handler, data);
 }
 
 bool
@@ -293,7 +295,7 @@ authTryGetUser(Auth::UserRequest::Pointer auth_user_request, ConnStateData * con
  * Caller is responsible for locking and unlocking their *auth_user_request!
  */
 AuthAclState
-Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr)
+Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al)
 {
     const char *proxy_auth;
     assert(headertype != 0);
@@ -372,7 +374,7 @@ Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request,
             /* beginning of a new request check */
             debugs(29, 4, HERE << "No connection authentication type");
 
-            *auth_user_request = Auth::Config::CreateAuthUser(proxy_auth);
+            *auth_user_request = Auth::Config::CreateAuthUser(proxy_auth, al);
             if (*auth_user_request == NULL)
                 return AUTH_ACL_CHALLENGE;
             else if (!(*auth_user_request)->valid()) {
@@ -455,7 +457,7 @@ Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request,
 }
 
 AuthAclState
-Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * aUR, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr)
+Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * aUR, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al)
 {
     // If we have already been called, return the cached value
     Auth::UserRequest::Pointer t = authTryGetUser(*aUR, conn, request);
@@ -471,7 +473,7 @@ Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *
     }
 
     // ok, call the actual authenticator routine.
-    AuthAclState result = authenticate(aUR, headertype, request, conn, src_addr);
+    AuthAclState result = authenticate(aUR, headertype, request, conn, src_addr, al);
 
     // auth process may have changed the UserRequest we are dealing with
     t = authTryGetUser(*aUR, conn, request);
@@ -564,3 +566,20 @@ Auth::UserRequest::scheme() const
 {
     return Auth::Scheme::Find(user()->config->type());
 }
+
+const char *
+Auth::UserRequest::helperRequestKeyExtras(HttpRequest *request, AccessLogEntry::Pointer &al)
+{
+    if (Format::Format *reqFmt = user()->config->keyExtras) {
+        static MemBuf mb;
+        mb.reset();
+        // We should pass AccessLogEntry as second argument ....
+        Auth::UserRequest::Pointer oldReq = request->auth_user_request;
+        request->auth_user_request = this;
+        reqFmt->assemble(mb, al, 0);
+        request->auth_user_request = oldReq;
+        debugs(29, 5, "Assembled line to send :" << mb.content());
+        return mb.content();
+    }
+    return NULL;
+}
index 0bdebdfe4e1b0e537d3636f442b2f928ef21132f..7ca884e24cf158b7177eaa0a008e254126fca4e5 100644 (file)
@@ -32,6 +32,7 @@
 
 #if USE_AUTH
 
+#include "AccessLogEntry.h"
 #include "auth/AuthAclState.h"
 #include "auth/Scheme.h"
 #include "auth/User.h"
@@ -164,7 +165,7 @@ public:
      * \param handler  Handler to process the callback when its run
      * \param data     CBDATA for handler
      */
-    virtual void module_start(AUTHCB *handler, void *data) = 0;
+    virtual void module_start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *handler, void *data) = 0;
 
     // User credentials object this UserRequest is managing
     virtual User::Pointer user() {return _auth_user;}
@@ -189,12 +190,12 @@ public:
      *
      * \return Some AUTH_ACL_* state
      */
-    static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &);
+    static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &);
 
     /// Add the appropriate [Proxy-]Authenticate header to the given reply
     static void addReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal);
 
-    void start(AUTHCB *handler, void *data);
+    void start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *handler, void *data);
     char const * denyMessage(char const * const default_message = NULL);
 
     /** Possibly overrideable in future */
@@ -217,9 +218,15 @@ public:
 
     virtual const char * connLastHeader();
 
+    /**
+     * The string representation of the credentials send by client
+     */
+    virtual const char *credentialsStr() = 0;
+
+    const char *helperRequestKeyExtras(HttpRequest *, AccessLogEntry::Pointer &al);
 private:
 
-    static AuthAclState authenticate(UserRequest::Pointer * auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr);
+    static AuthAclState authenticate(UserRequest::Pointer * auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al);
 
     /** return a message on the 407 error pages */
     char *message;
index 66320d2241f24ab05c68f729cf86682990e079b9..273ee33f2f55f0a6abdf935a1fc751e6a2bc693c 100644 (file)
@@ -5,8 +5,8 @@
 #include "SquidConfig.h"
 #include "SquidTime.h"
 
-Auth::Basic::User::User(Auth::Config *aConfig) :
-        Auth::User(aConfig),
+Auth::Basic::User::User(Auth::Config *aConfig, const char *aRequestRealm) :
+        Auth::User(aConfig, aRequestRealm),
         passwd(NULL),
         queue(NULL),
         currentRequest(NULL)
index 52ed43cfb5631d04622cd8b02c996be1b81edb60..1226fb736cec4e18837ffde83b2216c0a52bf4bb 100644 (file)
@@ -19,7 +19,7 @@ class User : public Auth::User
 public:
     MEMPROXY_CLASS(Auth::Basic::User);
 
-    User(Auth::Config *);
+    User(Auth::Config *, const char *requestRealm);
     ~User();
     bool authenticated() const;
     bool valid() const;
index ef9dc6fa814d96b731e9a5e99250d32bd05a26d1..a9f6305ec70311b0d90c495dadc016f13f0923e1 100644 (file)
@@ -7,6 +7,10 @@
 #include "charset.h"
 #include "Debug.h"
 #include "HelperReply.h"
+#include "HttpMsg.h"
+#include "HttpRequest.h"
+#include "format/Format.h"
+#include "MemBuf.h"
 #include "rfc1738.h"
 #include "SquidTime.h"
 
@@ -25,6 +29,15 @@ Auth::Basic::UserRequest::authenticated() const
     return 0;
 }
 
+const char *
+Auth::Basic::UserRequest::credentialsStr()
+{
+    Auth::Basic::User const *basic_auth = dynamic_cast<Auth::Basic::User const *>(user().getRaw());
+    if (basic_auth)
+        return basic_auth->passwd;
+    return NULL;
+}
+
 /* log a basic user in
  */
 void
@@ -80,7 +93,7 @@ Auth::Basic::UserRequest::module_direction()
 
 /* send the initial data to a basic authenticator module */
 void
-Auth::Basic::UserRequest::module_start(AUTHCB * handler, void *data)
+Auth::Basic::UserRequest::module_start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
 {
     assert(user()->auth_type == Auth::AUTH_BASIC);
     Auth::Basic::User *basic_auth = dynamic_cast<Auth::Basic::User *>(user().getRaw());
@@ -120,7 +133,12 @@ Auth::Basic::UserRequest::module_start(AUTHCB * handler, void *data)
         xstrncpy(usern, rfc1738_escape(user()->username()), sizeof(usern));
         xstrncpy(pass, rfc1738_escape(basic_auth->passwd), sizeof(pass));
     }
-    int sz = snprintf(buf, sizeof(buf), "%s %s\n", usern, pass);
+    int sz = 0;
+    if (const char *keyExtras = helperRequestKeyExtras(request, al))
+        sz = snprintf(buf, sizeof(buf), "%s %s %s\n", usern, pass, keyExtras);
+    else
+        sz = snprintf(buf, sizeof(buf), "%s %s\n", usern, pass);
+
     if (sz<=0) {
         debugs(9, DBG_CRITICAL, "ERROR: Basic Authentication Failure. Can not build helper validation request.");
         handler(data);
index 4dafb094f3a5e8546cd7670a2e5d61d75ac1e13d..7fad9169c73f635fcb7e3fa70b9c653f1c941dc0 100644 (file)
@@ -26,7 +26,8 @@ public:
     virtual int authenticated() const;
     virtual void authenticate(HttpRequest * request, ConnStateData *conn, http_hdr_type type);
     virtual Auth::Direction module_direction();
-    virtual void module_start(AUTHCB *, void *);
+    virtual void module_start(HttpRequest * request, AccessLogEntry::Pointer &al, AUTHCB *, void *);
+    virtual const char *credentialsStr();
 
 private:
     static HLPCB HandleReply;
index 7ece07ed63d41a0d7d7dabbd18abbbeed2f39444..8b47206a1999143247fe99438f75c7ca2462bfe6 100644 (file)
@@ -116,6 +116,8 @@ Auth::Basic::Config::rotateHelpers()
 void
 Auth::Basic::Config::done()
 {
+    Auth::Config::done();
+
     authbasic_initialised = 0;
 
     if (basicauthenticators) {
@@ -149,6 +151,7 @@ Auth::Basic::Config::dump(StoreEntry * entry, const char *name, Auth::Config * s
     storeAppendPrintf(entry, "%s basic children %d startup=%d idle=%d concurrency=%d\n", name, authenticateChildren.n_max, authenticateChildren.n_startup, authenticateChildren.n_idle, authenticateChildren.concurrency);
     storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL);
     storeAppendPrintf(entry, "%s basic casesensitive %s\n", name, casesensitive ? "on" : "off");
+    Auth::Config::dump(entry, name, scheme);
 }
 
 Auth::Basic::Config::Config() :
@@ -184,9 +187,8 @@ Auth::Basic::Config::parse(Auth::Config * scheme, int n_configured, char *param_
         parse_onoff(&casesensitive);
     } else if (strcmp(param_str, "utf8") == 0) {
         parse_onoff(&utf8);
-    } else {
-        debugs(29, DBG_CRITICAL, HERE << "unrecognised basic auth scheme parameter '" << param_str << "'");
-    }
+    } else
+        Auth::Config::parse(scheme, n_configured, param_str);
 }
 
 static void
@@ -196,15 +198,15 @@ authenticateBasicStats(StoreEntry * sentry)
 }
 
 static Auth::User::Pointer
-authBasicAuthUserFindUsername(const char *username)
+authBasicAuthUserFindUsername(const char *userkey)
 {
     AuthUserHashPointer *usernamehash;
-    debugs(29, 9, HERE << "Looking for user '" << username << "'");
+    debugs(29, 9, "Looking for user '" << userkey << "'");
 
-    if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) {
+    if (userkey && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, userkey)))) {
         while (usernamehash) {
             if ((usernamehash->user()->auth_type == Auth::AUTH_BASIC) &&
-                    !strcmp(username, (char const *)usernamehash->key))
+                    !strcmp(userkey, (char const *)usernamehash->key))
                 return usernamehash->user();
 
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
@@ -257,7 +259,7 @@ Auth::Basic::Config::decodeCleartext(const char *httpAuthHeader)
  * descriptive message to the user.
  */
 Auth::UserRequest::Pointer
-Auth::Basic::Config::decode(char const *proxy_auth)
+Auth::Basic::Config::decode(char const *proxy_auth, const char *aRequestRealm)
 {
     Auth::UserRequest::Pointer auth_user_request = dynamic_cast<Auth::UserRequest*>(new Auth::Basic::UserRequest);
     /* decode the username */
@@ -275,18 +277,18 @@ Auth::Basic::Config::decode(char const *proxy_auth)
 
     char *seperator = strchr(cleartext, ':');
 
-    lb = local_basic = new Auth::Basic::User(this);
-    if (seperator == NULL) {
-        local_basic->username(cleartext);
-    } else {
+    lb = local_basic = new Auth::Basic::User(this, aRequestRealm);
+
+    if (seperator) {
         /* terminate the username */
         *seperator = '\0';
-        local_basic->username(cleartext);
         local_basic->passwd = xstrdup(seperator+1);
     }
 
     if (!casesensitive)
-        Tolower((char *)local_basic->username());
+        Tolower(cleartext);
+    local_basic->username(cleartext);
+
 
     if (local_basic->passwd == NULL) {
         debugs(29, 4, HERE << "no password in proxy authorization header '" << proxy_auth << "'");
@@ -310,7 +312,7 @@ Auth::Basic::Config::decode(char const *proxy_auth)
     /* now lookup and see if we have a matching auth_user structure in memory. */
     Auth::User::Pointer auth_user;
 
-    if ((auth_user = authBasicAuthUserFindUsername(lb->username())) == NULL) {
+    if ((auth_user = authBasicAuthUserFindUsername(lb->userKey())) == NULL) {
         /* the user doesn't exist in the username cache yet */
         /* save the credentials */
         debugs(29, 9, HERE << "Creating new user '" << lb->username() << "'");
index 0c2e6a4b87f1d5b836a2944b62b51b31dff38057..e15fe26747bfcfc8841b120bf9760c35b79904bf 100644 (file)
@@ -26,7 +26,7 @@ public:
     ~Config();
     virtual bool active() const;
     virtual bool configured() const;
-    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth);
+    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth, const char *requestRealm);
     virtual void done();
     virtual void rotateHelpers();
     virtual void dump(StoreEntry *, const char *, Auth::Config *);
index 1cf7dd0ba51b5df061ee5569484e093b84bf916b..ecb2b1988891ad21727a61eb68b11e0e70fffea1 100644 (file)
@@ -6,8 +6,8 @@
 #include "SquidConfig.h"
 #include "SquidTime.h"
 
-Auth::Digest::User::User(Auth::Config *aConfig) :
-        Auth::User(aConfig),
+Auth::Digest::User::User(Auth::Config *aConfig, const char *aRequestRealm) :
+        Auth::User(aConfig, aRequestRealm),
         HA1created(0)
 {
     memset(HA1, 0, sizeof(HA1));
index 2e86534d0ff6e56e15f5f863b70148124996ea72..08ccae847de4b3b706958e6352ed828c4e7df405 100644 (file)
@@ -14,7 +14,7 @@ class User : public Auth::User
 public:
     MEMPROXY_CLASS(Auth::Digest::User);
 
-    User(Auth::Config *);
+    User(Auth::Config *, const char *requestRealm);
     ~User();
     int authenticated() const;
 
index 161161f8065f72726f1d46dfddffe73e84b11a04..0a4e9452ee504b801d814310c6b37070a2947223 100644 (file)
@@ -1,4 +1,5 @@
 #include "squid.h"
+#include "AccessLogEntry.h"
 #include "auth/digest/auth_digest.h"
 #include "auth/digest/User.h"
 #include "auth/digest/UserRequest.h"
@@ -7,6 +8,8 @@
 #include "HttpHeaderTools.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "format/Format.h"
+#include "MemBuf.h"
 #include "SquidTime.h"
 
 Auth::Digest::UserRequest::UserRequest() :
@@ -56,6 +59,12 @@ Auth::Digest::UserRequest::authenticated() const
     return 0;
 }
 
+const char *
+Auth::Digest::UserRequest::credentialsStr()
+{
+    return realm;
+}
+
 /** log a digest user in
  */
 void
@@ -248,7 +257,7 @@ Auth::Digest::UserRequest::addAuthenticationInfoTrailer(HttpReply * rep, int acc
 
 /* send the initial data to a digest authenticator module */
 void
-Auth::Digest::UserRequest::module_start(AUTHCB * handler, void *data)
+Auth::Digest::UserRequest::module_start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
 {
     char buf[8192];
 
@@ -261,12 +270,19 @@ Auth::Digest::UserRequest::module_start(AUTHCB * handler, void *data)
         return;
     }
 
+    const char *keyExtras = helperRequestKeyExtras(request, al);
     if (static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->utf8) {
         char userstr[1024];
         latin1_to_utf8(userstr, sizeof(userstr), user()->username());
-        snprintf(buf, 8192, "\"%s\":\"%s\"\n", userstr, realm);
+        if (keyExtras)
+            snprintf(buf, 8192, "\"%s\":\"%s\" %s\n", userstr, realm, keyExtras);
+        else
+            snprintf(buf, 8192, "\"%s\":\"%s\"\n", userstr, realm);
     } else {
-        snprintf(buf, 8192, "\"%s\":\"%s\"\n", user()->username(), realm);
+        if (keyExtras)
+            snprintf(buf, 8192, "\"%s\":\"%s\" %s\n", user()->username(), realm, keyExtras);
+        else
+            snprintf(buf, 8192, "\"%s\":\"%s\"\n", user()->username(), realm);
     }
 
     helperSubmit(digestauthenticators, buf, Auth::Digest::UserRequest::HandleReply,
index 55787a283717b3c7ea8db3088287206318031609..85415d1801d38cb6e2795ee5bc20b5c5bab9e44c 100644 (file)
@@ -34,7 +34,8 @@ public:
     virtual void addAuthenticationInfoTrailer(HttpReply * rep, int accel);
 #endif
 
-    virtual void module_start(AUTHCB *, void *);
+    virtual void module_start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *, void *);
+    virtual const char *credentialsStr();
 
     char *nonceb64;             /* "dcd98b7102dd2f0e8b11d0f600bfb0c093" */
     char *cnonce;               /* "0a4f113b" */
index 09313093eb1028e980f559649c74a0e7b40c1185..1b7c738a3f7b68645aefaeecea7d934e93532df5 100644 (file)
@@ -477,12 +477,12 @@ authDigestNoncePurge(digest_nonce_h * nonce)
 
 /* USER related functions */
 static Auth::User::Pointer
-authDigestUserFindUsername(const char *username)
+authDigestUserFindUsername(const char *userkey)
 {
     AuthUserHashPointer *usernamehash;
-    debugs(29, 9, HERE << "Looking for user '" << username << "'");
+    debugs(29, 9, "Looking for user '" << userkey << "'");
 
-    if (username && (usernamehash = static_cast < AuthUserHashPointer * >(hash_lookup(proxy_auth_username_cache, username)))) {
+    if ((usernamehash = static_cast < AuthUserHashPointer * >(hash_lookup(proxy_auth_username_cache, userkey)))) {
         while ((usernamehash->user()->auth_type != Auth::AUTH_DIGEST) && (usernamehash->next))
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
 
@@ -523,6 +523,7 @@ Auth::Digest::Config::dump(StoreEntry * entry, const char *name, Auth::Config *
                       name, "digest", noncemaxuses,
                       name, "digest", (int) noncemaxduration,
                       name, "digest", (int) nonceGCInterval);
+    Auth::Config::dump(entry, name, scheme);
 }
 
 bool
@@ -605,6 +606,8 @@ Auth::Digest::Config::registerWithCacheManager(void)
 void
 Auth::Digest::Config::done()
 {
+    Auth::Config::done();
+
     authdigest_initialised = 0;
 
     if (digestauthenticators)
@@ -666,9 +669,8 @@ Auth::Digest::Config::parse(Auth::Config * scheme, int n_configured, char *param
         parse_onoff(&PostWorkaround);
     } else if (strcmp(param_str, "utf8") == 0) {
         parse_onoff(&utf8);
-    } else {
-        debugs(29, DBG_CRITICAL, "unrecognised digest auth scheme parameter '" << param_str << "'");
-    }
+    } else
+        Auth::Config::parse(scheme, n_configured, param_str);
 }
 
 const char *
@@ -758,13 +760,13 @@ authDigestUserLinkNonce(Auth::Digest::User * user, digest_nonce_h * nonce)
 
 /* setup the necessary info to log the username */
 static Auth::UserRequest::Pointer
-authDigestLogUsername(char *username, Auth::UserRequest::Pointer auth_user_request)
+authDigestLogUsername(char *username, Auth::UserRequest::Pointer auth_user_request, const char *requestRealm)
 {
     assert(auth_user_request != NULL);
 
     /* log the username */
     debugs(29, 9, "Creating new user for logging '" << (username?username:"[no username]") << "'");
-    Auth::User::Pointer digest_user = new Auth::Digest::User(static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest")));
+    Auth::User::Pointer digest_user = new Auth::Digest::User(static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest")), requestRealm);
     /* save the credentials */
     digest_user->username(username);
     /* set the auth_user type */
@@ -779,7 +781,7 @@ authDigestLogUsername(char *username, Auth::UserRequest::Pointer auth_user_reque
  * Auth_user structure.
  */
 Auth::UserRequest::Pointer
-Auth::Digest::Config::decode(char const *proxy_auth)
+Auth::Digest::Config::decode(char const *proxy_auth, const char *aRequestRealm)
 {
     const char *item;
     const char *p;
@@ -944,7 +946,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     /* do we have a username ? */
     if (!username || username[0] == '\0') {
         debugs(29, 2, "Empty or not present username");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -955,7 +957,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
      */
     if (strchr(username, '"')) {
         debugs(29, 2, "Unacceptable username '" << username << "'");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -963,7 +965,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     /* do we have a realm ? */
     if (!digest_request->realm || digest_request->realm[0] == '\0') {
         debugs(29, 2, "Empty or not present realm");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -971,7 +973,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     /* and a nonce? */
     if (!digest_request->nonceb64 || digest_request->nonceb64[0] == '\0') {
         debugs(29, 2, "Empty or not present nonce");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -980,7 +982,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
      * authenticate phase, but needs to be given */
     if (!digest_request->uri || digest_request->uri[0] == '\0') {
         debugs(29, 2, "Missing URI field");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -988,7 +990,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     /* is the response the correct length? */
     if (!digest_request->response || strlen(digest_request->response) != 32) {
         debugs(29, 2, "Response length invalid");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -999,7 +1001,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     else if (strcmp(digest_request->algorithm, "MD5")
              && strcmp(digest_request->algorithm, "MD5-sess")) {
         debugs(29, 2, "invalid algorithm specified!");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -1011,7 +1013,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
         if (strcmp(digest_request->qop, QOP_AUTH) != 0) {
             /* we received a qop option we didn't send */
             debugs(29, 2, "Invalid qop option received");
-            rv = authDigestLogUsername(username, digest_request);
+            rv = authDigestLogUsername(username, digest_request, aRequestRealm);
             safe_free(username);
             return rv;
         }
@@ -1019,7 +1021,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
         /* check cnonce */
         if (!digest_request->cnonce || digest_request->cnonce[0] == '\0') {
             debugs(29, 2, "Missing cnonce field");
-            rv = authDigestLogUsername(username, digest_request);
+            rv = authDigestLogUsername(username, digest_request, aRequestRealm);
             safe_free(username);
             return rv;
         }
@@ -1027,7 +1029,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
         /* check nc */
         if (strlen(digest_request->nc) != 8 || strspn(digest_request->nc, "0123456789abcdefABCDEF") != 8) {
             debugs(29, 2, "invalid nonce count");
-            rv = authDigestLogUsername(username, digest_request);
+            rv = authDigestLogUsername(username, digest_request, aRequestRealm);
             safe_free(username);
             return rv;
         }
@@ -1035,7 +1037,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
         /* cnonce and nc both require qop */
         if (digest_request->cnonce || digest_request->nc[0] != '\0') {
             debugs(29, 2, "missing qop!");
-            rv = authDigestLogUsername(username, digest_request);
+            rv = authDigestLogUsername(username, digest_request, aRequestRealm);
             safe_free(username);
             return rv;
         }
@@ -1050,7 +1052,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
         debugs(29, 2, "Unexpected or invalid nonce received");
         if (digest_request->user() != NULL)
             digest_request->user()->credentials(Auth::Failed);
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -1061,7 +1063,7 @@ Auth::Digest::Config::decode(char const *proxy_auth)
     /* check that we're not being hacked / the username hasn't changed */
     if (nonce->user && strcmp(username, nonce->user->username())) {
         debugs(29, 2, "Username for the nonce does not equal the username for the request");
-        rv = authDigestLogUsername(username, digest_request);
+        rv = authDigestLogUsername(username, digest_request, aRequestRealm);
         safe_free(username);
         return rv;
     }
@@ -1075,10 +1077,11 @@ Auth::Digest::Config::decode(char const *proxy_auth)
 
     Auth::User::Pointer auth_user;
 
-    if ((auth_user = authDigestUserFindUsername(username)) == NULL) {
+    SBuf key = Auth::User::BuildUserKey(username, aRequestRealm);
+    if (key.isEmpty() || (auth_user = authDigestUserFindUsername(key.c_str())) == NULL) {
         /* the user doesn't exist in the username cache yet */
         debugs(29, 9, HERE << "Creating new digest user '" << username << "'");
-        digest_user = new Auth::Digest::User(this);
+        digest_user = new Auth::Digest::User(this, aRequestRealm);
         /* auth_user is a parent */
         auth_user = digest_user;
         /* save the username */
index 1b3892d61854669eb328f762ead6f1ce21b0b6a1..386109a3a19cb85e43389db6ce447109936f81cb 100644 (file)
@@ -69,7 +69,7 @@ public:
     Config();
     virtual bool active() const;
     virtual bool configured() const;
-    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth);
+    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth, const char *requestRealm);
     virtual void done();
     virtual void rotateHelpers();
     virtual void dump(StoreEntry *, const char *, Auth::Config *);
index ca73352da29141fa631d62d197f22dbf6b1526b2..a4b9c42373f7c1148eaf1ecb6c4223ed087b9163 100644 (file)
@@ -3,8 +3,8 @@
 #include "auth/negotiate/User.h"
 #include "Debug.h"
 
-Auth::Negotiate::User::User(Auth::Config *aConfig) :
-        Auth::User(aConfig)
+Auth::Negotiate::User::User(Auth::Config *aConfig, const char *aRequestRealm) :
+        Auth::User(aConfig, aRequestRealm)
 {
     proxy_auth_list.head = proxy_auth_list.tail = NULL;
 }
index b6e84588f8af6e79aac1776374743f074194ff38..57de9e5eff26dbc614a0b35fe308043d40f67d79 100644 (file)
@@ -16,7 +16,7 @@ class User : public Auth::User
 {
 public:
     MEMPROXY_CLASS(Auth::Negotiate::User);
-    User(Auth::Config *);
+    User(Auth::Config *, const char *requestRealm);
     ~User();
     virtual int32_t ttl() const;
 
index 086da9f7b9251ce777837443094f10333130f930..ed34ff2d63a84dc1735320775355dea37779b9e8 100644 (file)
@@ -1,4 +1,5 @@
 #include "squid.h"
+#include "AccessLogEntry.h"
 #include "auth/negotiate/auth_negotiate.h"
 #include "auth/negotiate/UserRequest.h"
 #include "auth/State.h"
@@ -9,6 +10,8 @@
 #include "HttpHeaderTools.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "format/Format.h"
+#include "MemBuf.h"
 #include "SquidTime.h"
 
 Auth::Negotiate::UserRequest::UserRequest()
@@ -52,6 +55,18 @@ Auth::Negotiate::UserRequest::authenticated() const
     return 0;
 }
 
+const char *
+Auth::Negotiate::UserRequest::credentialsStr()
+{
+    static char buf[MAX_AUTHTOKEN_LEN];
+    if (user()->credentials() == Auth::Pending) {
+        snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+    } else {
+        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+    }
+    return buf;
+}
+
 Auth::Direction
 Auth::Negotiate::UserRequest::module_direction()
 {
@@ -82,7 +97,7 @@ Auth::Negotiate::UserRequest::module_direction()
 }
 
 void
-Auth::Negotiate::UserRequest::module_start(AUTHCB * handler, void *data)
+Auth::Negotiate::UserRequest::module_start(HttpRequest *req, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
 {
     static char buf[MAX_AUTHTOKEN_LEN];
 
@@ -100,10 +115,17 @@ Auth::Negotiate::UserRequest::module_start(AUTHCB * handler, void *data)
 
     debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'");
 
+    const char *keyExtras = helperRequestKeyExtras(request, al);
     if (user()->credentials() == Auth::Pending) {
-        snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+        if (keyExtras)
+            snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
+        else
+            snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
     } else {
-        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+        if (keyExtras)
+            snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
+        else
+            snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
     }
 
     waiting = 1;
@@ -283,10 +305,10 @@ Auth::Negotiate::UserRequest::HandleReply(void *data, const HelperReply &reply)
         debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username());
         /* see if this is an existing user with a different proxy_auth
          * string */
-        AuthUserHashPointer *usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->username()));
+        AuthUserHashPointer *usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->userKey()));
         Auth::User::Pointer local_auth_user = lm_request->user();
         while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NEGOTIATE ||
-                                strcmp(usernamehash->user()->username(), auth_user_request->user()->username()) != 0))
+                                strcmp(usernamehash->user()->userKey(), auth_user_request->user()->userKey()) != 0))
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
         if (usernamehash) {
             /* we can't seamlessly recheck the username due to the
index 98276841d46b8a689fcb9e16542f2c41ac2c5a43..b7af9311ec00c7a9d496a53620a8a4cff8f31d5c 100644 (file)
@@ -26,7 +26,8 @@ public:
     virtual int authenticated() const;
     virtual void authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type);
     virtual Direction module_direction();
-    virtual void module_start(AUTHCB *, void *);
+    virtual void module_start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *, void *);
+    virtual const char *credentialsStr();
 
     virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel);
 
index 2455e6f2cb4b5a3ae81e8088da13149b5e46dbdf..9ce6010ae220848a9a45f464174e363c49e59762 100644 (file)
@@ -88,6 +88,8 @@ Auth::Negotiate::Config::rotateHelpers()
 void
 Auth::Negotiate::Config::done()
 {
+    Auth::Config::done();
+
     authnegotiate_initialised = 0;
 
     if (negotiateauthenticators) {
@@ -120,7 +122,7 @@ Auth::Negotiate::Config::dump(StoreEntry * entry, const char *name, Auth::Config
     storeAppendPrintf(entry, "\n%s negotiate children %d startup=%d idle=%d concurrency=%d\n",
                       name, authenticateChildren.n_max, authenticateChildren.n_startup, authenticateChildren.n_idle, authenticateChildren.concurrency);
     storeAppendPrintf(entry, "%s %s keep_alive %s\n", name, "negotiate", keep_alive ? "on" : "off");
-
+    Auth::Config::dump(entry, name, scheme);
 }
 
 Auth::Negotiate::Config::Config() : keep_alive(1)
@@ -140,9 +142,8 @@ Auth::Negotiate::Config::parse(Auth::Config * scheme, int n_configured, char *pa
         authenticateChildren.parseConfig();
     } else if (strcmp(param_str, "keep_alive") == 0) {
         parse_onoff(&keep_alive);
-    } else {
-        debugs(29, DBG_CRITICAL, "ERROR: unrecognised Negotiate auth scheme parameter '" << param_str << "'");
-    }
+    } else
+        Auth::Config::parse(scheme, n_configured, param_str);
 }
 
 const char *
@@ -287,9 +288,9 @@ authenticateNegotiateStats(StoreEntry * sentry)
  * Auth_user structure.
  */
 Auth::UserRequest::Pointer
-Auth::Negotiate::Config::decode(char const *proxy_auth)
+Auth::Negotiate::Config::decode(char const *proxy_auth, const char *aRequestRealm)
 {
-    Auth::Negotiate::User *newUser = new Auth::Negotiate::User(Auth::Config::Find("negotiate"));
+    Auth::Negotiate::User *newUser = new Auth::Negotiate::User(Auth::Config::Find("negotiate"), aRequestRealm);
     Auth::UserRequest *auth_user_request = new Auth::Negotiate::UserRequest();
     assert(auth_user_request->user() == NULL);
 
index b5414f5bf77ab49558aeb91483f81472c169264d..b1dcfb8e345b27876aa2fe4b395feb762c2c57c0 100644 (file)
@@ -31,7 +31,7 @@ public:
     Config();
     virtual bool active() const;
     virtual bool configured() const;
-    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth);
+    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth, const char *requestRealm);
     virtual void done();
     virtual void rotateHelpers();
     virtual void dump(StoreEntry *, const char *, Auth::Config *);
index 61457b098356451606410046e80114c287ad7777..cc5d9c704d7d45d7e091222e5344a57f2d2ff8b1 100644 (file)
@@ -3,8 +3,8 @@
 #include "auth/ntlm/User.h"
 #include "Debug.h"
 
-Auth::Ntlm::User::User(Auth::Config *aConfig) :
-        Auth::User(aConfig)
+Auth::Ntlm::User::User(Auth::Config *aConfig, const char *aRequestRealm) :
+        Auth::User(aConfig, aRequestRealm)
 {
     proxy_auth_list.head = proxy_auth_list.tail = NULL;
 }
index efdee13f41ff099542bc1a53333c02a6d2693e45..0dd72f96d5c48edc409452968ab0201e8e538e22 100644 (file)
@@ -16,7 +16,7 @@ class User : public Auth::User
 {
 public:
     MEMPROXY_CLASS(Auth::Ntlm::User);
-    User(Auth::Config *);
+    User(Auth::Config *, const char *requestRealm);
     ~User();
 
     virtual int32_t ttl() const;
index 4ce04ebf41f3d7a091ac32c6a1c3a9023e4a4986..9c6d58c9ee37854d502c61f498e151d52d79565f 100644 (file)
@@ -1,11 +1,15 @@
 #include "squid.h"
+#include "AccessLogEntry.h"
 #include "auth/ntlm/auth_ntlm.h"
 #include "auth/ntlm/UserRequest.h"
 #include "auth/State.h"
 #include "cbdata.h"
 #include "client_side.h"
 #include "globals.h"
+#include "HttpMsg.h"
 #include "HttpRequest.h"
+#include "format/Format.h"
+#include "MemBuf.h"
 #include "SquidTime.h"
 
 Auth::Ntlm::UserRequest::UserRequest()
@@ -49,6 +53,18 @@ Auth::Ntlm::UserRequest::authenticated() const
     return 0;
 }
 
+const char *
+Auth::Ntlm::UserRequest::credentialsStr()
+{
+    static char buf[MAX_AUTHTOKEN_LEN];
+    if (user()->credentials() == Auth::Pending) {
+        snprintf(buf, sizeof(buf), "YR %s\n", client_blob);
+    } else {
+        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+    }
+    return buf;
+}
+
 Auth::Direction
 Auth::Ntlm::UserRequest::module_direction()
 {
@@ -79,7 +95,7 @@ Auth::Ntlm::UserRequest::module_direction()
 }
 
 void
-Auth::Ntlm::UserRequest::module_start(AUTHCB * handler, void *data)
+Auth::Ntlm::UserRequest::module_start(HttpRequest *req, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
 {
     static char buf[MAX_AUTHTOKEN_LEN];
 
@@ -94,12 +110,18 @@ Auth::Ntlm::UserRequest::module_start(AUTHCB * handler, void *data)
 
     debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'");
 
+    const char *keyExtras = helperRequestKeyExtras(request, al);
     if (user()->credentials() == Auth::Pending) {
-        snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+        if (keyExtras)
+            snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
+        else
+            snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
     } else {
-        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+        if (keyExtras)
+            snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
+        else
+            snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
     }
-
     waiting = 1;
 
     safe_free(client_blob);
@@ -276,10 +298,10 @@ Auth::Ntlm::UserRequest::HandleReply(void *data, const HelperReply &reply)
         debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username());
         /* see if this is an existing user with a different proxy_auth
          * string */
-        AuthUserHashPointer *usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->username()));
+        AuthUserHashPointer *usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->userKey()));
         Auth::User::Pointer local_auth_user = lm_request->user();
         while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NTLM ||
-                                strcmp(usernamehash->user()->username(), auth_user_request->user()->username()) != 0))
+                                strcmp(usernamehash->user()->userKey(), auth_user_request->user()->userKey()) != 0))
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
         if (usernamehash) {
             /* we can't seamlessly recheck the username due to the
index b353c416c766e92f846ec2947ad6ab43de5ef5ea..7bed6b12793a81db69b91e75d4d6bb55fb28af0b 100644 (file)
@@ -26,7 +26,8 @@ public:
     virtual int authenticated() const;
     virtual void authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type);
     virtual Auth::Direction module_direction();
-    virtual void module_start(AUTHCB *, void *);
+    virtual void module_start(HttpRequest *req, AccessLogEntry::Pointer &al, AUTHCB *, void *);
+    virtual const char *credentialsStr();
 
     virtual const char * connLastHeader();
 
index 4515183e3b9ff8ee32cfe652561a452cded8644c..03d62f1dfd6a447b88a1aebe84a3149f57d9c763 100644 (file)
@@ -80,6 +80,8 @@ Auth::Ntlm::Config::rotateHelpers()
 void
 Auth::Ntlm::Config::done()
 {
+    Auth::Config::done();
+
     authntlm_initialised = 0;
 
     if (ntlmauthenticators) {
@@ -112,7 +114,7 @@ Auth::Ntlm::Config::dump(StoreEntry * entry, const char *name, Auth::Config * sc
     storeAppendPrintf(entry, "\n%s ntlm children %d startup=%d idle=%d concurrency=%d\n",
                       name, authenticateChildren.n_max, authenticateChildren.n_startup, authenticateChildren.n_idle, authenticateChildren.concurrency);
     storeAppendPrintf(entry, "%s %s keep_alive %s\n", name, "ntlm", keep_alive ? "on" : "off");
-
+    Auth::Config::dump(entry, name, scheme);
 }
 
 Auth::Ntlm::Config::Config() : keep_alive(1)
@@ -132,9 +134,8 @@ Auth::Ntlm::Config::parse(Auth::Config * scheme, int n_configured, char *param_s
         authenticateChildren.parseConfig();
     } else if (strcmp(param_str, "keep_alive") == 0) {
         parse_onoff(&keep_alive);
-    } else {
-        debugs(29, DBG_CRITICAL, "ERROR unrecognised NTLM auth scheme parameter '" << param_str << "'");
-    }
+    } else
+        Auth::Config::parse(scheme, n_configured, param_str);
 }
 
 const char *
@@ -267,9 +268,9 @@ authenticateNTLMStats(StoreEntry * sentry)
  * Auth_user structure.
  */
 Auth::UserRequest::Pointer
-Auth::Ntlm::Config::decode(char const *proxy_auth)
+Auth::Ntlm::Config::decode(char const *proxy_auth, const char *aRequestRealm)
 {
-    Auth::Ntlm::User *newUser = new Auth::Ntlm::User(Auth::Config::Find("ntlm"));
+    Auth::Ntlm::User *newUser = new Auth::Ntlm::User(Auth::Config::Find("ntlm"), aRequestRealm);
     Auth::UserRequest::Pointer auth_user_request = new Auth::Ntlm::UserRequest();
     assert(auth_user_request->user() == NULL);
 
index 04c0c43c7d2d27307d6cc335f7e815cb12d28f0f..e704c2a73973609fc8ebccd45e7548325f5d41e0 100644 (file)
@@ -27,7 +27,7 @@ public:
     Config();
     virtual bool active() const;
     virtual bool configured() const;
-    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth);
+    virtual Auth::UserRequest::Pointer decode(char const *proxy_auth, const char *requestRealm);
     virtual void done();
     virtual void rotateHelpers();
     virtual void dump(StoreEntry *, const char *, Auth::Config *);
index b0dbe9176b260224b324d17c2e72b44b6ddeac3d..533b726ac62ede80062fdde2b7e6ea4c11463f48 100644 (file)
@@ -319,12 +319,30 @@ DOC_START
        Ports flagged 'transparent', 'intercept', or 'tproxy' have
        authentication disabled.
 
+       === Parameters common to all schemes. ===
+
+       "program" cmdline
+       Specifies the command for the external authenticator.  Such a program
+       runs a loop that, on every iteration, reads a request line from
+       the standard and responds with a scheme-specific answer. The loop
+       stops when all input is exchausted (EOF). See scheme-specific
+       "program" descriptions below for details.
+
+       "key_extras" format
+       Specifies a string to be append to request line format for the
+       authentication helper. "Quoted" format values may contain spaces and
+       logformat %macros. In theory, any logformat %macro can be used.
+       In practice, a %macro expands as a dash (-) if the helper request is
+       sent before the required macro information is available to Squid.
+       By default, Squid uses request formats provided in scheme-specific
+       examples below (search for %credentials).
+
        === Parameters for the basic scheme follow. ===
 
        "program" cmdline
        Specify the command for the external authenticator.  Such a program
-       reads a line containing "username password" and replies with one of
-       three results:
+       reads a request_format line ("username password" by default) and
+       replies with one of three results:
 
          OK
                the user exists.
@@ -407,8 +425,8 @@ DOC_START
        === Parameters for the digest scheme follow ===
 
        "program" cmdline
-       Specify the command for the external authenticator.  Such
-       a program reads a line containing "username":"realm" and
+       Specify the command for the external authenticator.  Such a program
+       reads a request_format line ("username":"realm" by default) and
        replies with one of three results:
 
          OK ha1="..."
@@ -576,7 +594,6 @@ DOC_START
        supported by the proxy.
 
        auth_param negotiate keep_alive on
-
        
        Examples:
 
@@ -3726,6 +3743,11 @@ DOC_START
                ue      User name from external acl helper
                ui      User name from ident
                us      User name from SSL
+               credentials Client credentials. The exact meaning depends on
+                       the authentication scheme: For Basic authentication,
+                       it is the password; for Digest, the realm sent by the
+                       client; for NTLM and Negotiate, the client challenge
+                       or client credentials prefixed with "YR " or "KK ".
 
        HTTP related format codes:
 
index 249e72a0b39c0b666fa89b79fb29fb1ee8daa51c..ae05be6bff9a2ef72d9b8a79ddb74cd3220d4a39 100644 (file)
@@ -633,13 +633,6 @@ ClientHttpRequest::logRequest()
     if (loggingEntry() && loggingEntry()->mem_obj)
         al->cache.objectSize = loggingEntry()->contentLen(); // payload duplicate ?? with or without TE ?
 
-    al->cache.caddr.setNoAddr();
-
-    if (getConn() != NULL) {
-        al->cache.caddr = getConn()->log_addr;
-        al->cache.port =  cbdataReference(getConn()->port);
-    }
-
     al->http.clientRequestSz.header = req_sz;
     al->http.clientReplySz.header = out.headers_sz;
     // XXX: calculate without payload encoding or headers !!
@@ -4323,7 +4316,7 @@ clientAclChecklistCreate(const acl_access * acl, ClientHttpRequest * http)
     ConnStateData * conn = http->getConn();
     ACLFilledChecklist *ch = new ACLFilledChecklist(acl, http->request,
             cbdataReferenceValid(conn) && conn != NULL && conn->clientConnection != NULL ? conn->clientConnection->rfc931 : dash_str);
-
+    ch->al = http->al;
     /*
      * hack for ident ACL. It needs to get full addresses, and a place to store
      * the ident result on persistent connections...
index e7df8a2515b36efddb3f45e1aa87973d3b1ccdc9..fd1effe8387e6f2ac4ae728aefd1b91866201cab 100644 (file)
@@ -164,6 +164,9 @@ ClientHttpRequest::ClientHttpRequest(ConnStateData * aConn) :
     al = new AccessLogEntry;
     al->cache.start_time = current_time;
     al->tcpClient = clientConnection = aConn->clientConnection;
+    al->cache.port =  cbdataReference(aConn->port);
+    al->cache.caddr = aConn->log_addr;
+
 #if USE_SSL
     if (aConn->clientConnection != NULL && aConn->clientConnection->isOpen()) {
         if (SSL *ssl = fd_table[aConn->clientConnection->fd].ssl)
@@ -507,6 +510,7 @@ clientFollowXForwardedForCheck(allow_t answer, void *data)
         */
         ConnStateData *conn = http->getConn();
         conn->log_addr = request->indirect_client_addr;
+        http->al->cache.caddr = conn->log_addr;
     }
     request->x_forwarded_for_iterator.clean();
     request->flags.done_follow_x_forwarded_for = true;
index 43bd5ea02ab08e7de6ea35cfae911d1380981acc..e19d7d4a1e4b1b704cdb80bd9279029d1ce17674 100644 (file)
@@ -193,6 +193,7 @@ typedef enum {
     LFT_ICAP_OUTCOME,
     LFT_ICAP_STATUS_CODE,
 #endif
+    LFT_CREDENTIALS,
 
 #if USE_SSL
     LFT_SSL_BUMP_MODE,
index dcd64034d9be787a6cf6df97bda1d67c08e9e705..15bef5e86888653fdc37ea975699f4f1edcf4989 100644 (file)
@@ -1115,6 +1115,14 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
             }
             break;
 
+        case LFT_CREDENTIALS:
+#if USE_AUTH
+            if (al->request && al->request->auth_user_request != NULL)
+                out = strOrNull(al->request->auth_user_request->credentialsStr());
+#endif
+
+            break;
+
         case LFT_PERCENT:
             out = "%";
 
index e10cef5121a41b7c9d92c5d743a56159ad67eed8..a0341be0d83067de711519b58769fdd9938a5a70 100644 (file)
@@ -129,6 +129,7 @@ static TokenTableEntry TokenTableMisc[] = {
     {"err_code", LFT_SQUID_ERROR },
     {"err_detail", LFT_SQUID_ERROR_DETAIL },
     {"note", LFT_NOTE },
+    {"credentials", LFT_CREDENTIALS},
     {NULL, LFT_NONE}           /* this must be last */
 };
 
index 9c92594e43a70b077650ec3571376fee77d4837f..2c6e4d4dfe138d2a20cdbb1e9b5b2dd350642556 100644 (file)
@@ -141,6 +141,7 @@ peerSelectIcpPing(HttpRequest * request, int direct, StoreEntry * entry)
 void
 peerSelect(Comm::ConnectionList * paths,
            HttpRequest * request,
+           AccessLogEntry::Pointer const &al,
            StoreEntry * entry,
            PSC * callback,
            void *callback_data)
@@ -156,6 +157,7 @@ peerSelect(Comm::ConnectionList * paths,
 
     psstate->request = request;
     HTTPMSGLOCK(psstate->request);
+    psstate->al = al;
 
     psstate->entry = entry;
     psstate->paths = paths;
@@ -439,13 +441,17 @@ peerSelectFoo(ps_state * ps)
         if (ps->always_direct == ACCESS_DUNNO) {
             debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (always_direct to be checked)");
             /** check always_direct; */
-            ps->acl_checklist = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, NULL);
+            ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, NULL);
+            ch->al = ps->al;
+            ps->acl_checklist = ch;
             ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone, ps);
             return;
         } else if (ps->never_direct == ACCESS_DUNNO) {
             debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (never_direct to be checked)");
             /** check never_direct; */
-            ps->acl_checklist = new ACLFilledChecklist(Config.accessList.NeverDirect, request, NULL);
+            ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, NULL);
+            ch->al = ps->al;
+            ps->acl_checklist = ch;
             ps->acl_checklist->nonBlockingCheck(peerCheckNeverDirectDone, ps);
             return;
         } else if (request->flags.noDirect) {
index 090d5d6c872b66665560da59d999b84e60f86be8..a14c3151b79c73b7502cd7409315fdd43c664834 100644 (file)
@@ -5,7 +5,7 @@
 
 #if USE_AUTH
 #include "auth/Config.h"
-Auth::UserRequest::Pointer Auth::Config::CreateAuthUser(const char *) STUB_RETVAL(NULL)
+Auth::UserRequest::Pointer Auth::Config::CreateAuthUser(const char *, AccessLogEntry::Pointer &al) STUB_RETVAL(NULL)
 Auth::Config * Auth::Config::Find(const char *) STUB_RETVAL(NULL)
 void Auth::Config::registerWithCacheManager(void) STUB_NOP
 Auth::ConfigVector Auth::TheConfig;
@@ -28,7 +28,7 @@ Vector<Auth::Scheme::Pointer> & Auth::Scheme::GetSchemes() STUB_RETVAL(*_Schemes
 void Auth::Scheme::FreeAll() STUB
 
 #include "auth/User.h"
-Auth::User::User(Auth::Config *) STUB
+Auth::User::User(Auth::Config *, const char *) STUB
 Auth::CredentialState Auth::User::credentials() const STUB_RETVAL(credentials_state)
 void Auth::User::credentials(CredentialState) STUB
 void Auth::User::absorb(Auth::User::Pointer) STUB
@@ -44,7 +44,7 @@ void Auth::User::UsernameCacheStats(StoreEntry *) STUB
 
 #include "auth/UserRequest.h"
 char const * Auth::UserRequest::username() const STUB_RETVAL("stub_username")
-void Auth::UserRequest::start(AUTHCB *, void *) STUB
+void Auth::UserRequest::start(HttpRequest *, AccessLogEntry::Pointer &, AUTHCB *, void *) STUB
 bool Auth::UserRequest::valid() const STUB_RETVAL(false)
 void * Auth::UserRequest::operator new (size_t) STUB_RETVAL((void *)1)
 void Auth::UserRequest::operator delete (void *) STUB
@@ -62,8 +62,8 @@ void Auth::UserRequest::addAuthenticationInfoHeader(HttpReply *, int) STUB
 void Auth::UserRequest::addAuthenticationInfoTrailer(HttpReply *, int) STUB
 void Auth::UserRequest::releaseAuthServer() STUB
 const char * Auth::UserRequest::connLastHeader() STUB_RETVAL("stub")
-AuthAclState Auth::UserRequest::authenticate(Auth::UserRequest::Pointer *, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &) STUB_RETVAL(AUTH_AUTHENTICATED)
-AuthAclState Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &) STUB_RETVAL(AUTH_AUTHENTICATED)
+AuthAclState Auth::UserRequest::authenticate(Auth::UserRequest::Pointer *, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED)
+AuthAclState Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *, http_hdr_type, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED)
 void Auth::UserRequest::addReplyAuthHeader(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int, int) STUB
 void authenticateFixHeader(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int, int) STUB
 void authenticateAddTrailer(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int) STUB
index c44c21848b2b76f686a2a4d96b0a191f70867abe..66c6b08b8cf89bc700aaa5b86080bb298ed33eca 100644 (file)
@@ -901,7 +901,7 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr, const
                                      CommTimeoutCbPtrFun(tunnelTimeout, tunnelState));
     commSetConnTimeout(tunnelState->client.conn, Config.Timeout.lifetime, timeoutCall);
 
-    peerSelect(&(tunnelState->serverDestinations), request,
+    peerSelect(&(tunnelState->serverDestinations), request, al,
                NULL,
                tunnelPeerSelectComplete,
                tunnelState);