tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From na...@apache.org
Subject cvs commit: jakarta-tomcat-connectors/jk/native/iis jk_isapi_plugin.c
Date Sat, 13 Oct 2001 17:38:05 GMT
nacho       01/10/13 10:38:05

  Modified:    jk/native/iis jk_isapi_plugin.c
  Log:
  Porting features done in Tomcat 3.3 tree.
  
  Revision  Changes    Path
  1.7       +500 -163  jakarta-tomcat-connectors/jk/native/iis/jk_isapi_plugin.c
  
  Index: jk_isapi_plugin.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/iis/jk_isapi_plugin.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- jk_isapi_plugin.c	2001/06/24 15:37:43	1.6
  +++ jk_isapi_plugin.c	2001/10/13 17:38:04	1.7
  @@ -58,9 +58,14 @@
   /***************************************************************************
    * Description: ISAPI plugin for IIS/PWS                                   *
    * Author:      Gal Shachor <shachor@il.ibm.com>                           *
  - * Version:     $Revision: 1.6 $                                           *
  + * Author:      Larry Isaacs <larryi@apache.org>                           *
  + * Author:      Ignacio J. Ortega <nacho@apache.org>                       *
  + * Version:     $Revision: 1.7 $                                           *
    ***************************************************************************/
   
  +// This define is needed to include wincrypt,h, needed to get client certificates
  +#define _WIN32_WINNT 0x0400
  +
   #include <httpext.h>
   #include <httpfilt.h>
   #include <wininet.h>
  @@ -86,14 +91,17 @@
    */
   #define URI_HEADER_NAME         ("TOMCATURI:")
   #define WORKER_HEADER_NAME      ("TOMCATWORKER:")
  +#define CONTENT_LENGTH          ("CONTENT_LENGTH:")
   
   #define HTTP_URI_HEADER_NAME     ("HTTP_TOMCATURI")
   #define HTTP_WORKER_HEADER_NAME  ("HTTP_TOMCATWORKER")
   
   #define REGISTRY_LOCATION       ("Software\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0")
   #define EXTENSION_URI_TAG       ("extension_uri")
  -
  -#define MAX_SERVERNAME			128
  +
  +#define BAD_REQUEST		-1
  +#define BAD_PATH		-2
  +#define MAX_SERVERNAME			128
   
   #define GET_SERVER_VARIABLE_VALUE(name, place) {    \
       (place) = NULL;                                   \
  @@ -122,13 +130,15 @@
           (place) = def;  \
       }           \
   }\
  -
  -static char *SERVER_NAME = "SERVER_NAME";
  +
  +static char  ini_file_name[MAX_PATH];
  +static int   using_ini_file = JK_FALSE;
  +static int   is_inited = JK_FALSE;
  +static int	 is_mapread	= JK_FALSE;
  +static jk_uri_worker_map_t *uw_map = NULL; 
  +static jk_logger_t *logger = NULL; 
  +static char *SERVER_NAME = "SERVER_NAME";
   
  -static int					is_inited	= JK_FALSE;
  -static int					is_mapread	= JK_FALSE;
  -static jk_uri_worker_map_t	*uw_map		= NULL; 
  -static jk_logger_t			*logger		= NULL; 
   
   static char extension_uri[INTERNET_MAX_URL_LENGTH] = "/jakarta/isapi_redirect.dll";
   static char log_file[MAX_PATH * 2];
  @@ -168,8 +178,8 @@
                              jk_ws_service_t *s,
                              char **worker_name);
   
  -static int init_jk(char *serverName);
  -
  +static int init_jk(char *serverName);
  +
   static int initialize_extension(void);
   
   static int read_registry_init_data(void);
  @@ -186,6 +196,115 @@
                               DWORD bufsz,
                               char  *def_val);
   
  +static int base64_encode_cert_len(int len);
  +
  +static int base64_encode_cert(char *encoded,
  +                              const unsigned char *string,
  +                              int len);
  +
  +
  +static char x2c(const char *what)
  +{
  +    register char digit;
  +
  +    digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
  +    digit *= 16;
  +    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
  +    return (digit);
  +}
  +
  +static int unescape_url(char *url)
  +{
  +    register int x, y, badesc, badpath;
  +
  +    badesc = 0;
  +    badpath = 0;
  +    for (x = 0, y = 0; url[y]; ++x, ++y) {
  +        if (url[y] != '%')
  +            url[x] = url[y];
  +        else {
  +            if (!isxdigit(url[y + 1]) || !isxdigit(url[y + 2])) {
  +                badesc = 1;
  +                url[x] = '%';
  +            }
  +            else {
  +                url[x] = x2c(&url[y + 1]);
  +                y += 2;
  +                if (url[x] == '/' || url[x] == '\0')
  +                    badpath = 1;
  +            }
  +        }
  +    }
  +    url[x] = '\0';
  +    if (badesc)
  +            return BAD_REQUEST;
  +    else if (badpath)
  +            return BAD_PATH;
  +    else
  +            return 0;
  +}
  +
  +static void getparents(char *name)
  +{
  +    int l, w;
  +
  +    /* Four paseses, as per RFC 1808 */
  +    /* a) remove ./ path segments */
  +
  +    for (l = 0, w = 0; name[l] != '\0';) {
  +        if (name[l] == '.' && name[l + 1] == '/' && (l == 0 || name[l -
1] == '/'))
  +            l += 2;
  +        else
  +            name[w++] = name[l++];
  +    }
  +
  +    /* b) remove trailing . path, segment */
  +    if (w == 1 && name[0] == '.')
  +        w--;
  +    else if (w > 1 && name[w - 1] == '.' && name[w - 2] == '/')
  +        w--;
  +    name[w] = '\0';
  +
  +    /* c) remove all xx/../ segments. (including leading ../ and /../) */
  +    l = 0;
  +
  +    while (name[l] != '\0') {
  +        if (name[l] == '.' && name[l + 1] == '.' && name[l + 2] == '/'
&&
  +            (l == 0 || name[l - 1] == '/')) {
  +            register int m = l + 3, n;
  +
  +            l = l - 2;
  +            if (l >= 0) {
  +                while (l >= 0 && name[l] != '/')
  +                    l--;
  +                l++;
  +            }
  +            else
  +                l = 0;
  +            n = l;
  +            while ((name[n] = name[m]))
  +                (++n, ++m);
  +        }
  +        else
  +            ++l;
  +    }
  +
  +    /* d) remove trailing xx/.. segment. */
  +    if (l == 2 && name[0] == '.' && name[1] == '.')
  +        name[0] = '\0';
  +    else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' &&
name[l - 3] == '/') {
  +        l = l - 4;
  +        if (l >= 0) {
  +            while (l >= 0 && name[l] != '/')
  +                l--;
  +            l++;
  +        }
  +        else
  +            l = 0;
  +        name[l] = '\0';
  +    }
  +}
  +
   static int uri_is_web_inf(char *uri)
   {
       char *c = uri;
  @@ -193,13 +312,37 @@
           *c = tolower(*c);
           c++;
       }                    
  -    if (strstr(uri, "web-inf")) {
  +    if(strstr(uri, "web-inf")) {
  +        return JK_TRUE;
  +    }
  +    if(strstr(uri, "meta-inf")) {
           return JK_TRUE;
       }
   
       return JK_FALSE;
   }
   
  +static void write_error_response(PHTTP_FILTER_CONTEXT pfc,char *status,char * msg)
  +{
  +    char crlf[3] = { (char)13, (char)10, '\0' };
  +    char ctype[30];
  +    DWORD len = strlen(msg);
  +
  +    sprintf(ctype, 
  +            "Content-Type:text/html%s%s", 
  +            crlf, 
  +            crlf);
  +
  +    /* reject !!! */
  +    pfc->ServerSupportFunction(pfc, 
  +                               SF_REQ_SEND_RESPONSE_HEADER,
  +                               status,
  +                               (DWORD)crlf,
  +                               (DWORD)ctype);
  +    pfc->WriteClient(pfc, msg, &len, 0);
  +}
  +
  +
   static int JK_METHOD start_response(jk_ws_service_t *s,
                                       int status,
                                       const char *reason,
  @@ -409,33 +552,37 @@
                               DWORD dwNotificationType, 
                               LPVOID pvNotification)
   {
  -	/* Initialise jk */
  -	if (is_inited && !is_mapread) {
  -		char serverName[MAX_SERVERNAME];
  -		DWORD dwLen = sizeof(serverName);
  -
  -		if (pfc->GetServerVariable(pfc, SERVER_NAME, serverName, &dwLen))
  -		{
  -			if (dwLen > 0) serverName[dwLen-1] = '\0';
  -			if (init_jk(serverName))
  -				is_mapread = JK_TRUE;
  -		}
  -		/* If we can't read the map we become dormant */
  -		if (!is_mapread)
  -			is_inited = JK_FALSE;
  -	}
  -
  +	/* Initialise jk */
  +	if (is_inited && !is_mapread) {
  +		char serverName[MAX_SERVERNAME];
  +		DWORD dwLen = sizeof(serverName);
  +
  +		if (pfc->GetServerVariable(pfc, SERVER_NAME, serverName, &dwLen))
  +		{
  +			if (dwLen > 0) serverName[dwLen-1] = '\0';
  +			if (init_jk(serverName))
  +				is_mapread = JK_TRUE;
  +		}
  +		/* If we can't read the map we become dormant */
  +		if (!is_mapread)
  +			is_inited = JK_FALSE;
  +	}
  +
       if (is_inited &&
          (SF_NOTIFY_PREPROC_HEADERS == dwNotificationType)) { 
           PHTTP_FILTER_PREPROC_HEADERS p = (PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
           char uri[INTERNET_MAX_URL_LENGTH]; 
  +		char snuri[INTERNET_MAX_URL_LENGTH]="/";
  +		char Host[INTERNET_MAX_URL_LENGTH];
  +
           char *query;
           DWORD sz = sizeof(uri);
  +        DWORD szHost = sizeof(Host);
   
           jk_log(logger, JK_LOG_DEBUG, 
                  "HttpFilterProc started\n");
  -
   
  +
           /*
            * Just in case somebody set these headers in the request!
            */
  @@ -449,15 +596,46 @@
           }
   
           if (strlen(uri)) {
  -            char *worker;
  +            int rc;
  +            char *worker=0;
               query = strchr(uri, '?');
               if (query) {
                   *query = '\0';
               }
  -            jk_log(logger, JK_LOG_DEBUG, 
  -                   "In HttpFilterProc test redirection of %s\n", 
  -                   uri);
  -            worker = map_uri_to_worker(uw_map, uri, logger);                
  +
  +            rc = unescape_url(uri);
  +            if (rc == BAD_REQUEST) {
  +                jk_log(logger, JK_LOG_ERROR, 
  +                       "HttpFilterProc [%s] contains on or more invalid escape sequences.\n",

  +                       uri);
  +                write_error_response(pfc,"400 Bad Request",
  +                        "<HTML><BODY><H1>Request contains invalid encoding</H1></BODY></HTML>");
  +                return SF_STATUS_REQ_FINISHED;
  +            }
  +            else if(rc == BAD_PATH) {
  +                jk_log(logger, JK_LOG_EMERG, 
  +                       "HttpFilterProc [%s] contains forbidden escape sequences.\n", 
  +                       uri);
  +                write_error_response(pfc,"403 Forbidden",
  +                        "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>");
  +                return SF_STATUS_REQ_FINISHED;
  +            }
  +            getparents(uri);
  +
  +			if(p->GetHeader(pfc, "Host:", (LPVOID)Host, (LPDWORD)&szHost)) {
  +				strcat(snuri,Host);
  +				strcat(snuri,uri);
  +				jk_log(logger, JK_LOG_DEBUG, 
  +					   "In HttpFilterProc Virtual Host redirection of %s\n", 
  +					   snuri);
  +				worker = map_uri_to_worker(uw_map, snuri, logger);                
  +			}
  +			if (!worker) {
  +				jk_log(logger, JK_LOG_DEBUG, 
  +					   "In HttpFilterProc test Default redirection of %s\n", 
  +					   uri);
  +				worker = map_uri_to_worker(uw_map, uri, logger);
  +			}
               if (query) {
                   *query = '?';
               }
  @@ -489,30 +667,14 @@
               jk_log(logger, JK_LOG_DEBUG, 
                      "HttpFilterProc check if [%s] is points to the web-inf directory\n",

                      uri);
  -
  -            if (uri_is_web_inf(uri)) {
  -                char crlf[3] = { (char)13, (char)10, '\0' };
  -                char ctype[30];
  -                char *msg = "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>";
  -                DWORD len = strlen(msg);
   
  +            if(uri_is_web_inf(uri)) {
                   jk_log(logger, JK_LOG_EMERG, 
  -                       "HttpFilterProc [%s] points to the web-inf directory.\nSomebody
try to hack into the site!!!\n", 
  +                       "HttpFilterProc [%s] points to the web-inf or meta-inf directory.\nSomebody
try to hack into the site!!!\n", 
                          uri);
   
  -                sprintf(ctype, 
  -                        "Content-Type:text/html%s%s", 
  -                        crlf, 
  -                        crlf);
  -
  -                /* reject !!! */
  -                pfc->ServerSupportFunction(pfc, 
  -                                           SF_REQ_SEND_RESPONSE_HEADER,
  -                                           "403 Forbidden",
  -                                           (DWORD)crlf,
  -                                           (DWORD)ctype);
  -                pfc->WriteClient(pfc, msg, &len, 0);
  -
  +                write_error_response(pfc,"403 Forbidden",
  +                        "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>");
                   return SF_STATUS_REQ_FINISHED;
               }
           }
  @@ -544,27 +706,26 @@
   
       jk_log(logger, JK_LOG_DEBUG, 
              "HttpExtensionProc started\n");
  +
  +	/* Initialise jk */
  +	if (is_inited && !is_mapread) {
  +		char serverName[MAX_SERVERNAME];
  +		DWORD dwLen = sizeof(serverName);
  +		if (lpEcb->GetServerVariable(lpEcb->ConnID, SERVER_NAME, serverName, &dwLen))
  +		{
  +			if (dwLen > 0) serverName[dwLen-1] = '\0';
  +			if (init_jk(serverName))
  +				is_mapread = JK_TRUE;
  +		}
  +		if (!is_mapread)
  +			is_inited = JK_FALSE;
  +	}
   
  -	/* Initialise jk */
  -	if (is_inited && !is_mapread) {
  -		char serverName[MAX_SERVERNAME];
  -		DWORD dwLen = sizeof(serverName);
  -		if (lpEcb->GetServerVariable(lpEcb->ConnID, SERVER_NAME, serverName, &dwLen))
  -		{
  -			if (dwLen > 0) serverName[dwLen-1] = '\0';
  -			if (init_jk(serverName))
  -				is_mapread = JK_TRUE;
  -		}
  -		if (!is_mapread)
  -			is_inited = JK_FALSE;
  -	}
  -
   	if (is_inited) {
           isapi_private_data_t private_data;
           jk_ws_service_t s;
           jk_pool_atom_t buf[SMALL_POOL_SIZE];
           char *worker_name;
  -
   
           jk_init_ws_service(&s);
           jk_open_pool(&private_data.p, buf, sizeof(buf));
  @@ -625,10 +786,10 @@
   {
       if (is_inited) {
           is_inited = JK_FALSE;
  -
  +
   		if (is_mapread) {
  -			uri_worker_map_free(&uw_map, logger);
  -			is_mapread = JK_FALSE;
  +			uri_worker_map_free(&uw_map, logger);
  +			is_mapread = JK_FALSE;
   		}
           wc_close(logger);
           if (logger) {
  @@ -645,6 +806,10 @@
                       LPVOID lpReserved)      // Reserved parameter for future use
   {
       BOOL fReturn = TRUE;
  +    char drive[_MAX_DRIVE];
  +    char dir[_MAX_DIR];
  +    char fname[_MAX_FNAME];
  +    char file_name[_MAX_PATH];
   
       switch (ulReason) {
           case DLL_PROCESS_DETACH:
  @@ -657,53 +822,71 @@
           default:
           break;
       } 
  +    if (GetModuleFileName( hInst, file_name, sizeof(file_name))) {
  +        _splitpath( file_name, drive, dir, fname, NULL );
  +        _makepath( ini_file_name, drive, dir, fname, ".properties" );
  +    } else {
  +        fReturn = JK_FALSE;
  +    }
   
       return fReturn;
  -}
  -
  -static int init_jk(char *serverName)
  -{
  -    int rc = JK_FALSE;  
  -    jk_map_t *map;
  -
  -    if (!jk_open_file_logger(&logger, log_file, log_level)) {
  -        logger = NULL;
  -    }
  -    
  -    if (map_alloc(&map)) {
  -        if (map_read_properties(map, worker_mount_file)) {
  -            if (uri_worker_map_alloc(&uw_map, map, logger)) {
  -                rc = JK_TRUE;
  -            }
  -        }
  -        map_free(&map);
  -    }
  -
  -    if (rc) {
  -        rc = JK_FALSE;
  -        if (map_alloc(&map)) {
  -            if (map_read_properties(map, worker_file)) {
  -				/* we add the URI->WORKER MAP since workers using AJP14 will feed it */
  -
  -				worker_env.uri_to_worker = uw_map;
  -				worker_env.server_name = serverName;
  -
  -                if (wc_open(map, &worker_env, logger)) {
  -                    rc = JK_TRUE;
  -                }
  -            }
  -            map_free(&map);
  -        }
  -    }
  -
  -	return rc;
   }
   
  +static int init_jk(char *serverName)
  +{
  +    int rc = JK_FALSE;  
  +    jk_map_t *map;
  +
  +    if (!jk_open_file_logger(&logger, log_file, log_level)) {
  +        logger = NULL;
  +    }
  +    		/* Logging the initialization type: registry or properties file in virtual dir
  +		*/
  +	if (using_ini_file) {
  +			 jk_log(logger, JK_LOG_DEBUG, "Using ini file %s.\n", ini_file_name);
  +	} else {
  +			 jk_log(logger, JK_LOG_DEBUG, "Using registry.\n");
  +	}
  +	jk_log(logger, JK_LOG_DEBUG, "Using log file %s.\n", log_file);
  +	jk_log(logger, JK_LOG_DEBUG, "Using log level %d.\n", log_level);
  +	jk_log(logger, JK_LOG_DEBUG, "Using extension uri %s.\n", extension_uri);
  +	jk_log(logger, JK_LOG_DEBUG, "Using worker file %s.\n", worker_file);
  +	jk_log(logger, JK_LOG_DEBUG, "Using worker mount file %s.\n", worker_mount_file);
  +
  +    if (map_alloc(&map)) {
  +        if (map_read_properties(map, worker_mount_file)) {
  +            if (uri_worker_map_alloc(&uw_map, map, logger)) {
  +                rc = JK_TRUE;
  +            }
  +        }
  +        map_free(&map);
  +    }
  +
  +    if (rc) {
  +        rc = JK_FALSE;
  +        if (map_alloc(&map)) {
  +            if (map_read_properties(map, worker_file)) {
  +				/* we add the URI->WORKER MAP since workers using AJP14 will feed it */
  +
  +				worker_env.uri_to_worker = uw_map;
  +				worker_env.server_name = serverName;
  +
  +                if (wc_open(map, &worker_env, logger)) {
  +                    rc = JK_TRUE;
  +                }
  +            }
  +            map_free(&map);
  +        }
  +    }
  +
  +	return rc;
  +}
  +
   static int initialize_extension(void)
   {
  -
  +
       if (read_registry_init_data()) {
  -        is_inited = JK_TRUE;
  +        is_inited = JK_TRUE;
       }
       return is_inited;
   }
  @@ -714,64 +897,105 @@
       HKEY hkey;
       long rc;
       int  ok = JK_TRUE;
  -    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  -                      REGISTRY_LOCATION,
  -                      (DWORD)0,         
  -                      KEY_READ,         
  -                      &hkey);            
  -    if (ERROR_SUCCESS != rc) {
  -        return JK_FALSE;
  -    } 
  +    char *tmp;
  +    jk_map_t *map;
   
  -    if (get_registry_config_parameter(hkey,
  -                                     JK_LOG_FILE_TAG, 
  -                                     tmpbuf,
  -                                     sizeof(log_file))) {
  -        strcpy(log_file, tmpbuf);
  -    } else {
  -        ok = JK_FALSE;
  +    if (map_alloc(&map)) {
  +        if (map_read_properties(map, ini_file_name)) {
  +            using_ini_file = JK_TRUE;
  +		}
       }
  +    if (using_ini_file) {
  +        tmp = map_get_string(map, JK_LOG_FILE_TAG, NULL);
  +        if (tmp) {
  +            strcpy(log_file, tmp);
  +        } else {
  +            ok = JK_FALSE;
  +        }
  +        tmp = map_get_string(map, JK_LOG_LEVEL_TAG, NULL);
  +        if (tmp) {
  +            log_level = jk_parse_log_level(tmp);
  +        } else {
  +            ok = JK_FALSE;
  +        }
  +        tmp = map_get_string(map, EXTENSION_URI_TAG, NULL);
  +        if (tmp) {
  +            strcpy(extension_uri, tmp);
  +        } else {
  +            ok = JK_FALSE;
  +        }
  +        tmp = map_get_string(map, JK_WORKER_FILE_TAG, NULL);
  +        if (tmp) {
  +            strcpy(worker_file, tmp);
  +        } else {
  +            ok = JK_FALSE;
  +        }
  +        tmp = map_get_string(map, JK_MOUNT_FILE_TAG, NULL);
  +        if (tmp) {
  +            strcpy(worker_mount_file, tmp);
  +        } else {
  +            ok = JK_FALSE;
  +        }
       
  -    if (get_registry_config_parameter(hkey,
  -                                     JK_LOG_LEVEL_TAG, 
  -                                     tmpbuf,
  -                                     sizeof(tmpbuf))) {
  -        log_level = jk_parse_log_level(tmpbuf);
  -    } else {
  -        ok = JK_FALSE;
  -    }
  -
  -    if (get_registry_config_parameter(hkey,
  -                                     EXTENSION_URI_TAG, 
  -                                     tmpbuf,
  -                                     sizeof(extension_uri))) {
  -        strcpy(extension_uri, tmpbuf);
       } else {
  -        ok = JK_FALSE;
  -    }
  +		rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  +						  REGISTRY_LOCATION,
  +						  (DWORD)0,         
  +						  KEY_READ,         
  +						  &hkey);            
  +		if(ERROR_SUCCESS != rc) {
  +			return JK_FALSE;
  +		} 
  +
  +		if(get_registry_config_parameter(hkey,
  +										 JK_LOG_FILE_TAG, 
  +										 tmpbuf,
  +										 sizeof(log_file))) {
  +			strcpy(log_file, tmpbuf);
  +		} else {
  +			ok = JK_FALSE;
  +		}
  +    
  +		if(get_registry_config_parameter(hkey,
  +										 JK_LOG_LEVEL_TAG, 
  +										 tmpbuf,
  +										 sizeof(tmpbuf))) {
  +			log_level = jk_parse_log_level(tmpbuf);
  +		} else {
  +			ok = JK_FALSE;
  +		}
   
  -    if (get_registry_config_parameter(hkey,
  -                                     JK_WORKER_FILE_TAG, 
  -                                     tmpbuf,
  -                                     sizeof(worker_file))) {
  -        strcpy(worker_file, tmpbuf);
  -    } else {
  -        ok = JK_FALSE;
  -    }
  +		if(get_registry_config_parameter(hkey,
  +										 EXTENSION_URI_TAG, 
  +										 tmpbuf,
  +										 sizeof(extension_uri))) {
  +			strcpy(extension_uri, tmpbuf);
  +		} else {
  +			ok = JK_FALSE;
  +		}
   
  -    if (get_registry_config_parameter(hkey,
  -                                     JK_MOUNT_FILE_TAG, 
  -                                     tmpbuf,
  -                                     sizeof(worker_mount_file))) {
  -        strcpy(worker_mount_file, tmpbuf);
  -    } else {
  -        ok = JK_FALSE;
  -    }
  +		if(get_registry_config_parameter(hkey,
  +										 JK_WORKER_FILE_TAG, 
  +										 tmpbuf,
  +										 sizeof(worker_file))) {
  +			strcpy(worker_file, tmpbuf);
  +		} else {
  +			ok = JK_FALSE;
  +		}
   
  -    RegCloseKey(hkey);
  +		if(get_registry_config_parameter(hkey,
  +										 JK_MOUNT_FILE_TAG, 
  +										 tmpbuf,
  +										 sizeof(worker_mount_file))) {
  +			strcpy(worker_mount_file, tmpbuf);
  +		} else {
  +			ok = JK_FALSE;
  +		}
   
  +		RegCloseKey(hkey);
  +    }    
       return ok;
  -}
  +} 
   
   static int get_registry_config_parameter(HKEY hkey,
                                            const char *tag, 
  @@ -827,6 +1051,9 @@
           s->query_string = private_data->lpEcb->lpszQueryString;
           *worker_name    = JK_AJP12_WORKER_NAME;
           GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);       
  +        if (unescape_url(s->req_uri) < 0)
  +            return JK_FALSE;
  +        getparents(s->req_uri);
       }
       
       GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type);
  @@ -904,6 +1131,28 @@
                   }
               }
               s->num_attributes = num_of_vars;
  + 			if (ssl_env_values[4] && ssl_env_values[4][0] == '1') {
  +				CERT_CONTEXT_EX cc;
  +				DWORD cc_sz = sizeof(cc);
  +				cc.cbAllocated = sizeof(huge_buf);
  +				cc.CertContext.pbCertEncoded = (BYTE*) huge_buf;
  +				cc.CertContext.cbCertEncoded = 0;
  +
  +				if (private_data->lpEcb->ServerSupportFunction(private_data->lpEcb->ConnID,
  +											 (DWORD)HSE_REQ_GET_CERT_INFO_EX,                               
  +											 (LPVOID)&cc,NULL,NULL) != FALSE)
  +				{
  +					jk_log(logger, JK_LOG_DEBUG,"Client Certificate encoding:%d sz:%d flags:%ld\n",
  +								cc.CertContext.dwCertEncodingType & X509_ASN_ENCODING ,
  +								cc.CertContext.cbCertEncoded,
  +								cc.dwCertificateFlags);
  +                    s->ssl_cert=jk_pool_alloc(&private_data->p,
  +                                base64_encode_cert_len(cc.CertContext.cbCertEncoded));
  +
  +                    s->ssl_cert_len = base64_encode_cert(s->ssl_cert,
  +                                huge_buf,cc.CertContext.cbCertEncoded) - 1;
  +				}
  +			}
           }
       }
   
  @@ -926,10 +1175,12 @@
               char *headers_buf = jk_pool_strdup(&private_data->p, huge_buf);
               unsigned i;
               unsigned len_of_http_prefix = strlen("HTTP_");
  +            BOOL need_content_length_header = (s->content_length == 0);
               
               cnt -= 2; /* For our two special headers */
  -            s->headers_names  = jk_pool_alloc(&private_data->p, cnt * sizeof(char
*));
  -            s->headers_values = jk_pool_alloc(&private_data->p, cnt * sizeof(char
*));
  +            /* allocate an extra header slot in case we need to add a content-length header
*/
  +            s->headers_names  = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char
