User(Auth::Config *);
~User();
bool authenticated() const;
- void queueRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data);
- void submitRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data);
-
bool valid() const;
/** Update the cached password for a username. */
#include "auth/basic/auth_basic.h"
#include "auth/basic/User.h"
#include "auth/basic/UserRequest.h"
+#include "auth/State.h"
+#include "charset.h"
+#include "rfc1738.h"
#include "SquidTime.h"
+#if !defined(HELPER_INPUT_BUFFER)
+#define HELPER_INPUT_BUFFER 8192
+#endif
+
int
AuthBasicUserRequest::authenticated() const
{
/* check to see if the auth_user already has a request outstanding */
if (user()->credentials() == Auth::Pending) {
/* there is a request with the same credentials already being verified */
- basic_auth->queueRequest(this, handler, data);
+
+ BasicAuthQueueNode *node = static_cast<BasicAuthQueueNode *>(xcalloc(1, sizeof(BasicAuthQueueNode)));
+ assert(node);
+ node->auth_user_request = this;
+ node->handler = handler;
+ node->data = cbdataReference(data);
+
+ /* queue this validation request to be infored of the pending lookup results */
+ node->next = basic_auth->auth_queue;
+ basic_auth->auth_queue = node;
return;
}
-
- basic_auth->submitRequest(this, handler, data);
+ // otherwise submit this request to the auth helper(s) for validation
+
+ /* 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 pass[HELPER_INPUT_BUFFER];
+ if (static_cast<Auth::Basic::Config*>(user()->config)->utf8) {
+ latin1_to_utf8(username, sizeof(username), user()->username());
+ latin1_to_utf8(pass, sizeof(pass), basic_auth->passwd);
+ xstrncpy(username, rfc1738_escape(username), sizeof(username));
+ xstrncpy(pass, rfc1738_escape(pass), sizeof(pass));
+ } else {
+ xstrncpy(username, rfc1738_escape(user()->username()), sizeof(username));
+ xstrncpy(pass, rfc1738_escape(basic_auth->passwd), sizeof(pass));
+ }
+ int sz = snprintf(buf, sizeof(buf), "%s %s\n", username, pass);
+ if (sz<=0) {
+ debugs(9, DBG_CRITICAL, "ERROR: Basic Authentication Failure. Can not build helper validation request.");
+ handler(data, NULL);
+ } else if (sz>=sizeof(buf)) {
+ debugs(9, DBG_CRITICAL, "ERROR: Basic Authentication Failure. user:password exceeds " << sizeof(buf) << " bytes.");
+ handler(data, NULL);
+ } else
+ helperSubmit(basicauthenticators, buf, AuthBasicUserRequest::HandleReply,
+ new Auth::StateData(this, handler, data));
}
+void
+AuthBasicUserRequest::HandleReply(void *data, char *reply)
+{
+ Auth::StateData *r = static_cast<Auth::StateData *>(data);
+ BasicAuthQueueNode *tmpnode;
+ char *t = NULL;
+ void *cbdata;
+ debugs(29, 9, HERE << "{" << (reply ? reply : "<NULL>") << "}");
+
+ if (reply) {
+ if ((t = strchr(reply, ' ')))
+ *t++ = '\0';
+
+ if (*reply == '\0')
+ reply = NULL;
+ }
+
+ assert(r->auth_user_request != NULL);
+ assert(r->auth_user_request->user()->auth_type == Auth::AUTH_BASIC);
+
+ /* 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))
+ basic_auth->credentials(Auth::Ok);
+ else {
+ basic_auth->credentials(Auth::Failed);
+
+ if (t && *t)
+ r->auth_user_request->setDenyMessage(t);
+ }
+
+ basic_auth->expiretime = squid_curtime;
+
+ if (cbdataReferenceValidDone(r->data, &cbdata))
+ r->handler(cbdata, NULL);
+
+ 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);
+
+ xfree(basic_auth->auth_queue);
+
+ basic_auth->auth_queue = tmpnode;
+ }
+
+ delete r;
+}
virtual void authenticate(HttpRequest * request, ConnStateData *conn, http_hdr_type type);
virtual Auth::Direction module_direction();
virtual void module_start(RH *, void *);
+
+private:
+ static HLPCB HandleReply;
};
MEMPROXY_CLASS_INLINE(AuthBasicUserRequest);
#include "SquidTime.h"
/* Basic Scheme */
-static HLPCB authenticateBasicHandleReply;
static AUTHSSTATS authenticateBasicStats;
-static helper *basicauthenticators = NULL;
+helper *basicauthenticators = NULL;
static int authbasic_initialised = 0;
safe_free(basicAuthRealm);
}
-static void
-authenticateBasicHandleReply(void *data, char *reply)
-{
- Auth::StateData *r = static_cast<Auth::StateData *>(data);
- BasicAuthQueueNode *tmpnode;
- char *t = NULL;
- void *cbdata;
- debugs(29, 9, HERE << "{" << (reply ? reply : "<NULL>") << "}");
-
- if (reply) {
- if ((t = strchr(reply, ' ')))
- *t++ = '\0';
-
- if (*reply == '\0')
- reply = NULL;
- }
-
- assert(r->auth_user_request != NULL);
- assert(r->auth_user_request->user()->auth_type == Auth::AUTH_BASIC);
-
- /* 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))
- basic_auth->credentials(Auth::Ok);
- else {
- basic_auth->credentials(Auth::Failed);
-
- if (t && *t)
- r->auth_user_request->setDenyMessage(t);
- }
-
- basic_auth->expiretime = squid_curtime;
-
- if (cbdataReferenceValidDone(r->data, &cbdata))
- r->handler(cbdata, NULL);
-
- 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);
-
- xfree(basic_auth->auth_queue);
-
- basic_auth->auth_queue = tmpnode;
- }
-
- delete r;
-}
-
void
Auth::Basic::Config::dump(StoreEntry * entry, const char *name, Auth::Config * scheme)
{
"Basic User Authenticator Stats",
authenticateBasicStats, 0, 1);
}
-
-// XXX: this is a auth management function. Surely not in scope for the credentials storage object
-void
-Auth::Basic::User::queueRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data)
-{
- BasicAuthQueueNode *node;
- node = static_cast<BasicAuthQueueNode *>(xcalloc(1, sizeof(BasicAuthQueueNode)));
- assert(node);
- /* save the details */
- node->next = auth_queue;
- auth_queue = node;
- node->auth_user_request = auth_user_request;
- node->handler = handler;
- node->data = cbdataReference(data);
-}
-
-// XXX: this is a auth management function. Surely not in scope for the credentials storage object
-void
-Auth::Basic::User::submitRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data)
-{
- /* mark the user as having verification in progress */
- credentials(Auth::Pending);
- char buf[8192];
- char user[1024], pass[1024];
- if (static_cast<Auth::Basic::Config*>(config)->utf8) {
- latin1_to_utf8(user, sizeof(user), username());
- latin1_to_utf8(pass, sizeof(pass), passwd);
- xstrncpy(user, rfc1738_escape(user), sizeof(user));
- xstrncpy(pass, rfc1738_escape(pass), sizeof(pass));
- } else {
- xstrncpy(user, rfc1738_escape(username()), sizeof(user));
- xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
- }
- snprintf(buf, sizeof(buf), "%s %s\n", user, pass);
- helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply,
- new Auth::StateData(auth_user_request, handler, data));
-}
} // namespace Basic
} // namespace Auth
+extern helper *basicauthenticators;
+
#endif /* __AUTH_BASIC_H__ */