Index: src/cgi.c ================================================================== --- src/cgi.c +++ src/cgi.c @@ -354,11 +354,11 @@ /* ** Do a redirect request to the URL given in the argument. ** ** The URL must be relative to the base of the fossil server. */ -NORETURN static void cgi_redirect_with_status( +NORETURN void cgi_redirect_with_status( const char *zURL, int iStat, const char *zStat ){ char *zLocation; Index: src/login.c ================================================================== --- src/login.c +++ src/login.c @@ -549,34 +549,11 @@ const char *zIpAddr; /* IP address of requestor */ const char *zReferer; int noAnon = P("noanon")!=0; login_check_credentials(); - if( login_wants_https_redirect() ){ - const char *zQS = P("QUERY_STRING"); - if( P("redir")!=0 ){ - style_header("Insecure Connection"); - @
This website requires that login credentials be sent over - @ an encrypted connection. The current connection is not encrypted - @ across the entire route between your browser and the server. - @ An attempt was made to redirect to %h(g.zHttpsURL) but - @ the connection is still insecure even after the redirect.
- @This is probably some kind of configuration problem. Please - @ contact your sysadmin.
- @Sorry it did not work out.
- style_footer(); - return; - } - if( zQS==0 ){ - zQS = "?redir=1"; - }else if( zQS[0]!=0 ){ - zQS = mprintf("?%s&redir=1", zQS); - } - cgi_redirectf("%s%T%s", g.zHttpsURL, P("PATH_INFO"), zQS); - return; - } + fossil_redirect_to_https_if_needed(1); sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, constant_time_cmp_function, 0, 0); zUsername = P("u"); zPasswd = P("p"); anonFlag = g.zLogin==0 && PB("anon"); @@ -914,26 +891,10 @@ " AND constant_time_cmp(cookie,%Q)=0", zLogin, zRemoteAddr, zCookie ); return uid; } - -/* -** Return true if it is appropriate to redirect login requests to HTTPS. -** -** Redirect to https is appropriate if all of the above are true: -** (1) The redirect-to-https flag is set -** (2) The current connection is http, not https or ssh -** (3) The sslNotAvailable flag is clear -*/ -int login_wants_https_redirect(void){ - if( g.sslNotAvailable ) return 0; - if( db_get_boolean("redirect-to-https",0)==0 ) return 0; - if( P("HTTPS")!=0 ) return 0; - return 1; -} - /* ** Attempt to use Basic Authentication to establish the user. Return the ** (non-zero) uid if successful. Return 0 if it does not work. */ @@ -1461,11 +1422,11 @@ { const char *zUrl = PD("REQUEST_URI", "index"); const char *zQS = P("QUERY_STRING"); Blob redir; blob_init(&redir, 0, 0); - if( login_wants_https_redirect() && !g.sslNotAvailable ){ + if( fossil_wants_https(1) ){ blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl); }else{ blob_appendf(&redir, "%R/login?g=%T", zUrl); } if( anonOk ) blob_append(&redir, "&anon", 5); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -1334,10 +1334,60 @@ } #endif db_panic_close(); exit(1); } + +/* +** Return true if it is appropriate to redirect requests to HTTPS. +** +** Redirect to https is appropriate if all of the above are true: +** (1) The redirect-to-https flag has a valud of iLevel or greater. +** (2) The current connection is http, not https or ssh +** (3) The sslNotAvailable flag is clear +*/ +int fossil_wants_https(int iLevel){ + if( g.sslNotAvailable ) return 0; + if( db_get_int("redirect-to-https",0)This website requires an encrypted connection. + @ The current connection is not encrypted + @ across the entire route between your browser and the server. + @ An attempt was made to redirect to %h(g.zHttpsURL) but + @ the connection is still insecure even after the redirect.
+ @This is probably some kind of configuration problem. Please + @ contact your sysadmin.
+ @Sorry it did not work out.
+ style_footer(); + cgi_reply(); + return 1; + } + if( zQS==0 || zQS[0]==0 ){ + zURL = mprintf("%s%T?redir=1", g.zHttpsURL, P("PATH_INFO")); + }else if( zQS[0]!=0 ){ + zURL = mprintf("%s%T?%s&redir=1", g.zHttpsURL, P("PATH_INFO"), zQS); + } + cgi_redirect_with_status(zURL, 301, "Moved Permanently"); + return 1; + } + return 0; +} /* ** Preconditions: ** ** * Environment variables are set up according to the CGI standard. @@ -1609,10 +1659,11 @@ /* Use the first element of PATH_INFO as the page name ** and deliver the appropriate page back to the user. */ set_base_url(0); + if( fossil_redirect_to_https_if_needed(2) ) return; if( zPathInfo==0 || zPathInfo[0]==0 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ /* Second special case: If the PATH_INFO is blank, issue a redirect to ** the home page identified by the "index-page" setting in the repository ** CONFIG table, to "/index" if there no "index-page" setting. */ @@ -2427,11 +2478,12 @@ ** --https signal a request coming in via https ** --max-latency N Do not let any single HTTP request run for more than N ** seconds (only works on unix) ** --nocompress Do not compress HTTP replies ** --nojail Drop root privileges but do not enter the chroot jail -** --nossl signal that no SSL connections are available +** --nossl signal that no SSL connections are available (Always +** set by default for the "ui" command) ** --notfound URL Redirect ** -P|--port TCPPORT listen to request on port TCPPORT ** --th-trace trace TH1 execution (for debugging purposes) ** --repolist If REPOSITORY is dir, URL "/" lists repos. ** --scgi Accept SCGI rather than HTTP @@ -2498,11 +2550,11 @@ fCreate = find_option("create",0,0)!=0; if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI; if( zAltBase ){ set_base_url(zAltBase); } - g.sslNotAvailable = find_option("nossl", 0, 0)!=0; + g.sslNotAvailable = find_option("nossl", 0, 0)!=0 || isUiCmd; if( find_option("https",0,0)!=0 ){ cgi_replace_parameter("HTTPS","on"); } if( find_option("localhost", 0, 0)!=0 ){ flags |= HTTP_SERVER_LOCALHOST; Index: src/setup.c ================================================================== --- src/setup.c +++ src/setup.c @@ -284,11 +284,11 @@ const char *zLabel, /* The text label on the menu */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQP, /* The query parameter */ const char *zDflt, /* Default value if VAR table entry does not exist */ int nChoice, /* Number of choices */ - const char *const *azChoice /* Choices. 2 per choice: (VAR value, Display) */ + const char *const *azChoice /* Choices in pairs (VAR value, Display) */ ){ const char *z = db_get(zVar, zDflt); const char *zQ = P(zQP); int i; if( zQ && fossil_strcmp(zQ,z)!=0){ @@ -312,10 +312,15 @@ ** WEBPAGE: setup_access ** ** The access-control settings page. Requires Setup privileges. */ void setup_access(void){ + static const char * const azRedirectOpts[] = { + "0", "Off", + "1", "Login Page Only", + "2", "All Pages" + }; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } @@ -324,18 +329,21 @@ db_begin_transaction(); @