]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/AclMaxUserIp.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / auth / AclMaxUserIp.cc
1 /*
2 * Copyright (C) 1996-2015 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 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/FilledChecklist.h"
13 #include "auth/Acl.h"
14 #include "auth/AclMaxUserIp.h"
15 #include "auth/UserRequest.h"
16 #include "ConfigParser.h"
17 #include "Debug.h"
18 #include "Parsing.h"
19 #include "wordlist.h"
20
21 ACLFlag ACLMaxUserIP::SupportedFlags[] = {ACL_F_STRICT, ACL_F_END};
22
23 ACLMaxUserIP::ACLMaxUserIP(char const *theClass) :
24 ACL(SupportedFlags),
25 class_(theClass),
26 maximum(0)
27 {}
28
29 ACLMaxUserIP::ACLMaxUserIP(ACLMaxUserIP const &old) :
30 class_(old.class_),
31 maximum(old.maximum)
32 {
33 flags = old.flags;
34 }
35
36 ACLMaxUserIP::~ACLMaxUserIP()
37 {}
38
39 ACL *
40 ACLMaxUserIP::clone() const
41 {
42 return new ACLMaxUserIP(*this);
43 }
44
45 char const *
46 ACLMaxUserIP::typeString() const
47 {
48 return class_;
49 }
50
51 bool
52 ACLMaxUserIP::empty() const
53 {
54 return false;
55 }
56
57 bool
58 ACLMaxUserIP::valid() const
59 {
60 return maximum > 0;
61 }
62
63 void
64 ACLMaxUserIP::parse()
65 {
66 if (maximum) {
67 debugs(28, DBG_IMPORTANT, "Attempting to alter already set User max IP acl");
68 return;
69 }
70
71 char *t = ConfigParser::strtokFile();
72
73 if (!t)
74 return;
75
76 debugs(28, 5, "aclParseUserMaxIP: First token is " << t);
77
78 maximum = xatoi(t);
79
80 debugs(28, 5, "aclParseUserMaxIP: Max IP address's " << maximum);
81
82 return;
83 }
84
85 /*
86 * aclMatchUserMaxIP - check for users logging in from multiple IP's
87 * 0 : No match
88 * 1 : Match
89 */
90 int
91 ACLMaxUserIP::match(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &src_addr)
92 {
93 /*
94 * the logic for flush the ip list when the limit is hit vs keep
95 * it sorted in most recent access order and just drop the oldest
96 * one off is currently undecided (RBC)
97 */
98
99 if (authenticateAuthUserRequestIPCount(auth_user_request) <= maximum)
100 return 0;
101
102 debugs(28, DBG_IMPORTANT, "aclMatchUserMaxIP: user '" << auth_user_request->username() << "' tries to use too many IP addresses (max " << maximum << " allowed)!");
103
104 /* this is a match */
105 if (flags.isSet(ACL_F_STRICT)) {
106 /*
107 * simply deny access - the user name is already associated with
108 * the request
109 */
110 /* remove _this_ ip, as it is the culprit for going over the limit */
111 authenticateAuthUserRequestRemoveIp(auth_user_request, src_addr);
112 debugs(28, 4, "aclMatchUserMaxIP: Denying access in strict mode");
113 } else {
114 /*
115 * non-strict - remove some/all of the cached entries
116 * ie to allow the user to move machines easily
117 */
118 authenticateAuthUserRequestClearIp(auth_user_request);
119 debugs(28, 4, "aclMatchUserMaxIP: Denying access in non-strict mode - flushing the user ip cache");
120 }
121
122 return 1;
123 }
124
125 int
126 ACLMaxUserIP::match(ACLChecklist *cl)
127 {
128 ACLFilledChecklist *checklist = Filled(cl);
129 allow_t answer = AuthenticateAcl(checklist);
130 int ti;
131
132 // convert to tri-state ACL match 1,0,-1
133 switch (answer) {
134 case ACCESS_ALLOWED:
135 // check for a match
136 ti = match(checklist->auth_user_request, checklist->src_addr);
137 checklist->auth_user_request = NULL;
138 return ti;
139
140 case ACCESS_DENIED:
141 return 0; // non-match
142
143 case ACCESS_DUNNO:
144 case ACCESS_AUTH_REQUIRED:
145 default:
146 // If the answer is not allowed or denied (matches/not matches) and
147 // async authentication is not in progress, then we are done.
148 if (checklist->keepMatching())
149 checklist->markFinished(answer, "AuthenticateAcl exception");
150 return -1; // other
151 }
152 }
153
154 SBufList
155 ACLMaxUserIP::dump() const
156 {
157 SBufList sl;
158 if (!maximum)
159 return sl;
160 SBuf s;
161 s.Printf("%d", maximum);
162 sl.push_back(s);
163 return sl;
164 }
165