]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/basic/UserRequest.cc
2 #include "auth/basic/auth_basic.h"
3 #include "auth/basic/User.h"
4 #include "auth/basic/UserRequest.h"
5 #include "auth/State.h"
10 #if !defined(HELPER_INPUT_BUFFER)
11 #define HELPER_INPUT_BUFFER 8192
15 Auth::Basic::UserRequest::authenticated() const
17 Auth::Basic::User
const *basic_auth
= dynamic_cast<Auth::Basic::User
const *>(user().getRaw());
19 if (basic_auth
&& basic_auth
->authenticated())
25 /* log a basic user in
28 Auth::Basic::UserRequest::authenticate(HttpRequest
* request
, ConnStateData
* conn
, http_hdr_type type
)
30 assert(user() != NULL
);
32 /* if the password is not ok, do an identity */
33 if (!user() || user()->credentials() != Auth::Ok
)
36 /* are we about to recheck the credentials externally? */
37 if ((user()->expiretime
+ static_cast<Auth::Basic::Config
*>(Auth::Config::Find("basic"))->credentialsTTL
) <= squid_curtime
) {
38 debugs(29, 4, HERE
<< "credentials expired - rechecking");
42 /* we have been through the external helper, and the credentials haven't expired */
43 debugs(29, 9, HERE
<< "user '" << user()->username() << "' authenticated");
45 /* Decode now takes care of finding the AuthUser struct in the cache */
46 /* after external auth occurs anyway */
47 user()->expiretime
= current_time
.tv_sec
;
53 Auth::Basic::UserRequest::module_direction()
55 /* null auth_user is checked for by Auth::UserRequest::direction() */
56 if (user()->auth_type
!= Auth::AUTH_BASIC
)
57 return Auth::CRED_ERROR
;
59 switch (user()->credentials()) {
63 return Auth::CRED_LOOKUP
;
66 if (user()->expiretime
+ static_cast<Auth::Basic::Config
*>(Auth::Config::Find("basic"))->credentialsTTL
<= squid_curtime
)
67 return Auth::CRED_LOOKUP
;
68 return Auth::CRED_VALID
;
71 return Auth::CRED_VALID
;
74 return Auth::CRED_ERROR
;
78 /* send the initial data to a basic authenticator module */
80 Auth::Basic::UserRequest::module_start(RH
* handler
, void *data
)
82 assert(user()->auth_type
== Auth::AUTH_BASIC
);
83 Auth::Basic::User
*basic_auth
= dynamic_cast<Auth::Basic::User
*>(user().getRaw());
84 assert(basic_auth
!= NULL
);
85 debugs(29, 9, HERE
<< "'" << basic_auth
->username() << ":" << basic_auth
->passwd
<< "'");
87 if (static_cast<Auth::Basic::Config
*>(Auth::Config::Find("basic"))->authenticateProgram
== NULL
) {
88 debugs(29, DBG_CRITICAL
, "ERROR: No Basic authentication program configured.");
93 /* check to see if the auth_user already has a request outstanding */
94 if (user()->credentials() == Auth::Pending
) {
95 /* there is a request with the same credentials already being verified */
97 BasicAuthQueueNode
*node
= static_cast<BasicAuthQueueNode
*>(xcalloc(1, sizeof(BasicAuthQueueNode
)));
99 node
->auth_user_request
= this;
100 node
->handler
= handler
;
101 node
->data
= cbdataReference(data
);
103 /* queue this validation request to be infored of the pending lookup results */
104 node
->next
= basic_auth
->auth_queue
;
105 basic_auth
->auth_queue
= node
;
108 // otherwise submit this request to the auth helper(s) for validation
110 /* mark this user as having verification in progress */
111 user()->credentials(Auth::Pending
);
112 char buf
[HELPER_INPUT_BUFFER
];
113 static char username
[HELPER_INPUT_BUFFER
];
114 static char pass
[HELPER_INPUT_BUFFER
];
115 if (static_cast<Auth::Basic::Config
*>(user()->config
)->utf8
) {
116 latin1_to_utf8(username
, sizeof(username
), user()->username());
117 latin1_to_utf8(pass
, sizeof(pass
), basic_auth
->passwd
);
118 xstrncpy(username
, rfc1738_escape(username
), sizeof(username
));
119 xstrncpy(pass
, rfc1738_escape(pass
), sizeof(pass
));
121 xstrncpy(username
, rfc1738_escape(user()->username()), sizeof(username
));
122 xstrncpy(pass
, rfc1738_escape(basic_auth
->passwd
), sizeof(pass
));
124 int sz
= snprintf(buf
, sizeof(buf
), "%s %s\n", username
, pass
);
126 debugs(9, DBG_CRITICAL
, "ERROR: Basic Authentication Failure. Can not build helper validation request.");
128 } else if (static_cast<size_t>(sz
) >= sizeof(buf
)) {
129 debugs(9, DBG_CRITICAL
, "ERROR: Basic Authentication Failure. user:password exceeds " << sizeof(buf
) << " bytes.");
132 helperSubmit(basicauthenticators
, buf
, Auth::Basic::UserRequest::HandleReply
,
133 new Auth::StateData(this, handler
, data
));
137 Auth::Basic::UserRequest::HandleReply(void *data
, char *reply
)
139 Auth::StateData
*r
= static_cast<Auth::StateData
*>(data
);
140 BasicAuthQueueNode
*tmpnode
;
143 debugs(29, 5, HERE
<< "{" << (reply
? reply
: "<NULL>") << "}");
146 if ((t
= strchr(reply
, ' ')))
153 assert(r
->auth_user_request
!= NULL
);
154 assert(r
->auth_user_request
->user()->auth_type
== Auth::AUTH_BASIC
);
156 /* this is okay since we only play with the Auth::Basic::User child fields below
157 * and dont pass the pointer itself anywhere */
158 Auth::Basic::User
*basic_auth
= dynamic_cast<Auth::Basic::User
*>(r
->auth_user_request
->user().getRaw());
160 assert(basic_auth
!= NULL
);
162 if (reply
&& (strncasecmp(reply
, "OK", 2) == 0))
163 basic_auth
->credentials(Auth::Ok
);
165 basic_auth
->credentials(Auth::Failed
);
168 r
->auth_user_request
->setDenyMessage(t
);
171 basic_auth
->expiretime
= squid_curtime
;
173 if (cbdataReferenceValidDone(r
->data
, &cbdata
))
174 r
->handler(cbdata
, NULL
);
176 cbdataReferenceDone(r
->data
);
178 while (basic_auth
->auth_queue
) {
179 tmpnode
= basic_auth
->auth_queue
->next
;
181 if (cbdataReferenceValidDone(basic_auth
->auth_queue
->data
, &cbdata
))
182 basic_auth
->auth_queue
->handler(cbdata
, NULL
);
184 xfree(basic_auth
->auth_queue
);
186 basic_auth
->auth_queue
= tmpnode
;