SchemeConfig.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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/Stream.h"
19#include "errorpage.h"
20#include "format/Format.h"
21#include "globals.h"
22#include "Store.h"
23#include "wordlist.h"
24
34{
35 assert(proxy_auth != nullptr);
36 debugs(29, 9, "header = '" << proxy_auth << "'");
37
38 Auth::SchemeConfig *config = Find(proxy_auth);
39
40 if (config == nullptr || !config->active()) {
41 debugs(29, (shutting_down?3:DBG_IMPORTANT), (shutting_down?"":"WARNING: ") <<
42 "Unsupported or unconfigured/inactive proxy-auth scheme, '" << proxy_auth << "'");
43 return nullptr;
44 }
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 }
54
55 return config->decode(proxy_auth, al->request, rmb.hasContent() ? rmb.content() : nullptr);
56}
57
59Auth::SchemeConfig::Find(const char *proxy_auth)
60{
61 for (auto *scheme : Auth::TheConfig.schemes) {
62 if (strncasecmp(proxy_auth, scheme->type(), strlen(scheme->type())) == 0)
63 return scheme;
64 }
65
66 return nullptr;
67}
68
70Auth::SchemeConfig::GetParsed(const char *proxy_auth)
71{
72 if (auto *cfg = Find(proxy_auth))
73 return cfg;
74 fatalf("auth_schemes: required authentication method '%s' is not configured", proxy_auth);
75 return nullptr;
76}
77
79void
81{}
82
83void
84Auth::SchemeConfig::parse(Auth::SchemeConfig * scheme, int, char *param_str)
85{
86 if (strcmp(param_str, "program") == 0) {
87 if (authenticateProgram)
88 wordlistDestroy(&authenticateProgram);
89
90 parse_wordlist(&authenticateProgram);
91
92 requirePathnameExists("Authentication helper program", authenticateProgram->key);
93
94 } else if (strcmp(param_str, "realm") == 0) {
95 realm.clear();
96
97 char *token = ConfigParser::NextQuotedOrToEol();
98
99 while (token && *token && xisspace(*token))
100 ++token;
101
102 if (!token || !*token) {
103 debugs(29, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Missing auth_param " << scheme->type() << " realm");
105 return;
106 }
107
108 realm = token;
109
110 } else if (strcmp(param_str, "children") == 0) {
111 authenticateChildren.parseConfig();
112
113 } else if (strcmp(param_str, "key_extras") == 0) {
114 keyExtrasLine = ConfigParser::NextQuotedToken();
115 Format::Format *nlf = new ::Format::Format(scheme->type());
116 if (!nlf->parse(keyExtrasLine.termedBuf())) {
117 debugs(29, DBG_CRITICAL, "FATAL: Failed parsing key_extras formatting value");
119 return;
120 }
121 if (keyExtras)
122 delete keyExtras;
123
124 keyExtras = nlf;
125
126 if (char *t = strtok(nullptr, w_space)) {
127 debugs(29, DBG_CRITICAL, "FATAL: Unexpected argument '" << t << "' after request_format specification");
129 }
130 } else if (strcmp(param_str, "keep_alive") == 0) {
131 parse_onoff(&keep_alive);
132 } else if (strcmp(param_str, "utf8") == 0) {
133 parse_onoff(&utf8);
134 } else {
135 debugs(29, DBG_CRITICAL, "ERROR: Unrecognised " << scheme->type() << " auth scheme parameter '" << param_str << "'");
136 }
137}
138
139bool
140Auth::SchemeConfig::dump(StoreEntry *entry, const char *name, Auth::SchemeConfig *scheme) const
141{
142 if (!authenticateProgram)
143 return false; // not configured
144
145 const char *schemeType = scheme->type();
146
147 wordlist *list = authenticateProgram;
148 storeAppendPrintf(entry, "%s %s", name, schemeType);
149 while (list != nullptr) {
150 storeAppendPrintf(entry, " %s", list->key);
151 list = list->next;
152 }
153 storeAppendPrintf(entry, "\n");
154
155 storeAppendPrintf(entry, "%s %s realm " SQUIDSBUFPH "\n", name, schemeType, SQUIDSBUFPRINT(realm));
156
157 storeAppendPrintf(entry, "%s %s children %d startup=%d idle=%d concurrency=%d\n",
158 name, schemeType,
159 authenticateChildren.n_max, authenticateChildren.n_startup,
160 authenticateChildren.n_idle, authenticateChildren.concurrency);
161
162 if (keyExtrasLine.size() > 0) // default is none
163 storeAppendPrintf(entry, "%s %s key_extras \"%s\"\n", name, schemeType, keyExtrasLine.termedBuf());
164
165 if (!keep_alive) // default is on
166 storeAppendPrintf(entry, "%s %s keep_alive off\n", name, schemeType);
167
168 if (utf8) // default is off
169 storeAppendPrintf(entry, "%s %s utf8 on\n", name, schemeType);
170
171 return true;
172}
173
174void
176{
177 delete keyExtras;
178 keyExtras = nullptr;
179 keyExtrasLine.clean();
180}
181
182bool
184{
185 String hdr;
186
187 if (!request || !request->header.getList(Http::HdrType::ACCEPT_LANGUAGE, &hdr))
188 return false;
189
190 char lang[256];
191 size_t pos = 0; // current parsing position in header string
192
193 while (strHdrAcptLangGetItem(hdr, lang, 256, pos)) {
194
195 /* wildcard uses the configured default language */
196 if (lang[0] == '*' && lang[1] == '\0')
197 return false;
198
199 if ((strncmp(lang, "ru", 2) == 0 // Russian
200 || strncmp(lang, "uk", 2) == 0 // Ukrainian
201 || strncmp(lang, "be", 2) == 0 // Belorussian
202 || strncmp(lang, "bg", 2) == 0 // Bulgarian
203 || strncmp(lang, "sr", 2) == 0)) { // Serbian
204 if (lang[2] == '-') {
205 if (strcmp(lang + 3, "latn") == 0) // not Cyrillic
206 return false;
207 } else if (xisalpha(lang[2])) {
208 return false;
209 }
210
211 return true;
212 }
213 }
214
215 return false;
216}
217
#define SQUIDSBUFPH
Definition: SBuf.h:31
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
#define assert(EX)
Definition: assert.h:17
void parse_onoff(int *var)
Definition: cache_cf.cc:2586
void parse_wordlist(wordlist **list)
Definition: cache_cf.cc:3140
void requirePathnameExists(const char *name, const char *path)
Definition: cache_cf.cc:3929
void self_destruct(void)
Definition: cache_cf.cc:277
HttpRequest * request
bool isCP1251EncodingAllowed(const HttpRequest *request)
virtual bool active() const =0
virtual void registerWithCacheManager(void)
Definition: SchemeConfig.cc:80
virtual void done()
virtual UserRequest::Pointer decode(char const *proxy_auth, const HttpRequest *request, const char *requestRealm)=0
virtual bool dump(StoreEntry *, const char *, SchemeConfig *) const
static SchemeConfig * GetParsed(const char *proxy_auth)
Definition: SchemeConfig.cc:70
Format::Format * keyExtras
The compiled request format.
Definition: SchemeConfig.h:131
virtual void parse(SchemeConfig *, int, char *)
Definition: SchemeConfig.cc:84
virtual const char * type() const =0
static SchemeConfig * Find(const char *proxy_auth)
Definition: SchemeConfig.cc:59
static UserRequest::Pointer CreateAuthUser(const char *proxy_auth, AccessLogEntry::Pointer &al)
Definition: SchemeConfig.cc:33
static char * NextQuotedToken()
static char * NextQuotedOrToEol()
bool parse(const char *def)
Definition: Format.cc:66
void assemble(MemBuf &mb, const AccessLogEntryPointer &al, int logSequenceNumber) const
assemble the state information into a formatted line.
Definition: Format.cc:377
String getList(Http::HdrType id) const
Definition: HttpHeader.cc:789
HttpHeader header
Definition: Message.h:74
Definition: MemBuf.h:24
char * content()
start of the added data
Definition: MemBuf.h:41
void reset()
Definition: MemBuf.cc:129
bool hasContent() const
Definition: MemBuf.h:54
char * key
Definition: wordlist.h:32
wordlist * next
Definition: wordlist.h:33
#define w_space
#define DBG_PARSE_NOTE(x)
Definition: Stream.h:42
#define DBG_IMPORTANT
Definition: Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define DBG_CRITICAL
Definition: Stream.h:37
bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos)
Definition: errorpage.cc:465
void fatalf(const char *fmt,...)
Definition: fatal.cc:68
int shutting_down
Auth::Config TheConfig
Definition: Config.cc:15
@ ACCEPT_LANGUAGE
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:841
void wordlistDestroy(wordlist **list)
destroy a wordlist
Definition: wordlist.cc:16
#define xisspace(x)
Definition: xis.h:15
#define xisalpha(x)
Definition: xis.h:21

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors