Hello community, here is the log from the commit of package apache2-mod_fcgid for openSUSE:Factory checked in at 2013-11-07 08:33:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apache2-mod_fcgid (Old) and /work/SRC/openSUSE:Factory/.apache2-mod_fcgid.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "apache2-mod_fcgid" Changes: -------- --- /work/SRC/openSUSE:Factory/apache2-mod_fcgid/apache2-mod_fcgid.changes 2013-03-12 22:36:29.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.apache2-mod_fcgid.new/apache2-mod_fcgid.changes 2013-11-07 08:33:57.000000000 +0100 @@ -1,0 +2,23 @@ +Wed Nov 6 14:03:05 CET 2013 - draht@suse.de + +- update to 2.3.9: + + obsoletes apache2-mod_fcgid-CVE-2013-4365-bnc844935.diff + and fixes CVE-2013-4365 [bnc#844935] (heap overflow). + The heap overflow discovery and fix was done by + Robert Matthews <rob tigertech.com>. + + quoting and spaces parsing correction for FcgidWrapper directive + and commandline options. + + logging improvements for access controls + + remove redundant processing of Location headers when running in + FCGI_AUTHORIZER mode + +------------------------------------------------------------------- +Mon Oct 21 15:05:29 CEST 2013 - draht@suse.de + +- Intermediate fix for openSUSE:Factory eg. openSUSE:13.1: + apache2-mod_fcgid-CVE-2013-4365-bnc844935.diff fixes a heap + overflow identified by CVE-2013-4365 [bnc#844935]. + This patch will be obsoleted by the next version update (to + 2.3.9 or higher). + +------------------------------------------------------------------- Old: ---- mod_fcgid-2.3.7.tar.bz2 New: ---- mod_fcgid-2.3.9.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apache2-mod_fcgid.spec ++++++ --- /var/tmp/diff_new_pack.JRrJbV/_old 2013-11-07 08:33:58.000000000 +0100 +++ /var/tmp/diff_new_pack.JRrJbV/_new 2013-11-07 08:33:58.000000000 +0100 @@ -27,7 +27,7 @@ %define apache_sysconfdir %(%{apxs} -q SYSCONFDIR) %define apache_mmn %(MMN=$(%{apxs} -q LIBEXECDIR)_MMN; test -x $MMN && $MMN) # -Version: 2.3.7 +Version: 2.3.9 Release: 0 # # @@ -46,12 +46,13 @@ Group: Productivity/Networking/Web/Servers %description -What is mod_fcgid? It is a binary compatibility alternative to Apache +A binary compatibile alternative to the Apache module mod_fastcgi. -mod_fcgid has a new process management strategy, which concentrates on -reducing the number of fastcgi server, and kick out the corrupt fastcgi -server as soon as possible. +The module implements an efficient process pool management for external +CGI program invocation. The pool of CGI programs is mapped against the +pool of apache workers in such way that there is always a weighted number +of programs waiting for requests in the pool. To load the module into Apache, run the command "a2enmod fcgid" as root. ++++++ mod_fcgid-2.3.7.tar.bz2 -> mod_fcgid-2.3.9.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/CHANGES-FCGID new/mod_fcgid-2.3.9/CHANGES-FCGID --- old/mod_fcgid-2.3.7/CHANGES-FCGID 2012-04-10 06:27:08.000000000 +0200 +++ new/mod_fcgid-2.3.9/CHANGES-FCGID 2013-10-04 03:53:35.000000000 +0200 @@ -1,4 +1,35 @@ -*- coding: utf-8 -*- +Changes with mod_fcgid 2.3.9 + + *) Revert fix for PR 53693, added in 2.3.8 but undocumented. Fix + issues with a minor optimization added in 2.3.8. [Jeff Trawick] + +Changes with mod_fcgid 2.3.8 + + *) SECURITY: CVE-2013-4365 (cve.mitre.org) + Fix possible heap buffer overwrite. Reported and solved by: + [Robert Matthews <rob tigertech.com>] + + *) Add experimental cmake-based build system for Windows. [Jeff Trawick] + + *) Correctly parse quotation and escaped spaces in FcgidWrapper and the + AAA Authenticator/Authorizor/Access directives' command line argument, + as currently documented. PR 51194 [William Rowe] + + *) Honor quoted FcgidCmdOptions arguments (notably for InitialEnv + assignments). PR 51657 [William Rowe] + + *) Conform script response parsing with mod_cgid and ensure no response + body is sent when ap_meets_conditions() determines that request + conditions are met. [Chris Darroch] + + *) Improve logging in access control hook functions. [Chris Darroch] + + *) Avoid making internal sub-requests and processing Location headers + when in FCGI_AUTHORIZER mode, as the auth hook functions already + treat Location headers returned by scripts as an error since + redirections are not meaningful in this mode. [Chris Darroch] + Changes with mod_fcgid 2.3.7 *) Introduce FcgidWin32PreventOrphans directive on Windows to use OS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/NOTICE-FCGID new/mod_fcgid-2.3.9/NOTICE-FCGID --- old/mod_fcgid-2.3.7/NOTICE-FCGID 2012-01-21 23:49:25.000000000 +0100 +++ new/mod_fcgid-2.3.9/NOTICE-FCGID 2013-09-29 19:42:30.000000000 +0200 @@ -1,5 +1,5 @@ Apache HTTP Server mod_fcgid -Copyright 2012 The Apache Software Foundation +Copyright 2013 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/README-FCGID new/mod_fcgid-2.3.9/README-FCGID --- old/mod_fcgid-2.3.7/README-FCGID 2009-10-07 06:06:48.000000000 +0200 +++ new/mod_fcgid-2.3.9/README-FCGID 2013-09-19 16:43:42.000000000 +0200 @@ -30,6 +30,8 @@ Win32 Build Instructions ------------------------ +1. Win32 build based on Visual Studio + The windows packages prior to 2.2.7 (or 2.0.62) left out the file include\mod_log_config.h, just copy these from the source tree or you can export them from subversion, just change to your @@ -90,6 +92,35 @@ lines in Makefile.win, or you must manually copy the .so module from modules\fcgid\Release after compiling. +2. Win32 build based on cmake: + +Note: This support is experimental and may not build mod_fcgid in a + manner compatible with the existing Windows build support. The + build interfaces may change as feedback is received and bugs are + resolved. Currently a .conf file is not created. + +Install httpd and APR to a common prefix, and point CMAKE_INSTALL_PREFIX +to that prefix when configuring mod_fcgid. + +Example using the "NMake Makefiles" generator from a Visual Studio command +prompt: + + cd some-build-directory + cmake -G "NMake Makefiles" ^ + -DCMAKE_INSTALL_PREFIX=C:\Apache246 ^ + -DCMAKE_BUILD_TYPE=RelWithDebInfo ^ + C:\path\to\fcgid-sources\modules\fcgid + nmake && nmake install + +The last argument to cmake in the example is the directory "modules\fcgid" +within your svn checkout or tarball/zip extract of mod_fcgid. + +Add -DINSTALL_PDB=OFF to the cmake invocation to leave mod_fcgid.pdb (if +generated) in the build directory. + +Add the following LoadModule directive to your configuration: + + LoadModule fcgid_module modules/mod_fcgid.so Documentation Build ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/STATUS-FCGID new/mod_fcgid-2.3.9/STATUS-FCGID --- old/mod_fcgid-2.3.7/STATUS-FCGID 2012-04-17 15:54:08.000000000 +0200 +++ new/mod_fcgid-2.3.9/STATUS-FCGID 2013-10-04 22:59:58.000000000 +0200 @@ -1,5 +1,5 @@ MOD_FCGID STATUS: -*-text-*- -Last modified at [$Date: 2012-04-17 13:54:08 +0000 (Tue, 17 Apr 2012) $] +Last modified at [$Date: 2013-10-04 20:59:58 +0000 (Fri, 04 Oct 2013) $] The current version of this file can be found at: @@ -14,8 +14,10 @@ [NOTE that x.{odd}.z versions are strictly Alpha/Beta releases, while x.{even}.z versions are Stable/GA releases.] - 2.3.8 : in development - 2.3.7 : tagged April 17, 2012 + 2.3.10 : in development + 2.3.9 : tagged October 4, 2013 + 2.3.8 : not released + 2.3.7 : released April 23, 2012 2.3.6 : released November 6, 2010 2.3.5 : released January 28, 2010 2.3.4 : released October 15, 2009 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/CMakeLists.txt new/mod_fcgid-2.3.9/modules/fcgid/CMakeLists.txt --- old/mod_fcgid-2.3.7/modules/fcgid/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/mod_fcgid-2.3.9/modules/fcgid/CMakeLists.txt 2013-09-19 16:43:42.000000000 +0200 @@ -0,0 +1,56 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Read the section on cmake builds in README-FCGID. + +PROJECT(mod_fcgid C) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +IF(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/lib/libhttpd.lib) + MESSAGE(FATAL_ERROR "libhttpd.lib was not found in prefix ${CMAKE_INSTALL_PREFIX}") +ENDIF() + +# Select APR trunk (libapr-2.lib) if it exists in PREFIX/lib; otherwise, select +# APR 1.x + APR-util 1.x +IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libapr-2.lib") + SET(apr_libraries + ${CMAKE_INSTALL_PREFIX}/lib/libapr-2.lib) +ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libapr-1.lib") + SET(apr_libraries + ${CMAKE_INSTALL_PREFIX}/lib/libapr-1.lib + ${CMAKE_INSTALL_PREFIX}/lib/libaprutil-1.lib) +ELSE() + MESSAGE(FATAL_ERROR "APR libraries were not found in prefix ${CMAKE_INSTALL_PREFIX}") +ENDIF() + +# Misc. options +OPTION(INSTALL_PDB "Install .pdb file (if generated)" ON) + +SET(mod_fcgid_sources + fcgid_bridge.c fcgid_bucket.c fcgid_conf.c fcgid_filter.c + fcgid_pm_main.c fcgid_pm_win.c fcgid_proc_win.c fcgid_proctbl_win.c + fcgid_protocol.c fcgid_spawn_ctl.c mod_fcgid.c mod_fcgid.rc +) +INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include) +ADD_LIBRARY(mod_fcgid SHARED ${mod_fcgid_sources}) +# magic base address taken from traditional Windows build +SET_TARGET_PROPERTIES(mod_fcgid PROPERTIES SUFFIX .so LINK_FLAGS /base:0x46430000) +TARGET_LINK_LIBRARIES(mod_fcgid ${CMAKE_INSTALL_PREFIX}/lib/libhttpd.lib ${apr_libraries}) +INSTALL(TARGETS mod_fcgid RUNTIME DESTINATION modules) +IF(INSTALL_PDB) + INSTALL(FILES ${CMAKE_BINARY_DIR}/mod_fcgid.pdb DESTINATION modules + CONFIGURATIONS RelWithDebInfo Debug) +ENDIF() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_bridge.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_bridge.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_bridge.c 2012-04-17 14:58:29.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_bridge.c 2013-10-04 03:48:20.000000000 +0200 @@ -316,7 +316,46 @@ /* Check the script header first; return immediately on error. */ if ((cond_status = ap_scan_script_header_err_core(r, sbuf, getsfunc_fcgid_BRIGADE, - brigade_stdout)) >= 400) { + brigade_stdout))) { + /* + * cond_status could be HTTP_NOT_MODIFIED in the case that the FCGI + * script does not set an explicit status and ap_meets_conditions, + * which is called by ap_scan_script_header_err_brigade, detects that + * the conditions of the requests are met and the response is + * not modified. + * In this case set r->status and return OK in order to prevent + * running through the error processing stack as this would + * break with mod_cache, if the conditions had been set by + * mod_cache itself to validate a stale entity. + * BTW: We circumvent the error processing stack anyway if the + * FCGI script set an explicit status code (whatever it is) and + * the only possible values for cond_status here are: + * + * HTTP_NOT_MODIFIED (set by ap_meets_conditions) + * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) + * HTTP_GATEWAY_TIME_OUT (script timed out, returned no headers) + * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the + * processing of the response of the FCGI script, e.g broken headers + * or a crashed FCGI process). + */ + if (cond_status == HTTP_NOT_MODIFIED) { + /* We need to remove our fcgid_filter before returning this + * status and code; otherwise, when ap_process_async_request() + * invokes ap_finalize_request_protocol() and that calls + * ap_pass_brigade(), fcgid_filter notices it has an empty + * brigade and returns without calling ap_pass_brigade() itself, + * which incorrectly circumvents the standard output filters. + */ + ap_remove_output_filter(r->output_filters); + + r->status = cond_status; + return OK; + } + + return cond_status; + } + + if (role == FCGI_AUTHORIZER) { return cond_status; } @@ -336,20 +375,34 @@ */ apr_table_unset(r->headers_in, "Content-Length"); + /* Setting this Location header value causes handle_request() to + * invoke ap_internal_redirect_handler(); that calls + * internal_internal_redirect() which sets the new sub-request's + * r->output_filters back to r->proto_output_filters before + * running the sub-request's handler. Because we return here + * without invoking ap_pass_brigade(), our fcgid_filter is ignored. + */ *location_ptr = location; - return HTTP_OK; + return OK; } else if (location && r->status == 200) { /* XX Note that if a script wants to produce its own Redirect * body, it now has to explicitly *say* "Status: 302" */ + + /* This return code causes ap_process_async_request() to invoke + * ap_die(); that calls ap_send_error_response(), which resets + * r->output_filters back to r->proto_output_filters, thus removing + * our fcgid_filter from the output chain before making a final call + * to ap_finalize_request_protocol(), which passes the brigade to + * the standard output filters. + */ return HTTP_MOVED_TEMPORARILY; } - /* Now pass to output filter */ - if (role == FCGI_RESPONDER - && (rv = ap_pass_brigade(r->output_filters, - brigade_stdout)) != APR_SUCCESS) { + /* Now pass any remaining response body data to output filters */ + if ((rv = ap_pass_brigade(r->output_filters, + brigade_stdout)) != APR_SUCCESS) { if (!APR_STATUS_IS_ECONNABORTED(rv)) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, "mod_fcgid: ap_pass_brigade failed in " @@ -376,14 +429,12 @@ bucket_ctx->ipc.request = r; apr_pool_cleanup_register(r->pool, bucket_ctx, bucket_ctx_cleanup, apr_pool_cleanup_null); + procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf); /* Try to get a connected ipc handle */ for (i = 0; i < FCGID_REQUEST_COUNT; i++) { /* Apply a free process slot, send a spawn request if I can't get one */ for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) { - /* Init spawn request */ - procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf); - bucket_ctx->ipc.connect_timeout = fcgi_request.cmdopts.ipc_connect_timeout; bucket_ctx->ipc.communation_timeout = @@ -406,7 +457,7 @@ } /* Send a spawn request if I can't get a process slot */ - procmgr_post_spawn_cmd(&fcgi_request, r); + procmgr_send_spawn_cmd(&fcgi_request, r); } /* Connect to the fastcgi server */ @@ -466,7 +517,7 @@ ap_internal_redirect_handler(location, r); } - /* Retrun condition status */ + /* Return condition status */ return cond_status; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_bucket.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_bucket.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_bucket.c 2010-11-04 13:10:10.000000000 +0100 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_bucket.c 2013-09-29 19:40:47.000000000 +0200 @@ -112,10 +112,12 @@ if (header.type == FCGI_STDERR) { char *logbuf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->list); char *line; + apr_size_t hasput; memset(logbuf, 0, APR_BUCKET_BUFF_SIZE); hasread = 0; + hasput = 0; while (hasread < bodysize) { char *buffer; apr_size_t bufferlen, canput, willput; @@ -130,9 +132,10 @@ canput = fcgid_min(bufferlen, bodysize - hasread); willput = - fcgid_min(canput, APR_BUCKET_BUFF_SIZE - hasread - 1); - memcpy(logbuf + hasread, buffer, willput); + fcgid_min(canput, APR_BUCKET_BUFF_SIZE - hasput - 1); + memcpy(logbuf + hasput, buffer, willput); hasread += canput; + hasput += willput; /* Ignore the "canput" bytes */ fcgid_ignore_bytes(ctx, canput); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_conf.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_conf.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_conf.c 2012-04-11 03:16:03.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_conf.c 2013-09-17 13:08:37.000000000 +0200 @@ -621,9 +621,16 @@ apr_status_t rv; apr_finfo_t finfo; fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config; + char **args; + + /* Get wrapper path */ + apr_tokenize_to_argv(authenticator, &args, cmd->temp_pool); + + if (*args == NULL || **args == '\0') + return "Invalid authenticator config"; /* Fetch only required file details inode + device */ - if ((rv = apr_stat(&finfo, authenticator, APR_FINFO_IDENT, + if ((rv = apr_stat(&finfo, args[0], APR_FINFO_IDENT, cmd->temp_pool)) != APR_SUCCESS) { return missing_file_msg(cmd->pool, "Authenticator", authenticator, rv); } @@ -632,10 +639,8 @@ dirconfig->authenticator_info = apr_pcalloc(cmd->server->process->pconf, sizeof(*dirconfig->authenticator_info)); - dirconfig->authenticator_info->cgipath = - apr_pstrdup(cmd->pool, authenticator); - dirconfig->authenticator_info->cmdline = - dirconfig->authenticator_info->cgipath; + dirconfig->authenticator_info->cgipath = apr_pstrdup(cmd->pool, args[0]); + dirconfig->authenticator_info->cmdline = authenticator; dirconfig->authenticator_info->inode = finfo.inode; dirconfig->authenticator_info->deviceid = finfo.device; return NULL; @@ -670,9 +675,16 @@ apr_status_t rv; apr_finfo_t finfo; fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config; + char **args; + + /* Get wrapper path */ + apr_tokenize_to_argv(authorizer, &args, cmd->temp_pool); + + if (*args == NULL || **args == '\0') + return "Invalid authorizer config"; /* Fetch only required file details inode + device */ - if ((rv = apr_stat(&finfo, authorizer, APR_FINFO_IDENT, + if ((rv = apr_stat(&finfo, args[0], APR_FINFO_IDENT, cmd->temp_pool)) != APR_SUCCESS) { return missing_file_msg(cmd->pool, "Authorizer", authorizer, rv); } @@ -681,10 +693,8 @@ dirconfig->authorizer_info = apr_pcalloc(cmd->server->process->pconf, sizeof(*dirconfig->authorizer_info)); - dirconfig->authorizer_info->cgipath = - apr_pstrdup(cmd->pool, authorizer); - dirconfig->authorizer_info->cmdline = - dirconfig->authorizer_info->cgipath; + dirconfig->authorizer_info->cgipath = apr_pstrdup(cmd->pool, args[0]); + dirconfig->authorizer_info->cmdline = authorizer; dirconfig->authorizer_info->inode = finfo.inode; dirconfig->authorizer_info->deviceid = finfo.device; return NULL; @@ -719,9 +729,16 @@ apr_status_t rv; apr_finfo_t finfo; fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config; + char **args; + + /* Get wrapper path */ + apr_tokenize_to_argv(access, &args, cmd->temp_pool); + + if (*args == NULL || **args == '\0') + return "Invalid access config"; /* Fetch only required file details inode + device */ - if ((rv = apr_stat(&finfo, access, APR_FINFO_IDENT, + if ((rv = apr_stat(&finfo, args[0], APR_FINFO_IDENT, cmd->temp_pool)) != APR_SUCCESS) { return missing_file_msg(cmd->pool, "Access checker", access, rv); } @@ -730,10 +747,8 @@ dirconfig->access_info = apr_pcalloc(cmd->server->process->pconf, sizeof(*dirconfig->access_info)); - dirconfig->access_info->cgipath = - apr_pstrdup(cmd->pool, access); - dirconfig->access_info->cmdline = - dirconfig->access_info->cgipath; + dirconfig->access_info->cgipath = apr_pstrdup(cmd->pool, args[0]); + dirconfig->access_info->cmdline = access; dirconfig->access_info->inode = finfo.inode; dirconfig->access_info->deviceid = finfo.device; return NULL; @@ -749,6 +764,18 @@ return NULL; } +fcgid_cmd_conf *get_access_info(request_rec * r, int *authoritative) +{ + fcgid_dir_conf *config = + ap_get_module_config(r->per_dir_config, &fcgid_module); + + if (config != NULL && config->access_info != NULL) { + *authoritative = config->access_authoritative; + return config->access_info; + } + + return NULL; +} #ifdef WIN32 /* FcgidWin32PreventOrphans @@ -814,29 +841,17 @@ } #endif /* WIN32*/ -fcgid_cmd_conf *get_access_info(request_rec * r, int *authoritative) -{ - fcgid_dir_conf *config = - ap_get_module_config(r->per_dir_config, &fcgid_module); - - if (config != NULL && config->access_info != NULL) { - *authoritative = config->access_authoritative; - return config->access_info; - } - - return NULL; -} - const char *set_wrapper_config(cmd_parms * cmd, void *dirconfig, const char *wrapper_cmdline, const char *extension, const char *virtual) { - const char *path, *tmp; + const char *path; apr_status_t rv; apr_finfo_t finfo; fcgid_cmd_conf *wrapper = NULL; fcgid_dir_conf *config = (fcgid_dir_conf *) dirconfig; + char **args; /* Sanity checks */ @@ -855,8 +870,9 @@ return "Invalid wrapper file extension"; /* Get wrapper path */ - tmp = wrapper_cmdline; - path = ap_getword_white(cmd->temp_pool, &tmp); + apr_tokenize_to_argv(wrapper_cmdline, &args, cmd->temp_pool); + path = apr_pstrdup(cmd->pool, args[0]); + if (path == NULL || *path == '\0') return "Invalid wrapper config"; @@ -994,14 +1010,14 @@ } while (*args) { - const char *option = ap_getword_white(cmd->pool, &args); + const char *option = ap_getword_conf(cmd->pool, &args); const char *val; /* TODO: Consider supporting BusyTimeout. */ if (!strcasecmp(option, "ConnectTimeout")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "ConnectTimeout must have an argument"; } @@ -1010,7 +1026,7 @@ } if (!strcasecmp(option, "IdleTimeout")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "IdleTimeout must have an argument"; } @@ -1022,7 +1038,7 @@ char *name; char *eql; - name = ap_getword_white(cmd->pool, &args); + name = ap_getword_conf(cmd->pool, &args); if (!strlen(name)) { return "InitialEnv must have an argument"; } @@ -1041,7 +1057,7 @@ } if (!strcasecmp(option, "IOTimeout")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "IOTimeout must have an argument"; } @@ -1050,7 +1066,7 @@ } if (!strcasecmp(option, "MaxProcesses")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "MaxProcesses must have an argument"; } @@ -1059,7 +1075,7 @@ } if (!strcasecmp(option, "MaxProcessLifetime")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "MaxProcessLifetime must have an argument"; } @@ -1068,7 +1084,7 @@ } if (!strcasecmp(option, "MaxRequestsPerProcess")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "MaxRequestsPerProcess must have an argument"; } @@ -1077,7 +1093,7 @@ } if (!strcasecmp(option, "MinProcesses")) { - val = ap_getword_white(cmd->pool, &args); + val = ap_getword_conf(cmd->pool, &args); if (!strlen(val)) { return "MinProcesses must have an argument"; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_conf.h new/mod_fcgid-2.3.9/modules/fcgid/fcgid_conf.h --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_conf.h 2012-04-17 15:54:08.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_conf.h 2013-10-04 22:59:58.000000000 +0200 @@ -18,14 +18,12 @@ #ifndef FCGID_CONF_H #define FCGID_CONF_H -#include "apr_general.h" /* stringify */ - #define MODFCGID_COPYRIGHT \ - "Copyright 2012 The Apache Software Foundation." + "Copyright 2013 The Apache Software Foundation." #define MODFCGID_VERSION_MAJOR 2 #define MODFCGID_VERSION_MINOR 3 -#define MODFCGID_VERSION_SUBVER 7 +#define MODFCGID_VERSION_SUBVER 9 #define MODFCGID_VERSION_DEV 0 #if MODFCGID_VERSION_DEV @@ -34,6 +32,14 @@ #define MODFCGID_VERSION_DEVSTR "" #endif +/* APR_STRINGIFY is defined here, and also in apr_general.h, so wrap it */ +#ifndef APR_STRINGIFY +/** Properly quote a value as a string in the C preprocessor */ +#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n) +/** Helper macro for APR_STRINGIFY */ +#define APR_STRINGIFY_HELPER(n) #n +#endif + #define MODFCGID_REVISION APR_STRINGIFY(MODFCGID_VERSION_MAJOR) \ "." APR_STRINGIFY(MODFCGID_VERSION_MINOR) \ "." APR_STRINGIFY(MODFCGID_VERSION_SUBVER) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_filter.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_filter.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_filter.c 2009-09-17 22:14:45.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_filter.c 2013-09-17 13:08:37.000000000 +0200 @@ -26,7 +26,7 @@ { apr_status_t rv; apr_bucket_brigade *tmp_brigade; - int save_size = 0; + apr_size_t save_size = 0; conn_rec *c = f->c; server_rec *s = f->r->server; fcgid_server_conf *sconf = ap_get_module_config(s->module_config, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm.h new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm.h --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm.h 2010-10-29 22:35:35.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm.h 2013-10-04 03:48:20.000000000 +0200 @@ -41,9 +41,9 @@ void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r, fcgid_cmd_conf *cmd_conf); -apr_status_t procmgr_post_spawn_cmd(fcgid_command * command, +apr_status_t procmgr_send_spawn_cmd(fcgid_command * command, request_rec * r); -apr_status_t procmgr_peek_cmd(fcgid_command * command, +apr_status_t procmgr_fetch_cmd(fcgid_command * command, server_rec * main_server); apr_status_t procmgr_finish_notify(server_rec * main_server); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_main.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_main.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_main.c 2012-01-20 23:02:50.000000000 +0100 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_main.c 2013-10-04 03:48:20.000000000 +0200 @@ -639,7 +639,7 @@ break; /* Wait for command */ - if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) { + if (procmgr_fetch_cmd(&command, main_server) == APR_SUCCESS) { if (is_spawn_allowed(main_server, &command)) fastcgi_spawn(&command, main_server, configpool); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_unix.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_unix.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_unix.c 2011-09-23 15:41:15.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_unix.c 2013-10-04 03:48:20.000000000 +0200 @@ -354,7 +354,7 @@ fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config, &fcgid_module); - /* Calculate procmgr_peek_cmd wake up interval */ + /* Calculate procmgr_fetch_cmd wake up interval */ g_wakeup_timeout = fcgid_min(sconf->error_scan_interval, sconf->busy_scan_interval); g_wakeup_timeout = fcgid_min(sconf->idle_scan_interval, @@ -427,8 +427,6 @@ fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); - memset(command, 0, sizeof(*command)); - /* suEXEC check */ if ((ugid = ap_run_get_suexec_identity(r))) { command->uid = ugid->uid; @@ -453,11 +451,14 @@ apr_cpystrn(command->server_hostname, r->server->server_hostname, sizeof command->server_hostname); } + else { + command->server_hostname[0] = '\0'; + } get_cmd_options(r, command->cgipath, &command->cmdopts, &command->cmdenv); } -apr_status_t procmgr_post_spawn_cmd(fcgid_command * command, +apr_status_t procmgr_send_spawn_cmd(fcgid_command * command, request_rec * r) { apr_status_t rv; @@ -515,7 +516,7 @@ } #define FOR_READ 1 -apr_status_t procmgr_peek_cmd(fcgid_command * command, +apr_status_t procmgr_fetch_cmd(fcgid_command * command, server_rec * main_server) { apr_status_t rv; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_win.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_win.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_pm_win.c 2012-04-17 14:56:13.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_pm_win.c 2013-10-04 03:53:35.000000000 +0200 @@ -44,7 +44,7 @@ apr_sleep(apr_time_from_sec(1)); } - /* Send a wake up message to procmgr_peek_cmd() */ + /* Send a wake up message to procmgr_fetch_cmd() */ if (!g_must_exit && g_msgqueue) apr_queue_trypush(g_msgqueue, NULL); } @@ -96,7 +96,7 @@ exit(1); } - /* Calculate procmgr_peek_cmd wake up interval */ + /* Calculate procmgr_fetch_cmd wake up interval */ g_wakeup_timeout = min(sconf->error_scan_interval, sconf->busy_scan_interval); g_wakeup_timeout = min(sconf->idle_scan_interval, @@ -136,14 +136,14 @@ fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); - memset(command, 0, sizeof(*command)); - /* no truncation should ever occur */ AP_DEBUG_ASSERT(sizeof command->cgipath > strlen(cmd_conf->cgipath)); apr_cpystrn(command->cgipath, cmd_conf->cgipath, sizeof command->cgipath); AP_DEBUG_ASSERT(sizeof command->cmdline > strlen(cmd_conf->cmdline)); apr_cpystrn(command->cmdline, cmd_conf->cmdline, sizeof command->cmdline); + command->inode = (apr_ino_t) -1; + command->deviceid = (dev_t) -1; command->uid = (uid_t) - 1; command->gid = (gid_t) - 1; command->userdir = 0; @@ -152,11 +152,14 @@ apr_cpystrn(command->server_hostname, r->server->server_hostname, sizeof command->server_hostname); } + else { + command->server_hostname[0] = '\0'; + } get_cmd_options(r, command->cgipath, &command->cmdopts, &command->cmdenv); } -apr_status_t procmgr_post_spawn_cmd(fcgid_command * command, +apr_status_t procmgr_send_spawn_cmd(fcgid_command * command, request_rec * r) { if (g_thread && g_msgqueue && !g_must_exit @@ -226,7 +229,7 @@ return rv; } -apr_status_t procmgr_peek_cmd(fcgid_command * command, +apr_status_t procmgr_fetch_cmd(fcgid_command * command, server_rec * main_server) { fcgid_command *peakcmd = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_proc_unix.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_proc_unix.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_proc_unix.c 2012-04-17 13:21:22.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_proc_unix.c 2013-07-06 20:44:24.000000000 +0200 @@ -204,23 +204,11 @@ char **proc_environ; struct sockaddr_un unix_addr; apr_procattr_t *procattr = NULL; - int argc, len; - const char *wargv[APACHE_ARG_MAX + 1]; - const char *word; /* For wrapper */ - const char *tmp; + int len; + const char **wargv; /* Build wrapper args */ - argc = 0; - tmp = cmdline; - while (1) { - word = ap_getword_white(procnode->proc_pool, &tmp); - if (word == NULL || *word == '\0') - break; - if (argc >= APACHE_ARG_MAX) - break; - wargv[argc++] = word; - } - wargv[argc] = NULL; + apr_tokenize_to_argv(cmdline, (char ***)&wargv, procnode->proc_pool); /* Create UNIX domain socket before spawn diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_proc_win.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_proc_win.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_proc_win.c 2012-04-11 01:59:13.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_proc_win.c 2012-11-16 19:33:14.000000000 +0100 @@ -69,22 +69,10 @@ apr_file_t *file; const char * const *proc_environ; char sock_path[FCGID_PATH_MAX]; - int argc; - char const * wargv[APACHE_ARG_MAX + 1], *word; /* For wrapper */ - const char *tmp; + const char **wargv; /* Build wrapper args */ - argc = 0; - tmp = cmdline; - while (1) { - word = ap_getword_white(procnode->proc_pool, &tmp); - if (word == NULL || *word == '\0') - break; - if (argc >= APACHE_ARG_MAX) - break; - wargv[argc++] = word; - } - wargv[argc] = NULL; + apr_tokenize_to_argv(cmdline, (char ***)&wargv, procnode->proc_pool); memset(&SecurityAttributes, 0, sizeof(SecurityAttributes)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/fcgid_protocol.c new/mod_fcgid-2.3.9/modules/fcgid/fcgid_protocol.c --- old/mod_fcgid-2.3.7/modules/fcgid/fcgid_protocol.c 2009-09-17 22:14:45.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/fcgid_protocol.c 2013-09-17 13:08:37.000000000 +0200 @@ -25,7 +25,7 @@ static size_t init_environment(char *buf, char **envp) { char *spliter; - int namelen, valuelen; + apr_size_t namelen, valuelen; char *cur_buf = buf; size_t buffer_size = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_fcgid-2.3.7/modules/fcgid/mod_fcgid.c new/mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c --- old/mod_fcgid-2.3.7/modules/fcgid/mod_fcgid.c 2012-04-11 02:54:32.000000000 +0200 +++ new/mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c 2012-07-17 02:02:26.000000000 +0200 @@ -46,6 +46,12 @@ FCGID_PROCNODE_TYPE_ERROR, }; +enum fcgid_auth_check_mode { + FCGID_AUTH_CHECK_AUTHN, + FCGID_AUTH_CHECK_AUTHZ, + FCGID_AUTH_CHECK_ACCESS +}; + /* Stolen from mod_cgi.c */ /* KLUDGE --- for back-compatibility, we don't have to check ExecCGI * in ScriptAliased directories, which means we need to know if this @@ -477,107 +483,78 @@ return 1; } -static int mod_fcgid_authenticator(request_rec * r) +static int mod_fcgid_check_auth(request_rec *r, + enum fcgid_auth_check_mode auth_check_mode) { int res = 0; const char *password = NULL; apr_table_t *saved_subprocess_env = NULL; - fcgid_cmd_conf *authenticator_info; + fcgid_cmd_conf *auth_cmd_info = NULL; int authoritative; + const char *auth_role = NULL; + const char *role_log_msg = NULL; + const char *user_log_msg = ""; + + /* Because we don't function as authn/z providers, integration with + * the standard httpd authn/z modules is somewhat problematic. + * + * With httpd 2.4 in particular, our hook functions may be + * circumvented by mod_authz_core's check_access_ex hook, unless + * Require directives specify that user-based authn/z is needed. + * + * Even then, APR_HOOK_MIDDLE may cause our authentication hook to be + * ordered after mod_auth_basic's check_authn hook, in which case it + * will be skipped unless AuthBasicAuthoritative is Off and no authn + * provider recognizes the user or outright denies the request. + * + * Also, when acting as an authenticator, we don't have a mechanism to + * set r->user based on the script response, so scripts can't implement + * a private authentication scheme; instead we use ap_get_basic_auth_pw() + * and only support Basic HTTP authentication. + * + * It is possible to act reliably as both authenticator and authorizer + * if mod_authn_core is loaded to support AuthType and AuthName, but + * mod_authz_core and mod_auth_basic are not loaded. However, in this + * case the Require directive is not available, which defeats many + * common configuration tropes. + */ - authenticator_info = get_authenticator_info(r, &authoritative); + switch (auth_check_mode) { + case FCGID_AUTH_CHECK_AUTHN: + auth_cmd_info = get_authenticator_info(r, &authoritative); + auth_role = "AUTHENTICATOR"; + role_log_msg = "Authentication"; + break; + + case FCGID_AUTH_CHECK_AUTHZ: + auth_cmd_info = get_authorizer_info(r, &authoritative); + auth_role = "AUTHORIZER"; + role_log_msg = "Authorization"; + break; + + case FCGID_AUTH_CHECK_ACCESS: + auth_cmd_info = get_access_info(r, &authoritative); + auth_role = "ACCESS_CHECKER"; + role_log_msg = "Access check"; + break; + } - /* Is authenticator enable? */ - if (authenticator_info == NULL) + /* Is this auth check command enabled? */ + if (auth_cmd_info == NULL) return DECLINED; /* Get the user password */ - if ((res = ap_get_basic_auth_pw(r, &password)) != OK) + if (auth_check_mode == FCGID_AUTH_CHECK_AUTHN + && (res = ap_get_basic_auth_pw(r, &password)) != OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "mod_fcgid: authenticator requires " + "basic HTTP auth credentials"); return res; - - /* Save old process environment */ - saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env); - - /* Add some environment variables */ - ap_add_common_vars(r); - ap_add_cgi_vars(r); - fcgid_add_cgi_vars(r); - apr_table_setn(r->subprocess_env, "REMOTE_PASSWD", password); - apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", "AUTHENTICATOR"); - - /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, - * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass - * PROXY_AUTH to allow CGI to perform proxy auth for httpd - */ - apr_table_unset(r->subprocess_env, "CONTENT_LENGTH"); - apr_table_unset(r->subprocess_env, "PATH_INFO"); - apr_table_unset(r->subprocess_env, "PATH_TRANSLATED"); - apr_table_unset(r->subprocess_env, "SCRIPT_NAME"); - apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE"); - apr_table_unset(r->subprocess_env, "HTTP_TE"); - apr_table_unset(r->subprocess_env, "HTTP_TRAILER"); - apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING"); - apr_table_unset(r->subprocess_env, "HTTP_UPGRADE"); - - /* Connection hop-by-hop header to prevent the CGI from hanging */ - apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close"); - - /* Handle the request */ - res = bridge_request(r, FCGI_AUTHORIZER, authenticator_info); - - /* Restore r->subprocess_env */ - r->subprocess_env = saved_subprocess_env; - - if (res == OK && r->status == 200 - && apr_table_get(r->headers_out, "Location") == NULL) - { - /* Pass */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authentication pass", r->user); - - /* Modify headers: An Authorizer application's 200 response may include headers - whose names are prefixed with Variable-. */ - apr_table_do(mod_fcgid_modify_auth_header, r->subprocess_env, - r->err_headers_out, NULL); - - return OK; - } else { - /* Print error info first */ - if (res != OK) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authentication failed, respond %d, URI %s", - r->user, res, r->uri); - else if (r->status != 200) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authentication failed, status %d, URI %s", - r->user, r->status, r->uri); - else - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authentication failed, redirected is not allowed", - r->user); - - /* Handle error */ - if (!authoritative) - return DECLINED; - else { - ap_note_basic_auth_failure(r); - return (res == OK) ? HTTP_UNAUTHORIZED : res; - } } -} -static int mod_fcgid_authorizer(request_rec * r) -{ - int res = 0; - apr_table_t *saved_subprocess_env = NULL; - fcgid_cmd_conf *authorizer_info; - int authoritative; - - authorizer_info = get_authorizer_info(r, &authoritative); - - /* Is authenticator enable? */ - if (authorizer_info == NULL) - return DECLINED; + if (auth_check_mode != FCGID_AUTH_CHECK_ACCESS) { + user_log_msg = apr_psprintf(r->pool, " of user %s", r->user); + } /* Save old process environment */ saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env); @@ -586,7 +563,10 @@ ap_add_common_vars(r); ap_add_cgi_vars(r); fcgid_add_cgi_vars(r); - apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", "AUTHORIZER"); + if (auth_check_mode == FCGID_AUTH_CHECK_AUTHN) { + apr_table_setn(r->subprocess_env, "REMOTE_PASSWD", password); + } + apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", auth_role); /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass @@ -606,17 +586,17 @@ apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close"); /* Handle the request */ - res = bridge_request(r, FCGI_AUTHORIZER, authorizer_info); + res = bridge_request(r, FCGI_AUTHORIZER, auth_cmd_info); /* Restore r->subprocess_env */ r->subprocess_env = saved_subprocess_env; - if (res == OK && r->status == 200 - && apr_table_get(r->headers_out, "Location") == NULL) - { + if (res == OK && r->status == HTTP_OK + && apr_table_get(r->headers_out, "Location") == NULL) { /* Pass */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "mod_fcgid: access granted (authorization)"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "mod_fcgid: %s%s to access %s succeeded", + role_log_msg, user_log_msg, r->uri); /* Modify headers: An Authorizer application's 200 response may include headers whose names are prefixed with Variable-. */ @@ -624,112 +604,53 @@ r->err_headers_out, NULL); return OK; - } else { + } + else { + const char *add_err_msg = ""; + /* Print error info first */ - if (res != OK) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authorization failed, respond %d, URI %s", - r->user, res, r->uri); - else if (r->status != 200) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authorization failed, status %d, URI %s", - r->user, r->status, r->uri); - else - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s authorization failed, redirected is not allowed", - r->user); + if (res != OK) { + add_err_msg = + apr_psprintf(r->pool, "; error or unexpected condition " + "while parsing response (%d)", res); + } + else if (r->status == HTTP_OK) { + add_err_msg = "; internal redirection not allowed"; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "mod_fcgid: %s%s to access %s failed, reason: " + "script returned status %d%s", + role_log_msg, user_log_msg, r->uri, r->status, + add_err_msg); /* Handle error */ - if (!authoritative) + if (!authoritative) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "mod_fcgid: not authoritative"); return DECLINED; + } else { - ap_note_basic_auth_failure(r); + if (auth_check_mode != FCGID_AUTH_CHECK_ACCESS) { + ap_note_basic_auth_failure(r); + } return (res == OK) ? HTTP_UNAUTHORIZED : res; } } } -static int mod_fcgid_check_access(request_rec * r) +static int mod_fcgid_authenticator(request_rec *r) { - int res = 0; - apr_table_t *saved_subprocess_env = NULL; - fcgid_cmd_conf *access_info; - int authoritative; - - access_info = get_access_info(r, &authoritative); - - /* Is access check enable? */ - if (access_info == NULL) - return DECLINED; - - /* Save old process environment */ - saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env); - - /* Add some environment variables */ - ap_add_common_vars(r); - ap_add_cgi_vars(r); - fcgid_add_cgi_vars(r); - apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", - "ACCESS_CHECKER"); - - /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, - * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass - * PROXY_AUTH to allow CGI to perform proxy auth for httpd - */ - apr_table_unset(r->subprocess_env, "CONTENT_LENGTH"); - apr_table_unset(r->subprocess_env, "PATH_INFO"); - apr_table_unset(r->subprocess_env, "PATH_TRANSLATED"); - apr_table_unset(r->subprocess_env, "SCRIPT_NAME"); - apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE"); - apr_table_unset(r->subprocess_env, "HTTP_TE"); - apr_table_unset(r->subprocess_env, "HTTP_TRAILER"); - apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING"); - apr_table_unset(r->subprocess_env, "HTTP_UPGRADE"); - - /* Connection hop-by-hop header to prevent the CGI from hanging */ - apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close"); - - /* Handle the request */ - res = bridge_request(r, FCGI_AUTHORIZER, access_info); - - /* Restore r->subprocess_env */ - r->subprocess_env = saved_subprocess_env; - - if (res == OK && r->status == 200 - && apr_table_get(r->headers_out, "Location") == NULL) - { - /* Pass */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "mod_fcgid: access check pass"); - - /* Modify headers: An Authorizer application's 200 response may include headers - whose names are prefixed with Variable-. */ - apr_table_do(mod_fcgid_modify_auth_header, r->subprocess_env, - r->err_headers_out, NULL); + return mod_fcgid_check_auth(r, FCGID_AUTH_CHECK_AUTHN); +} - return OK; - } else { - /* Print error info first */ - if (res != OK) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s access check failed, respond %d, URI %s", - r->user, res, r->uri); - else if (r->status != 200) - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s access check failed, status %d, URI %s", - r->user, r->status, r->uri); - else - ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r, - "mod_fcgid: user %s access check failed, redirected is not allowed", - r->user); +static int mod_fcgid_authorizer(request_rec *r) +{ + return mod_fcgid_check_auth(r, FCGID_AUTH_CHECK_AUTHZ); +} - /* Handle error */ - if (!authoritative) - return DECLINED; - else { - return (res == OK) ? HTTP_UNAUTHORIZED : res; - } - } +static int mod_fcgid_check_access(request_rec *r) +{ + return mod_fcgid_check_auth(r, FCGID_AUTH_CHECK_ACCESS); } static void initialize_child(apr_pool_t * pchild, server_rec * main_server) -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org