]> git.ipfire.org Git - thirdparty/squid.git/blame - src/auth/Config.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / auth / Config.cc
CommitLineData
f5691f9c 1/*
bde978a6 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
f5691f9c 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
f5691f9c 7 */
8
bbc27441
AJ
9/* DEBUG: section 29 Authenticator */
10
582c2af2 11#include "squid.h"
2d2b0bb7 12#include "auth/Config.h"
d8d76b36 13#include "auth/Gadgets.h"
2d2b0bb7 14#include "auth/UserRequest.h"
d4806c91
CT
15#include "cache_cf.h"
16#include "ConfigParser.h"
582c2af2 17#include "Debug.h"
d4806c91 18#include "format/Format.h"
582c2af2 19#include "globals.h"
d4806c91 20#include "Store.h"
3616c90c 21#include "wordlist.h"
f5691f9c 22
9f3d2b2e 23Auth::ConfigVector Auth::TheConfig;
5817ee13
AJ
24
25/**
9f3d2b2e
AJ
26 * Get an User credentials object filled out for the given Proxy- or WWW-Authenticate header.
27 * Any decoding which needs to be done will be done.
28 *
29 * It may be a cached AuthUser or a new Unauthenticated object.
f5691f9c 30 * It may also be NULL reflecting that no user could be created.
31 */
c7baff40 32Auth::UserRequest::Pointer
d4806c91 33Auth::Config::CreateAuthUser(const char *proxy_auth, AccessLogEntry::Pointer &al)
f5691f9c 34{
35 assert(proxy_auth != NULL);
9f3d2b2e 36 debugs(29, 9, HERE << "header = '" << proxy_auth << "'");
f5691f9c 37
9f3d2b2e 38 Auth::Config *config = Find(proxy_auth);
f5691f9c 39
40 if (config == NULL || !config->active()) {
c6cf8dee 41 debugs(29, (shutting_down?3:DBG_IMPORTANT), (shutting_down?"":"WARNING: ") <<
8add28cd 42 "Unsupported or unconfigured/inactive proxy-auth scheme, '" << proxy_auth << "'");
f5691f9c 43 return NULL;
44 }
d4806c91
CT
45 static MemBuf rmb;
46 rmb.reset();
47 if (config->keyExtras) {
48 // %credentials and %username, which normally included in
49 // request_format, are - at this time, but that is OK
50 // because user name is added to key explicitly, and we do
51 // not want to store authenticated credentials at all.
52 config->keyExtras->assemble(rmb, al, 0);
53 }
f5691f9c 54
d4806c91 55 return config->decode(proxy_auth, rmb.hasContent() ? rmb.content() : NULL);
f5691f9c 56}
57
9f3d2b2e
AJ
58Auth::Config *
59Auth::Config::Find(const char *proxy_auth)
f5691f9c 60{
9f3d2b2e 61 for (Auth::ConfigVector::iterator i = Auth::TheConfig.begin(); i != Auth::TheConfig.end(); ++i)
f5691f9c 62 if (strncasecmp(proxy_auth, (*i)->type(), strlen((*i)->type())) == 0)
63 return *i;
64
65 return NULL;
66}
62ee09ca 67
9f3d2b2e 68/** Default behaviour is to expose nothing */
62ee09ca 69void
9f3d2b2e 70Auth::Config::registerWithCacheManager(void)
62ee09ca 71{}
d4806c91
CT
72
73void
ced8def3 74Auth::Config::parse(Auth::Config * scheme, int, char *param_str)
d4806c91 75{
3616c90c
AJ
76 if (strcmp(param_str, "program") == 0) {
77 if (authenticateProgram)
78 wordlistDestroy(&authenticateProgram);
79
80 parse_wordlist(&authenticateProgram);
81
82 requirePathnameExists("Authentication helper program", authenticateProgram->key);
83
84 } else if (strcmp(param_str, "realm") == 0) {
ec980001
AJ
85 realm.clear();
86
87 char *token = ConfigParser::NextQuotedOrToEol();
88
fc3f1d5c 89 while (token && *token && xisspace(*token))
ec980001
AJ
90 ++token;
91
92 if (!token || !*token) {
93 debugs(29, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Missing auth_param " << scheme->type() << " realm");
94 self_destruct();
95 return;
96 }
97
98 realm = token;
99
100 } else if (strcmp(param_str, "children") == 0) {
0309fc40
AJ
101 authenticateChildren.parseConfig();
102
103 } else if (strcmp(param_str, "key_extras") == 0) {
d4806c91
CT
104 keyExtrasLine = ConfigParser::NextQuotedToken();
105 Format::Format *nlf = new ::Format::Format(scheme->type());
106 if (!nlf->parse(keyExtrasLine.termedBuf())) {
107 debugs(29, DBG_CRITICAL, "FATAL: Failed parsing key_extras formatting value");
108 self_destruct();
109 return;
110 }
111 if (keyExtras)
112 delete keyExtras;
113
114 keyExtras = nlf;
86c63190 115
d4806c91 116 if (char *t = strtok(NULL, w_space)) {
86c63190
AJ
117 debugs(29, DBG_CRITICAL, "FATAL: Unexpected argument '" << t << "' after request_format specification");
118 self_destruct();
d4806c91
CT
119 }
120 } else {
121 debugs(29, DBG_CRITICAL, "Unrecognised " << scheme->type() << " auth scheme parameter '" << param_str << "'");
122 }
123}
124
3616c90c
AJ
125bool
126Auth::Config::dump(StoreEntry *entry, const char *name, Auth::Config *scheme) const
d4806c91 127{
3616c90c
AJ
128 if (!authenticateProgram)
129 return false; // not configured
130
131 wordlist *list = authenticateProgram;
132 storeAppendPrintf(entry, "%s %s", name, scheme->type());
133 while (list != NULL) {
134 storeAppendPrintf(entry, " %s", list->key);
135 list = list->next;
136 }
137 storeAppendPrintf(entry, "\n");
138
ec980001
AJ
139 storeAppendPrintf(entry, "%s %s realm " SQUIDSBUFPH "\n", name, scheme->type(), SQUIDSBUFPRINT(realm));
140
0309fc40
AJ
141 storeAppendPrintf(entry, "%s %s children %d startup=%d idle=%d concurrency=%d\n",
142 name, scheme->type(),
143 authenticateChildren.n_max, authenticateChildren.n_startup,
144 authenticateChildren.n_idle, authenticateChildren.concurrency);
145
d4806c91
CT
146 if (keyExtrasLine.size() > 0)
147 storeAppendPrintf(entry, "%s %s key_extras \"%s\"\n", name, scheme->type(), keyExtrasLine.termedBuf());
3616c90c
AJ
148
149 return true;
d4806c91
CT
150}
151
152void
153Auth::Config::done()
154{
155 delete keyExtras;
86c63190 156 keyExtras = NULL;
d4806c91
CT
157 keyExtrasLine.clean();
158}
d8d76b36
FB
159
160Auth::User::Pointer
8c60f60f 161Auth::Config::findUserInCache(const char *nameKey, Auth::Type authType)
d8d76b36
FB
162{
163 AuthUserHashPointer *usernamehash;
164 debugs(29, 9, "Looking for user '" << nameKey << "'");
165
166 if (nameKey && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, nameKey)))) {
167 while (usernamehash) {
8c60f60f 168 if ((usernamehash->user()->auth_type == authType) &&
d8d76b36
FB
169 !strcmp(nameKey, (char const *)usernamehash->key))
170 return usernamehash->user();
171
172 usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
173 }
174 }
175
176 return NULL;
177}
f53969cc 178