| | @@ -18,20 +18,21 @@ |
| 18 | 18 | ** This module codes the main() procedure that runs first when the |
| 19 | 19 | ** program is invoked. |
| 20 | 20 | */ |
| 21 | 21 | #include "VERSION.h" |
| 22 | 22 | #include "config.h" |
| 23 | +#if defined(_WIN32) |
| 24 | +# include <windows.h> |
| 25 | +#endif |
| 23 | 26 | #include "main.h" |
| 24 | 27 | #include <string.h> |
| 25 | 28 | #include <time.h> |
| 26 | 29 | #include <fcntl.h> |
| 27 | 30 | #include <sys/types.h> |
| 28 | 31 | #include <sys/stat.h> |
| 29 | 32 | #include <stdlib.h> /* atexit() */ |
| 30 | | -#if defined(_WIN32) |
| 31 | | -# include <windows.h> |
| 32 | | -#else |
| 33 | +#if !defined(_WIN32) |
| 33 | 34 | # include <errno.h> /* errno global */ |
| 34 | 35 | #endif |
| 35 | 36 | #ifdef FOSSIL_ENABLE_SSL |
| 36 | 37 | # include "openssl/crypto.h" |
| 37 | 38 | #endif |
| | @@ -1929,10 +1930,41 @@ |
| 1929 | 1930 | } |
| 1930 | 1931 | } |
| 1931 | 1932 | } |
| 1932 | 1933 | } |
| 1933 | 1934 | |
| 1935 | +#if defined(_WIN32) && USE_SEE |
| 1936 | +/* |
| 1937 | +** This function attempts to parse a string value in the following |
| 1938 | +** format: |
| 1939 | +** |
| 1940 | +** "%lu:%p:%u" |
| 1941 | +** |
| 1942 | +** There are three parts, which must be delimited by colons. The |
| 1943 | +** first part is an unsigned long integer in base-10 (decimal) format. |
| 1944 | +** The second part is a numerical representation of a native pointer, |
| 1945 | +** in the appropriate implementation defined format. The third part |
| 1946 | +** is an unsigned integer in base-10 (decimal) format. |
| 1947 | +** |
| 1948 | +** If the specified value cannot be parsed, for any reason, a fatal |
| 1949 | +** error will be raised and the process will be terminated. |
| 1950 | +*/ |
| 1951 | +void parse_pid_key_value( |
| 1952 | + const char *zPidKey, /* The value to be parsed. */ |
| 1953 | + DWORD *pProcessId, /* The extracted process identifier. */ |
| 1954 | + LPVOID *ppAddress, /* The extracted pointer value. */ |
| 1955 | + SIZE_T *pnSize /* The extracted size value. */ |
| 1956 | +){ |
| 1957 | + unsigned int nSize = 0; |
| 1958 | + if( sscanf(zPidKey, "%lu:%p:%u", pProcessId, ppAddress, &nSize)==3 ){ |
| 1959 | + *pnSize = (SIZE_T)nSize; |
| 1960 | + }else{ |
| 1961 | + fossil_fatal("failed to parse pid key"); |
| 1962 | + } |
| 1963 | +} |
| 1964 | +#endif |
| 1965 | + |
| 1934 | 1966 | /* |
| 1935 | 1967 | ** undocumented format: |
| 1936 | 1968 | ** |
| 1937 | 1969 | ** fossil http INFILE OUTFILE IPADDR ?REPOSITORY? |
| 1938 | 1970 | ** |
| | @@ -1980,10 +2012,12 @@ |
| 1980 | 2012 | ** --notfound URL use URL as "HTTP 404, object not found" page. |
| 1981 | 2013 | ** --repolist If REPOSITORY is directory, URL "/" lists all repos |
| 1982 | 2014 | ** --scgi Interpret input as SCGI rather than HTTP |
| 1983 | 2015 | ** --skin LABEL Use override skin LABEL |
| 1984 | 2016 | ** --th-trace trace TH1 execution (for debugging purposes) |
| 2017 | +** --usepidkey Use saved encryption key from parent process. This is |
| 2018 | +** only necessary when using SEE on Windows. |
| 1985 | 2019 | ** |
| 1986 | 2020 | ** See also: cgi, server, winsrv |
| 1987 | 2021 | */ |
| 1988 | 2022 | void cmd_http(void){ |
| 1989 | 2023 | const char *zIpAddr = 0; |
| | @@ -1992,10 +2026,13 @@ |
| 1992 | 2026 | const char *zAltBase; |
| 1993 | 2027 | const char *zFileGlob; |
| 1994 | 2028 | int useSCGI; |
| 1995 | 2029 | int noJail; |
| 1996 | 2030 | int allowRepoList; |
| 2031 | +#if defined(_WIN32) && USE_SEE |
| 2032 | + const char *zPidKey; |
| 2033 | +#endif |
| 1997 | 2034 | |
| 1998 | 2035 | Th_InitTraceLog(); |
| 1999 | 2036 | |
| 2000 | 2037 | /* The winhttp module passes the --files option as --files-urlenc with |
| 2001 | 2038 | ** the argument being URL encoded, to avoid wildcard expansion in the |
| | @@ -2022,10 +2059,21 @@ |
| 2022 | 2059 | zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ |
| 2023 | 2060 | cgi_replace_parameter("HTTPS","on"); |
| 2024 | 2061 | } |
| 2025 | 2062 | zHost = find_option("host", 0, 1); |
| 2026 | 2063 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); |
| 2064 | + |
| 2065 | +#if defined(_WIN32) && USE_SEE |
| 2066 | + zPidKey = find_option("usepidkey", 0, 1); |
| 2067 | + if( zPidKey ){ |
| 2068 | + DWORD processId = 0; |
| 2069 | + LPVOID pAddress = NULL; |
| 2070 | + SIZE_T nSize = 0; |
| 2071 | + parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize); |
| 2072 | + db_read_saved_encryption_key_from_process(processId, pAddress, nSize); |
| 2073 | + } |
| 2074 | +#endif |
| 2027 | 2075 | |
| 2028 | 2076 | /* We should be done with options.. */ |
| 2029 | 2077 | verify_all_options(); |
| 2030 | 2078 | |
| 2031 | 2079 | if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){ |
| | @@ -2183,11 +2231,12 @@ |
| 2183 | 2231 | ** -P|--port TCPPORT listen to request on port TCPPORT |
| 2184 | 2232 | ** --th-trace trace TH1 execution (for debugging purposes) |
| 2185 | 2233 | ** --repolist If REPOSITORY is dir, URL "/" lists repos. |
| 2186 | 2234 | ** --scgi Accept SCGI rather than HTTP |
| 2187 | 2235 | ** --skin LABEL Use override skin LABEL |
| 2188 | | - |
| 2236 | +** --usepidkey Use saved encryption key from parent process. This is |
| 2237 | +** only necessary when using SEE on Windows. |
| 2189 | 2238 | ** |
| 2190 | 2239 | ** See also: cgi, http, winsrv |
| 2191 | 2240 | */ |
| 2192 | 2241 | void cmd_webserver(void){ |
| 2193 | 2242 | int iPort, mxPort; /* Range of TCP ports allowed */ |
| | @@ -2204,10 +2253,13 @@ |
| 2204 | 2253 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2205 | 2254 | const char *zFileGlob; /* Static content must match this */ |
| 2206 | 2255 | char *zIpAddr = 0; /* Bind to this IP address */ |
| 2207 | 2256 | int fCreate = 0; /* The --create flag */ |
| 2208 | 2257 | const char *zInitPage = 0; /* Start on this page. --page option */ |
| 2258 | +#if defined(_WIN32) && USE_SEE |
| 2259 | + const char *zPidKey; |
| 2260 | +#endif |
| 2209 | 2261 | |
| 2210 | 2262 | #if defined(_WIN32) |
| 2211 | 2263 | const char *zStopperFile; /* Name of file used to terminate server */ |
| 2212 | 2264 | zStopperFile = find_option("stopper", 0, 1); |
| 2213 | 2265 | #endif |
| | @@ -2247,10 +2299,21 @@ |
| 2247 | 2299 | g.sslNotAvailable = 1; |
| 2248 | 2300 | } |
| 2249 | 2301 | if( find_option("localhost", 0, 0)!=0 ){ |
| 2250 | 2302 | flags |= HTTP_SERVER_LOCALHOST; |
| 2251 | 2303 | } |
| 2304 | + |
| 2305 | +#if defined(_WIN32) && USE_SEE |
| 2306 | + zPidKey = find_option("usepidkey", 0, 1); |
| 2307 | + if( zPidKey ){ |
| 2308 | + DWORD processId = 0; |
| 2309 | + LPVOID pAddress = NULL; |
| 2310 | + SIZE_T nSize = 0; |
| 2311 | + parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize); |
| 2312 | + db_read_saved_encryption_key_from_process(processId, pAddress, nSize); |
| 2313 | + } |
| 2314 | +#endif |
| 2252 | 2315 | |
| 2253 | 2316 | /* We should be done with options.. */ |
| 2254 | 2317 | verify_all_options(); |
| 2255 | 2318 | |
| 2256 | 2319 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 2257 | 2320 | |