]> git.pld-linux.org Git - packages/squid.git/blame - squid-2.5.STABLE2-digest_nonce_count.patch
- added security patches from squids site:
[packages/squid.git] / squid-2.5.STABLE2-digest_nonce_count.patch
CommitLineData
15a12fe5
MW
1Index: squid/src/cf.data.pre
2diff -c squid/src/cf.data.pre:1.245.2.41 squid/src/cf.data.pre:1.245.2.42
3*** squid/src/cf.data.pre:1.245.2.41 Sat Apr 26 18:33:17 2003
4--- squid/src/cf.data.pre Sun May 18 15:49:19 2003
5***************
6*** 1351,1360 ****
7 used.
8
9 "nonce_strictness" on|off
10! Determines if squid requires increment-by-1 behaviour for
11! nonce counts (on - the default), or strictly incrementing
12! (off - for use when useragents generate nonce counts that
13! occasionally miss 1 (ie, 1,2,4,6)).
14
15 === NTLM scheme options follow ===
16
17--- 1351,1371 ----
18 used.
19
20 "nonce_strictness" on|off
21! Determines if squid requires strict increment-by-1 behaviour
22! for nonce counts, or just incrementing (off - for use when
23! useragents generate nonce counts that occasionally miss 1
24! (ie, 1,2,4,6)). Default off.
25!
26! "check_nonce_count" on|off
27! This directive if set to off can disable the nonce count check
28! completely to work around buggy digest qop implementations in
29! certain mainstream browser versions. Default on to check the
30! nonce count to protect from authentication replay attacks.
31!
32! "post_workaround" on|off
33! This is a workaround to certain buggy browsers who sends
34! an incorrect request digest in POST requests when reusing
35! the same nonce as aquired earlier on a GET request.
36
37 === NTLM scheme options follow ===
38
39Index: squid/src/authenticate.c
40diff -c squid/src/authenticate.c:1.36.2.9 squid/src/authenticate.c:1.36.2.10
41*** squid/src/authenticate.c:1.36.2.9 Sun May 11 15:44:31 2003
42--- squid/src/authenticate.c Sun May 18 15:49:19 2003
43***************
44*** 538,543 ****
45--- 538,549 ----
46 conn, headertype);
47 switch (authenticateDirection(*auth_user_request)) {
48 case 1:
49+ if (!request->auth_user_request) {
50+ /* lock the user for the request structure link */
51+ authenticateAuthUserRequestLock(*auth_user_request);
52+ request->auth_user_request = *auth_user_request;
53+ }
54+ /* fallthrough to -2 */
55 case -2:
56 /* this ACL check is finished. Unlock. */
57 authenticateAuthUserRequestUnlock(*auth_user_request);
58Index: squid/src/auth/digest/auth_digest.h
59diff -c squid/src/auth/digest/auth_digest.h:1.5.2.2 squid/src/auth/digest/auth_digest.h:1.5.2.3
60*** squid/src/auth/digest/auth_digest.h:1.5.2.2 Thu Feb 27 01:19:24 2003
61--- squid/src/auth/digest/auth_digest.h Sun May 18 15:49:20 2003
62***************
63*** 42,48 ****
64 char *response;
65 struct {
66 unsigned int authinfo_sent:1;
67! unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed */
68 } flags;
69 digest_nonce_h *nonce;
70 };
71--- 42,49 ----
72 char *response;
73 struct {
74 unsigned int authinfo_sent:1;
75! unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=helper,3=failed */
76! unsigned int nonce_stale:1;
77 } flags;
78 digest_nonce_h *nonce;
79 };
80***************
81*** 81,86 ****
82--- 82,89 ----
83 time_t noncemaxduration;
84 int noncemaxuses;
85 int NonceStrictness;
86+ int CheckNonceCount;
87+ int PostWorkaround;
88 };
89
90 typedef struct _auth_digest_config auth_digest_config;
91Index: squid/src/auth/digest/auth_digest.c
92diff -c squid/src/auth/digest/auth_digest.c:1.10.2.5 squid/src/auth/digest/auth_digest.c:1.10.2.6
93*** squid/src/auth/digest/auth_digest.c:1.10.2.5 Thu Feb 27 01:19:24 2003
94--- squid/src/auth/digest/auth_digest.c Sun May 18 15:49:20 2003
95***************
96*** 343,359 ****
97 if (!nonce)
98 return 0;
99 intnc = strtol(nc, NULL, 16);
100 if ((digestConfig->NonceStrictness && intnc != nonce->nc + 1) ||
101 intnc < nonce->nc + 1) {
102 debug(29, 4) ("authDigestNonceIsValid: Nonce count doesn't match\n");
103 nonce->flags.valid = 0;
104 return 0;
105 }
106- /* has it already been invalidated ? */
107- if (!nonce->flags.valid) {
108- debug(29, 4) ("authDigestNonceIsValid: Nonce already invalidated\n");
109- return 0;
110- }
111 /* seems ok */
112 /* increment the nonce count - we've already checked that intnc is a
113 * valid representation for us, so we don't need the test here.
114--- 343,364 ----
115 if (!nonce)
116 return 0;
117 intnc = strtol(nc, NULL, 16);
118+ /* has it already been invalidated ? */
119+ if (!nonce->flags.valid) {
120+ debug(29, 4) ("authDigestNonceIsValid: Nonce already invalidated\n");
121+ return 0;
122+ }
123+ /* is the nonce-count ok ? */
124+ if (!digestConfig->CheckNonceCount) {
125+ nonce->nc++;
126+ return -1; /* forced OK by configuration */
127+ }
128 if ((digestConfig->NonceStrictness && intnc != nonce->nc + 1) ||
129 intnc < nonce->nc + 1) {
130 debug(29, 4) ("authDigestNonceIsValid: Nonce count doesn't match\n");
131 nonce->flags.valid = 0;
132 return 0;
133 }
134 /* seems ok */
135 /* increment the nonce count - we've already checked that intnc is a
136 * valid representation for us, so we don't need the test here.
137***************
138*** 691,701 ****
139 "squid is = '%s'\n", digest_request->response, Response);
140
141 if (strcasecmp(digest_request->response, Response)) {
142 digest_request->flags.credentials_ok = 3;
143 return;
144 }
145- digest_request->flags.credentials_ok = 1;
146 /* password was checked and did match */
147 debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n",
148 digest_user->username);
149
150--- 696,739 ----
151 "squid is = '%s'\n", digest_request->response, Response);
152
153 if (strcasecmp(digest_request->response, Response)) {
154+ if (digestConfig->PostWorkaround && request->method != METHOD_GET) {
155+ /* Ugly workaround for certain very broken browsers using the
156+ * wrong method to calculate the request-digest on POST request.
157+ * This should be deleted once Digest authentication becomes more
158+ * widespread and such broken browsers no longer are commonly
159+ * used.
160+ */
161+ DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceb64(digest_request->nonce),
162+ digest_request->nc, digest_request->cnonce, digest_request->qop,
163+ RequestMethodStr[METHOD_GET], digest_request->uri, HA2, Response);
164+ if (strcasecmp(digest_request->response, Response)) {
165+ digest_request->flags.credentials_ok = 3;
166+ return;
167+ } else {
168+ const char *useragent = httpHeaderGetStr(&request->header, HDR_USER_AGENT);
169+ static struct in_addr last_broken_addr =
170+ {0};
171+ if (memcmp(&last_broken_addr, &request->client_addr, sizeof(last_broken_addr)) != 0) {
172+ debug(29, 1) ("\nDigest POST bug detected from %s using '%s'. Please upgrade browser. See Bug #630 for details.\n", inet_ntoa(request->client_addr), useragent ? useragent : "-");
173+ last_broken_addr = request->client_addr;
174+ }
175+ }
176+ } else {
177+ digest_request->flags.credentials_ok = 3;
178+ return;
179+ }
180+ }
181+ /* check for stale nonce */
182+ if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc)) {
183+ debug(29, 3) ("authenticateDigestAuthenticateuser: user '%s' validated OK but nonce stale\n",
184+ digest_user->username);
185+ digest_request->flags.nonce_stale = 1;
186 digest_request->flags.credentials_ok = 3;
187 return;
188 }
189 /* password was checked and did match */
190+ digest_request->flags.credentials_ok = 1;
191+
192 debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n",
193 digest_user->username);
194
195***************
196*** 714,726 ****
197 case 0: /* not checked */
198 return -1;
199 case 1: /* checked & ok */
200- if (authDigestNonceIsStale(digest_request->nonce))
201- /* send stale response to the client agent */
202- return -2;
203 return 0;
204 case 2: /* partway through checking. */
205 return -1;
206 case 3: /* authentication process failed. */
207 return -2;
208 }
209 return -2;
210--- 752,764 ----
211 case 0: /* not checked */
212 return -1;
213 case 1: /* checked & ok */
214 return 0;
215 case 2: /* partway through checking. */
216 return -1;
217 case 3: /* authentication process failed. */
218+ if (digest_request->flags.nonce_stale)
219+ /* nonce is stale, send new challenge */
220+ return 1;
221 return -2;
222 }
223 return -2;
224***************
225*** 787,795 ****
226 digest_request_h *digest_request;
227 int stale = 0;
228 digest_nonce_h *nonce = authenticateDigestNonceNew();
229! if (auth_user_request && auth_user_request->scheme_data && authDigestAuthenticated(auth_user_request)) {
230 digest_request = auth_user_request->scheme_data;
231! stale = authDigestNonceIsStale(digest_request->nonce);
232 }
233 if (digestConfig->authenticate) {
234 debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");
235--- 825,833 ----
236 digest_request_h *digest_request;
237 int stale = 0;
238 digest_nonce_h *nonce = authenticateDigestNonceNew();
239! if (auth_user_request && auth_user_request->scheme_data) {
240 digest_request = auth_user_request->scheme_data;
241! stale = digest_request->flags.nonce_stale;
242 }
243 if (digestConfig->authenticate) {
244 debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");
245***************
246*** 915,922 ****
247 digestConfig->noncemaxduration = 30 * 60;
248 /* 50 requests */
249 digestConfig->noncemaxuses = 50;
250! /* strict nonce count behaviour */
251! digestConfig->NonceStrictness = 1;
252 }
253 digestConfig = scheme->scheme_data;
254 if (strcasecmp(param_str, "program") == 0) {
255--- 953,962 ----
256 digestConfig->noncemaxduration = 30 * 60;
257 /* 50 requests */
258 digestConfig->noncemaxuses = 50;
259! /* Not strict nonce count behaviour */
260! digestConfig->NonceStrictness = 0;
261! /* Verify nonce count */
262! digestConfig->CheckNonceCount = 1;
263 }
264 digestConfig = scheme->scheme_data;
265 if (strcasecmp(param_str, "program") == 0) {
266***************
267*** 936,941 ****
268--- 976,985 ----
269 parse_int(&digestConfig->noncemaxuses);
270 } else if (strcasecmp(param_str, "nonce_strictness") == 0) {
271 parse_onoff(&digestConfig->NonceStrictness);
272+ } else if (strcasecmp(param_str, "check_nonce_count") == 0) {
273+ parse_onoff(&digestConfig->CheckNonceCount);
274+ } else if (strcasecmp(param_str, "post_workaround") == 0) {
275+ parse_onoff(&digestConfig->PostWorkaround);
276 } else {
277 debug(28, 0) ("unrecognised digest auth scheme parameter '%s'\n", param_str);
278 }
279***************
280*** 1184,1190 ****
281 }
282 /* now the nonce */
283 nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
284! if ((nonce == NULL) || !(authDigestNonceIsValid(nonce, digest_request->nc))) {
285 /* we couldn't find a matching nonce! */
286 debug(29, 4) ("authenticateDigestDecode: Unexpected or invalid nonce recieved\n");
287 authDigestLogUsername(auth_user_request, username);
288--- 1228,1234 ----
289 }
290 /* now the nonce */
291 nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
292! if (!nonce) {
293 /* we couldn't find a matching nonce! */
294 debug(29, 4) ("authenticateDigestDecode: Unexpected or invalid nonce recieved\n");
295 authDigestLogUsername(auth_user_request, username);
This page took 0.08942 seconds and 4 git commands to generate.