*));
  +            s->headers_values = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char
*));
   
               if (!s->headers_names || !s->headers_values || !headers_buf) {
                   return JK_FALSE;
  @@ -944,6 +1195,10 @@
                   if (!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME)) ||
                      !strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME))) {
                       real_header = JK_FALSE;
  +                } else if(need_content_length_header &&
  +                   !strnicmp(tmp, CONTENT_LENGTH, strlen(CONTENT_LENGTH))) {
  +                    need_content_length_header = FALSE;
  +                    s->headers_names[i]  = tmp;
                   } else {
                       s->headers_names[i]  = tmp;
                   }
  @@ -983,6 +1238,15 @@
                       i++;
                   }
               }
  +            /* Add a content-length = 0 header if needed.
  +             * Ajp13 assumes an absent content-length header means an unknown,
  +             * but non-zero length body.
  +             */
  +            if(need_content_length_header) {
  +                s->headers_names[cnt] = "content-length";
  +                s->headers_values[cnt] = "0";
  +                cnt++;
  +            }
               s->num_headers = cnt;
           } else {
               /* We must have our two headers */
  @@ -1015,3 +1279,76 @@
   
       return JK_TRUE;
   }
  +
  +static const char begin_cert [] = 
  +	"-----BEGIN CERTIFICATE-----\r\n";
  +
  +static const char end_cert [] = 
  +	"-----END CERTIFICATE-----\r\n";
  +
  +static const char basis_64[] =
  +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  +
  +static int base64_encode_cert_len(int len)
  +{
  +	int n = ((len + 2) / 3 * 4) + 1; // base64 encoded size
  +	n += (n + 63 / 64) * 2; // add CRLF's
  +	n += sizeof(begin_cert) + sizeof(end_cert) - 2;  // add enclosing strings.
  +    return n;
  +}
  +
  +static int base64_encode_cert(char *encoded,
  +                              const unsigned char *string, int len)
  +{
  +    int i,c;
  +    char *p;
  +	const char *t;
  +
  +    p = encoded;
  +
  +	t = begin_cert;
  +	while (*t != '\0')
  +		*p++ = *t++;
  +
  +    c = 0;
  +    for (i = 0; i < len - 2; i += 3) {
  +        *p++ = basis_64[(string[i] >> 2) & 0x3F];
  +        *p++ = basis_64[((string[i] & 0x3) << 4) |
  +                        ((int) (string[i + 1] & 0xF0) >> 4)];
  +        *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
  +                        ((int) (string[i + 2] & 0xC0) >> 6)];
  +        *p++ = basis_64[string[i + 2] & 0x3F];
  +        c += 4;
  +        if ( c >= 64 ) {
  +            *p++ = '\r';
  +            *p++ = '\n';
  +            c = 0;
  +		}
  +    }
  +    if (i < len) {
  +        *p++ = basis_64[(string[i] >> 2) & 0x3F];
  +        if (i == (len - 1)) {
  +            *p++ = basis_64[((string[i] & 0x3) << 4)];
  +            *p++ = '=';
  +        }
  +        else {
  +            *p++ = basis_64[((string[i] & 0x3) << 4) |
  +                            ((int) (string[i + 1] & 0xF0) >> 4)];
  +            *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
  +        }
  +        *p++ = '=';
  +        c++;
  +    }
  +    if ( c != 0 ) {
  +        *p++ = '\r';
  +        *p++ = '\n';
  +    }
  +
  +	t = end_cert;
  +	while (*t != '\0')
  +		*p++ = *t++;
  +
  +    *p++ = '\0';
  +    return p - encoded;
  +}
  +
  
  
  

Mime
View raw message