Project

General

Profile

fastcgi-authorizer-fixes.diff

All fastcgi mode=authorizer fixes (Variable- env works, proper re-dispatching, and assert failure fix when auth is running in front of cgi). - maherb, 2006-06-20 12:02

View differences:

src/mod_fastcgi.c (working copy)
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
		}