@@ -140,18 +140,25 @@ ngx_http_auth_digest_handler(ngx_http_request_t *r)
140
140
ngx_int_t rc ;
141
141
ngx_err_t err ;
142
142
ngx_str_t user_file , passwd_line ;
143
- ngx_uint_t i , level , left ;
144
143
ngx_file_t file ;
144
+ ngx_uint_t i , begin , tail , idle ;
145
145
ngx_http_auth_digest_loc_conf_t * alcf ;
146
146
ngx_http_auth_digest_cred_t * auth_fields ;
147
147
u_char buf [NGX_HTTP_AUTH_DIGEST_BUF_SIZE ];
148
-
148
+ u_char line [NGX_HTTP_AUTH_DIGEST_BUF_SIZE ];
149
+ u_char * p ;
149
150
150
151
151
152
// if digest auth is disabled for this location, bail out immediately
152
153
alcf = ngx_http_get_module_loc_conf (r , ngx_http_auth_digest_module );
153
154
if (alcf -> realm .len == 0 || alcf -> user_file .value .len == 0 ) {
154
155
return NGX_DECLINED ;
156
+
157
+ //
158
+ // BUG? wait wait wait. shouldn't this be ngx_ok by default in the case
159
+ // of the former and ngx_declined in the latter?
160
+ //
161
+
155
162
}
156
163
157
164
// unpack the Authorization header (if any) and verify that it contains all
@@ -164,12 +171,13 @@ ngx_http_auth_digest_handler(ngx_http_request_t *r)
164
171
return NGX_HTTP_INTERNAL_SERVER_ERROR ;
165
172
}
166
173
167
- // read in the passwd file from disk
174
+ // check for the existence of a passwd file and attempt to open it
168
175
if (ngx_http_complex_value (r , & alcf -> user_file , & user_file ) != NGX_OK ) {
169
176
return NGX_ERROR ;
170
177
}
171
178
fd = ngx_open_file (user_file .data , NGX_FILE_RDONLY , NGX_FILE_OPEN , 0 );
172
179
if (fd == NGX_INVALID_FILE ) {
180
+ ngx_uint_t level ;
173
181
err = ngx_errno ;
174
182
175
183
if (err == NGX_ENOENT ) {
@@ -185,76 +193,72 @@ ngx_http_auth_digest_handler(ngx_http_request_t *r)
185
193
ngx_open_file_n " \"%s\" failed" , user_file .data );
186
194
return rc ;
187
195
}
188
-
189
196
ngx_memzero (& file , sizeof (ngx_file_t ));
190
-
191
197
file .fd = fd ;
192
198
file .name = user_file ;
193
199
file .log = r -> connection -> log ;
194
200
195
- // parse through the passwd file and find the individual lines, then pass them off
201
+ // step through the passwd file and find the individual lines, then pass them off
196
202
// to be compared against the values in the authorization header
197
- left = offset = 0 ;
203
+ passwd_line .data = line ;
204
+ offset = begin = tail = 0 ;
205
+ idle = 1 ;
206
+ ngx_memzero (buf , NGX_HTTP_AUTH_DIGEST_BUF_SIZE );
207
+ ngx_memzero (passwd_line .data , NGX_HTTP_AUTH_DIGEST_BUF_SIZE );
198
208
while (1 ){
199
- n = ngx_read_file (& file , buf + left , NGX_HTTP_AUTH_DIGEST_BUF_SIZE - left , offset );
200
-
201
- if (n == 0 ){
202
- ngx_str_t remain ;
203
- remain .len = left ;
204
- remain .data = buf ;
205
- remain .data [left ] = '\0' ;
206
-
207
- rc = ngx_http_auth_digest_verify_user (r , auth_fields , & remain );
208
- if (rc != NGX_DECLINED ){
209
- ngx_http_auth_digest_close (& file );
210
- return rc ;
211
- }
212
-
213
- break ;
214
- }
215
-
209
+ n = ngx_read_file (& file , buf + tail , NGX_HTTP_AUTH_DIGEST_BUF_SIZE - tail , offset );
216
210
if (n == NGX_ERROR ) {
217
211
ngx_http_auth_digest_close (& file );
218
212
return NGX_HTTP_INTERNAL_SERVER_ERROR ;
219
213
}
220
-
221
- left = 0 ;
222
- for (i = left ; i < (ngx_uint_t )n ; i ++ ){
223
- if (i == left && (buf [i ]== CR || buf [i ]== LF || buf [i ]== '\0' )){
224
- left ++ ;
225
- continue ;
226
- }
227
-
228
- if (buf [i ] == CR || buf [i ] == LF ){
229
- u_char * p ;
230
- passwd_line .len = i - left + 1 ;
231
- passwd_line .data = ngx_pcalloc (r -> pool , passwd_line .len );
232
- if (passwd_line .data == NULL ){
233
- ngx_http_auth_digest_close (& file );
234
- return NGX_HTTP_INTERNAL_SERVER_ERROR ;
214
+
215
+ begin = 0 ;
216
+ for (i = 0 ; i < n + tail ; i ++ ){
217
+ if (buf [i ] == '\n' || buf [i ] == '\r' ){
218
+ if (!idle && i - begin > 36 ){ // 36 is the min length with a single-char name and realm
219
+ p = ngx_cpymem (passwd_line .data , & buf [begin ], i - begin );
220
+ p [0 ] = '\0' ;
221
+ passwd_line .len = i - begin ;
222
+ rc = ngx_http_auth_digest_verify_user (r , auth_fields , & passwd_line );
223
+ if (rc != NGX_DECLINED ){
224
+ ngx_http_auth_digest_close (& file );
225
+ return rc ;
226
+ }
235
227
}
236
- p = ngx_cpymem (passwd_line .data , & buf [left ], i - left );
237
-
228
+ idle = 1 ;
229
+ begin = i ;
230
+ }else if (idle ){
231
+ idle = 0 ;
232
+ begin = i ;
233
+ }
234
+ }
235
+
236
+ if (!idle ){
237
+ tail = n + tail - begin ;
238
+ if (n == 0 && tail > 36 ){
239
+ p = ngx_cpymem (passwd_line .data , & buf [begin ], tail );
240
+ p [0 ] = '\0' ;
241
+ passwd_line .len = i - begin ;
238
242
rc = ngx_http_auth_digest_verify_user (r , auth_fields , & passwd_line );
239
243
if (rc != NGX_DECLINED ){
240
244
ngx_http_auth_digest_close (& file );
241
245
return rc ;
242
- }
243
- left = i + 1 ;
246
+ }
247
+ }else {
248
+ ngx_memmove (buf , & buf [begin ], tail );
244
249
}
245
250
}
251
+
252
+ if (n == 0 ){
253
+ break ;
254
+ }
246
255
247
- if (left <=(ngx_uint_t )n ){
248
- ngx_memmove (buf , & buf [left ], n - left );
249
- left = n - left ;
250
- }else {
251
- left = 0 ;
252
- }
253
- offset += n ;
256
+ offset += n ;
254
257
}
258
+
255
259
ngx_http_auth_digest_close (& file );
256
260
257
- // no match was found based on the fields in the authorization header.
261
+ // since no match was found based on the fields in the authorization header,
258
262
// send a new challenge and let the client retry
259
263
return ngx_http_auth_digest_send_challenge (r , & alcf -> realm , auth_fields -> stale );
260
264
}
0 commit comments