]> git.pld-linux.org Git - packages/squid.git/blob - squid-2.5.STABLE2-digest_nonce_count.patch
- grant stats user (statistics generators) access to squid logs
[packages/squid.git] / squid-2.5.STABLE2-digest_nonce_count.patch
1 Index: squid/src/cf.data.pre
2 diff -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   
39 Index: squid/src/authenticate.c
40 diff -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);
58 Index: squid/src/auth/digest/auth_digest.h
59 diff -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;
91 Index: squid/src/auth/digest/auth_digest.c
92 diff -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.047963 seconds and 3 git commands to generate.