Index: src/http_ssl.c ================================================================== --- src/http_ssl.c +++ src/http_ssl.c @@ -705,10 +705,12 @@ ** a built-in self-signed cert is used. */ void ssl_init_server(const char *zCertFile, const char *zKeyFile){ if( sslIsInit==0 ){ const char *zTlsCert; + db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0); + db_open_config(1,0); SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); sslCtx = SSL_CTX_new(SSLv23_server_method()); if( sslCtx==0 ){ @@ -919,11 +921,11 @@ } db_unprotect(PROTECT_ALL); db_multi_exec( "PRAGMA secure_delete=ON;" "DELETE FROM config " - " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');" + " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-key-file');" ); db_protect_pop(); }else if( strncmp("load-cert",zCmd,nCmd)==0 && nCmd>=4 ){ int bFN = find_option("filename",0,0)!=0; @@ -935,11 +937,11 @@ db_begin_transaction(); db_unprotect(PROTECT_ALL); db_multi_exec( "PRAGMA secure_delete=ON;" "DELETE FROM config " - " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');" + " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-key-file');" ); nHit = 0; for(i=3; i<g.argc; i++){ Blob x; int isCert; @@ -958,11 +960,10 @@ fossil_fatal("more than one certificate provided"); } haveCert = 1; if( bFN ){ db_set("ssl-cert-file", file_canonical_name_dup(g.argv[i]), 0); - }else{ blob_append(&allText, blob_buffer(&x), blob_size(&x)); } if( isKey && !haveKey ){ haveKey = 1; isKey = 0; @@ -973,11 +974,10 @@ fossil_fatal("more than one private key provided"); } haveKey = 1; if( bFN ){ db_set("ssl-key-file", file_canonical_name_dup(g.argv[i]), 0); - }else{ blob_append(&allText, blob_buffer(&x), blob_size(&x)); } } } if( !haveCert ){ @@ -987,11 +987,11 @@ fossil_fatal("missing certificate"); } }else if( !haveKey ){ fossil_fatal("missing private-key"); } - if( !bFN ){ + if( bFN ){ db_set("ssl-cert", blob_str(&allText), 0); } db_protect_pop(); db_commit_transaction(); }else Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -2589,10 +2589,26 @@ } } #endif @ %d(GETPID()) } + +/* +** Initialize the SSL decoder. +*/ +static void init_ssl_decoder(const char *zCertFile, int tls){ +#if FOSSIL_ENABLE_SSL + if( zCertFile ){ + g.httpUseSSL = 1; + ssl_init_server(zCertFile, zCertFile); + } + if( 1 == tls ){ + g.httpUseSSL = 1; + ssl_init_server(0,0); + } +#endif +} /* ** Check for options to "fossil server" or "fossil ui" that imply that ** SSL should be used, and initialize the SSL decoder. */ @@ -2599,16 +2615,14 @@ static void decode_ssl_options(void){ #if FOSSIL_ENABLE_SSL const char *zCertFile = 0; zCertFile = find_option("tls-cert-file",0,1); if( zCertFile ){ - g.httpUseSSL = 1; - ssl_init_server(zCertFile, zCertFile); + init_ssl_decoder(zCertFile, 0); } if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){ - g.httpUseSSL = 1; - ssl_init_server(0,0); + init_ssl_decoder(0, 1); } #endif } /* @@ -3049,12 +3063,15 @@ const char *zInitPage = 0; /* Start on this page. --page option */ int findServerArg = 2; /* argv index for find_server_repository() */ char *zRemote = 0; /* Remote host on which to run "fossil ui" */ const char *zJsMode; /* The --jsmode parameter */ const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */ - - +#if FOSSIL_ENABLE_SSL + const char *zCertFile =0; /* Internal - TLS/SSL cert filename of the --tls-cert-file option */ + int zTls =0; /* Internal - 1 = use a TLS/SSL cert that has been previously loaded by ssl-config load-cert command or 0 if no TLS / SSL has been loaeded */ +#endif + const char *zHttps =0; /* Internal - set if if --https is present */ #if defined(_WIN32) const char *zStopperFile; /* Name of file used to terminate server */ zStopperFile = find_option("stopper", 0, 1); #endif @@ -3096,14 +3113,23 @@ if( zAltBase ){ set_base_url(zAltBase); } g.sslNotAvailable = find_option("nossl", 0, 0)!=0 || isUiCmd; fNoBrowser = find_option("nobrowser", 0, 0)!=0; - decode_ssl_options(); - if( find_option("https",0,0)!=0 || g.httpUseSSL ){ - cgi_replace_parameter("HTTPS","on"); + + /* + ** get tls / ssl options, the calls that use these options need + ** access to the repo database which has not been found yet. + ** we get and store them now, as find_option removes them from + ** argv + */ +#if FOSSIL_ENABLE_SSL + zCertFile = find_option("tls-cert-file",0,1); + if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){ + zTls = 1; } +#endif if( find_option("localhost", 0, 0)!=0 ){ flags |= HTTP_SERVER_LOCALHOST; } g.zCkoutAlias = find_option("ckout-alias",0,1); g.zMainMenuFile = find_option("mainmenu",0,1); @@ -3123,17 +3149,15 @@ #if !defined(_WIN32) /* Disable the timeout during debugging */ zTimeout = "100000000"; #endif } + zHttps = find_option("https",0,0); /* We should be done with options.. */ verify_all_options(); if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); - if( g.httpUseSSL && (flags & HTTP_SERVER_SCGI)!=0 ){ - fossil_fatal("SCGI does not (yet) support TLS-encrypted connections"); - } if( isUiCmd && 3==g.argc && file_isdir(g.argv[2], ExtFILE)>0 ){ /* If REPOSITORY arg is the root of a checkout, ** chdir to that checkout so that the current version ** gets highlighted in the timeline by default. */ const char * zDir = g.argv[2]; @@ -3166,10 +3190,26 @@ allowRepoList = 1; } if( !zRemote ){ find_server_repository(findServerArg, fCreate); } + /* + ** We need call enable TLS / SSL here as we need query the + ** repo database to access the certificate if its been loaded + ** + ** The database has only just been found and made available + */ +#if FOSSIL_ENABLE_SSL + init_ssl_decoder(zCertFile, zTls); +#endif + if( zHttps !=0 || g.httpUseSSL ){ + cgi_replace_parameter("HTTPS","on"); + } + if( g.httpUseSSL && (flags & HTTP_SERVER_SCGI)!=0 ){ + fossil_fatal("SCGI does not (yet) support TLS-encrypted connections"); + } + if( zInitPage==0 ){ if( isUiCmd && g.localOpen ){ zInitPage = "timeline?c=current"; }else{ zInitPage = "";