]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/auth/basic/UserRequest.cc
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / auth / basic / UserRequest.cc
index 0efa5adb5cc1067044be78862930a394ce057f34..0c885b8d43c0a90888cbbde06cfa0d26c08e88ac 100644 (file)
@@ -1,9 +1,24 @@
+/*
+ * Copyright (C) 1996-2018 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 "auth/basic/auth_basic.h"
+#include "auth/basic/Config.h"
 #include "auth/basic/User.h"
 #include "auth/basic/UserRequest.h"
+#include "auth/QueueNode.h"
 #include "auth/State.h"
 #include "charset.h"
+#include "Debug.h"
+#include "format/Format.h"
+#include "helper.h"
+#include "helper/Reply.h"
+#include "HttpRequest.h"
+#include "MemBuf.h"
 #include "rfc1738.h"
 #include "SquidTime.h"
 
@@ -22,10 +37,19 @@ 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
-Auth::Basic::UserRequest::authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type)
+Auth::Basic::UserRequest::authenticate(HttpRequest *, ConnStateData *, Http::HdrType)
 {
     assert(user() != NULL);
 
@@ -34,7 +58,7 @@ Auth::Basic::UserRequest::authenticate(HttpRequest * request, ConnStateData * co
         return;
 
     /* are we about to recheck the credentials externally? */
