Ticket #322: fastcgi-authorizer-fixes.diff
| File fastcgi-authorizer-fixes.diff, 6.6 kB (added by maherb, 2 years ago) |
|---|
-
src/mod_fastcgi.c
1386 1386 1387 1387 host->min_procs = 1; 1388 1388 host->max_procs = 1; 1389 1389 } 1390 1390 1391 1391 if (!buffer_is_empty(fcgi_mode)) { 1392 1392 if (strcmp(fcgi_mode->ptr, "responder") == 0) { 1393 1393 host->mode = FCGI_RESPONDER; 1394 1394 } else if (strcmp(fcgi_mode->ptr, "authorizer") == 0) { 1395 1395 host->mode = FCGI_AUTHORIZER; 1396 if (buffer_is_empty(host->docroot)) {1397 log_error_write(srv, __FILE__, __LINE__, "s",1398 "ERROR: docroot is required for authorizer mode.");1399 return HANDLER_ERROR;1400 }1401 1396 } else { 1402 1397 log_error_write(srv, __FILE__, __LINE__, "sbs", 1403 1398 "WARNING: unknown fastcgi mode:", 1404 1399 fcgi_mode, "(ignored, mode set to responder)"); 1405 1400 } 1406 1401 } 1407 1402 1408 1403 /* if extension already exists, take it */ 1409 1404 fastcgi_extension_insert(s->exts, da_ext->key, host); 1410 1405 } … … 2037 2032 fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0); 2038 2033 buffer_append_memory(b, (const char *)&header, sizeof(header)); 2039 2034 buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used); 2040 2035 2041 2036 fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0); 2042 2037 buffer_append_memory(b, (const char *)&header, sizeof(header)); 2043 2038 2044 2039 b->used++; /* add virtual \0 */ 2045 2040 hctx->wb->bytes_in += b->used - 1; 2046 2041 2047 if (con->request.content_length ) {2042 if (con->request.content_length && host->mode != FCGI_AUTHORIZER) { 2048 2043 chunkqueue *req_cq = con->request_content_queue; 2049 2044 chunk *req_c; 2050 2045 off_t offset; 2051 2046 2052 2047 /* something to send ? */ 2053 2048 for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; ) { 2054 2049 off_t weWant = req_cq->bytes_in - offset > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : req_cq->bytes_in - offset; 2055 2050 off_t written = 0; 2056 2051 off_t weHave = 0; 2057 2052 … … 2267 2262 if (0 == strncasecmp(key, "Content-Length", key_len)) { 2268 2263 con->response.content_length = strtol(value, NULL, 10); 2269 2264 con->parsed_response |= HTTP_CONTENT_LENGTH; 2270 2265 2271 2266 if (con->response.content_length < 0) con->response.content_length = 0; 2272 2267 } 2273 2268 break; 2274 2269 default: 2275 2270 break; 2276 2271 } 2272 if ( host->mode == FCGI_AUTHORIZER && 2273 key_len > 9 && 2274 0 == strncasecmp(key, CONST_STR_LEN("Variable-")) ) 2275 { 2276 if ( key_len == 20 && 0 == strncasecmp(key, CONST_STR_LEN("Variable-REMOTE_USER")) ) { 2277 buffer_copy_string(con->authed_user, value); 2278 } else { 2279 if (NULL == (ds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) { 2280 ds = data_response_init(); 2281 } 2282 buffer_copy_string_len(ds->key, key + 9, key_len - 9); 2283 buffer_copy_string(ds->value, value); 2284 2285 array_insert_unique(con->environment, (data_unset *)ds); 2286 } 2287 } 2277 2288 } 2278 2289 2279 2290 /* CGI/1.1 rev 03 - 7.2.1.2 */ 2280 2291 if ((con->parsed_response & HTTP_LOCATION) && 2281 2292 !(con->parsed_response & HTTP_STATUS)) { 2282 2293 con->http_status = 302; 2283 2294 } 2284 2295 2285 2296 return 0; 2286 2297 } … … 3130 3141 3131 3142 if (host->mode == FCGI_AUTHORIZER && 3132 3143 (con->http_status == 200 || 3133 3144 con->http_status == 0)) { 3134 3145 /* 3135 3146 * If we are here in AUTHORIZER mode then a request for autorizer 3136 3147 * was proceeded already, and status 200 has been returned. We need 3137 3148 * now to handle autorized request. 3138 3149 */ 3139 3150 3140 buffer_copy_string_buffer(con->physical.doc_root, host->docroot); 3151 if ( ! buffer_is_empty(host->docroot) ) { 3152 /* 3153 * Serve local file if they specified 3154 * a docroot 3155 */ 3156 buffer_copy_string_buffer(con->physical.doc_root, host->docroot); 3157 3158 buffer_copy_string_buffer(con->physical.path, host->docroot); 3159 buffer_append_string_buffer(con->physical.path, con->uri.path); 3160 fcgi_connection_close(srv, hctx); 3141 3161 3142 buffer_copy_string_buffer(con->physical.path, host->docroot); 3143 buffer_append_string_buffer(con->physical.path, con->uri.path); 3144 fcgi_connection_close(srv, hctx); 3162 con->mode = DIRECT; 3163 con->file_started = 1; /* fcgi_extension won't touch the request afterwards */ 3164 } else { 3165 if ( buffer_is_empty(con->authed_user) ) { 3166 /* 3167 * Currently we depend on a 3168 * non-empty authed_user in order to 3169 * determine if a user has been 3170 * authed, this should probably change 3171 * in the future: 3172 */ 3173 buffer_copy_string(con->authed_user, "-"); 3174 } 3145 3175 3146 con->mode = DIRECT; 3147 con->file_started = 1; /* fcgi_extension won't touch the request afterwards */ 3176 fcgi_connection_close(srv, hctx); 3177 con->mode = DIRECT; 3178 con->file_started = 0; 3179 con->file_finished = 0; 3180 buffer_reset(con->physical.path); 3181 } 3148 3182 } else { 3149 3183 /* we are done */ 3150 3184 fcgi_connection_close(srv, hctx); 3151 3185 } 3152 3186 3153 3187 joblist_append(srv, con); 3154 3188 return HANDLER_FINISHED; 3155 3189 case -1: 3156 3190 if (proc->pid && proc->state != PROC_STATE_DIED) { 3157 3191 int status; … … 3391 3425 3392 3426 if (buffer_is_equal(ds->value, extension->key)) { 3393 3427 break; 3394 3428 } 3395 3429 } 3396 3430 3397 3431 if (k == p->conf.exts->used) { 3398 3432 /* found nothign */ 3399 3433 extension = NULL; 3400 3434 } 3435 3436 if ( extension != NULL && 3437 ! buffer_is_empty(con->authed_user) && 3438 extension->used > 0 && 3439 extension->hosts[0]->mode == FCGI_AUTHORIZER ) 3440 { 3441 extension = NULL; 3442 } 3401 3443 break; 3402 3444 } 3403 3445 } 3404 3446 3405 3447 if (extension == NULL) { 3406 3448 /* check if extension matches */ 3407 3449 for (k = 0; k < p->conf.exts->used; k++) { 3408 3450 size_t ct_len; /* length of the config entry */ 3409 3451 3410 3452 extension = p->conf.exts->exts[k]; 3411 3453 3454 if ( ! buffer_is_empty(con->authed_user) && 3455 extension->used > 0 && 3456 extension->hosts[0]->mode == FCGI_AUTHORIZER ) 3457 { 3458 continue; 3459 } 3460 3412 3461 if (extension->key->used == 0) continue; 3413 3462 3414 3463 ct_len = extension->key->used - 1; 3415 3464 3416 3465 if (s_len < ct_len) continue; 3417 3466 3418 3467 /* check extension in the form "/fcgi_pattern" */ 3419 3468 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) { 3420 3469 break; 3421 3470 } else if (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len)) { … … 3511 3560 * 3512 3561 * /fcgi-bin/foo/bar 3513 3562 * 3514 3563 * SCRIPT_NAME = /fcgi-bin/foo 3515 3564 * PATH_INFO = /bar 3516 3565 * 3517 3566 */ 3518 3567 3519 3568 /* the rewrite is only done for /prefix/? matches */ 3520 3569 if (extension->key->ptr[0] == '/' && 3570 extension->key->used > 2 && 3521 3571 con->uri.path->used > extension->key->used && 3522 3572 NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) { 3523 3573 /* rewrite uri.path and pathinfo */ 3524 3574 3525 3575 buffer_copy_string(con->request.pathinfo, pathinfo); 3526 3576 3527 3577 con->uri.path->used -= con->request.pathinfo->used - 1; 3528 3578 con->uri.path->ptr[con->uri.path->used - 1] = '\0'; 3529 3579 } 3530 3580 }

