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