-    if ((user()->expiretime + static_cast<Auth::Basic::Config*>(Auth::Config::Find("basic"))->credentialsTTL) <= squid_curtime) {
+    if ((user()->expiretime + static_cast<Auth::Basic::Config*>(Auth::SchemeConfig::Find("basic"))->credentialsTTL) <= squid_curtime) {
         debugs(29, 4, HERE << "credentials expired - rechecking");
         return;
     }
@@ -45,8 +69,6 @@ Auth::Basic::UserRequest::authenticate(HttpRequest * request, ConnStateData * co
     /* Decode now takes care of finding the AuthUser struct in the cache */
     /* after external auth occurs anyway */
     user()->expiretime = current_time.tv_sec;
-
-    return;
 }
 
 Auth::Direction
@@ -63,7 +85,7 @@ Auth::Basic::UserRequest::module_direction()
         return Auth::CRED_LOOKUP;
 
     case Auth::Ok:
-        if (user()->expiretime + static_cast<Auth::Basic::Config*>(Auth::Config::Find("basic"))->credentialsTTL <= squid_curtime)
+        if (user()->expiretime + static_cast<Auth::Basic::Config*>(Auth::SchemeConfig::Find("basic"))->credentialsTTL <= squid_curtime)
             return Auth::CRED_LOOKUP;
         return Auth::CRED_VALID;
 
@@ -77,16 +99,16 @@ Auth::Basic::UserRequest::module_direction()
 
 /* send the initial data to a basic authenticator module */
 void
-Auth::Basic::UserRequest::module_start(RH * handler, void *data)
+Auth::Basic::UserRequest::startHelperLookup(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());
     assert(basic_auth != NULL);
     debugs(29, 9, HERE << "'" << basic_auth->username() << ":" << basic_auth->passwd << "'");
 
-    if (static_cast<Auth::Basic::Config*>(Auth::Config::Find("basic"))->authenticateProgram == NULL) {
+    if (static_cast<Auth::Basic::Config*>(Auth::SchemeConfig::Find("basic"))->authenticateProgram == NULL) {
         debugs(29, DBG_CRITICAL, "ERROR: No Basic authentication program configured.");
-        handler(data, NULL);
+        handler(data);
         return;
     }
 
@@ -94,15 +116,11 @@ Auth::Basic::UserRequest::module_start(RH * handler, void *data)
     if (user()->credentials() == Auth::Pending) {
         /* there is a request with the same credentials already being verified */
 
-        BasicAuthQueueNode *node = static_cast<BasicAuthQueueNode *>(xcalloc(1, sizeof(BasicAuthQueueNode)));
-        assert(node);
-        node->auth_user_request = this;
-        node->handler = handler;
-        node->data = cbdataReference(data);
+        Auth::QueueNode *node = new Auth::QueueNode(this, handler, data);
 
         /* queue this validation request to be infored of the pending lookup results */
-        node->next = basic_auth->auth_queue;
-        basic_auth->auth_queue = node;
+        node->next = basic_auth->queue;
+        basic_auth->queue = node;
         return;
     }
     // otherwise submit this request to the auth helper(s) for validation
@@ -110,81 +128,81 @@ Auth::Basic::UserRequest::module_start(RH * handler, void *data)
     /* mark this user as having verification in progress */
     user()->credentials(Auth::Pending);
     char buf[HELPER_INPUT_BUFFER];
-    static char username[HELPER_INPUT_BUFFER];
+    static char usern[HELPER_INPUT_BUFFER];
     static char pass[HELPER_INPUT_BUFFER];
     if (static_cast<Auth::Basic::Config*>(user()->config)->utf8) {
-        latin1_to_utf8(username, sizeof(username), user()->username());
+        latin1_to_utf8(usern, sizeof(usern), user()->username());
         latin1_to_utf8(pass, sizeof(pass), basic_auth->passwd);
-        xstrncpy(username, rfc1738_escape(username), sizeof(username));
+        xstrncpy(usern, rfc1738_escape(usern), sizeof(usern));
         xstrncpy(pass, rfc1738_escape(pass), sizeof(pass));
     } else {
-        xstrncpy(username, rfc1738_escape(user()->username()), sizeof(username));
+        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", username, 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, NULL);
+        handler(data);
     } else if (static_cast<size_t>(sz) >= sizeof(buf)) {
         debugs(9, DBG_CRITICAL, "ERROR: Basic Authentication Failure. user:password exceeds " << sizeof(buf) << " bytes.");
-        handler(data, NULL);
+        handler(data);
     } else
         helperSubmit(basicauthenticators, buf, Auth::Basic::UserRequest::HandleReply,
                      new Auth::StateData(this, handler, data));
 }
 
 void
-Auth::Basic::UserRequest::HandleReply(void *data, char *reply)
+Auth::Basic::UserRequest::HandleReply(void *data, const Helper::Reply &reply)
 {
     Auth::StateData *r = static_cast<Auth::StateData *>(data);
-    BasicAuthQueueNode *tmpnode;
-    char *t = NULL;
     void *cbdata;
-    debugs(29, 5, HERE << "{" << (reply ? reply : "<NULL>") << "}");
-
-    if (reply) {
-        if ((t = strchr(reply, ' ')))
-            *t++ = '\0';
-
-        if (*reply == '\0')
-            reply = NULL;
-    }
+    debugs(29, 5, HERE << "reply=" << reply);
 
     assert(r->auth_user_request != NULL);
     assert(r->auth_user_request->user()->auth_type == Auth::AUTH_BASIC);
 
+    // add new helper kv-pair notes to the credentials object
+    // so that any transaction using those credentials can access them
+    r->auth_user_request->user()->notes.appendNewOnly(&reply.notes);
+
     /* this is okay since we only play with the Auth::Basic::User child fields below
      * and dont pass the pointer itself anywhere */
     Auth::Basic::User *basic_auth = dynamic_cast<Auth::Basic::User *>(r->auth_user_request->user().getRaw());
 
     assert(basic_auth != NULL);
 
-    if (reply && (strncasecmp(reply, "OK", 2) == 0))
+    if (reply.result == Helper::Okay)
         basic_auth->credentials(Auth::Ok);
     else {
         basic_auth->credentials(Auth::Failed);
 
-        if (t && *t)
-            r->auth_user_request->setDenyMessage(t);
+        if (reply.other().hasContent())
+            r->auth_user_request->setDenyMessage(reply.other().content());
     }
 
     basic_auth->expiretime = squid_curtime;
 
     if (cbdataReferenceValidDone(r->data, &cbdata))
-        r->handler(cbdata, NULL);
+        r->handler(cbdata);
 
     cbdataReferenceDone(r->data);
 
-    while (basic_auth->auth_queue) {
-        tmpnode = basic_auth->auth_queue->next;
-
-        if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata))
-            basic_auth->auth_queue->handler(cbdata, NULL);
+    while (basic_auth->queue) {
+        if (cbdataReferenceValidDone(basic_auth->queue->data, &cbdata))
+            basic_auth->queue->handler(cbdata);
 
-        xfree(basic_auth->auth_queue);
+        Auth::QueueNode *tmpnode = basic_auth->queue->next;
+        basic_auth->queue->next = NULL;
+        delete basic_auth->queue;
 
-        basic_auth->auth_queue = tmpnode;
+        basic_auth->queue = tmpnode;
     }
 
     delete r;
 }
+