Fossil SCM

Rename the "tls-config" command into "ssl-config" for consistency. The older "tls-config" command is retained as an alias. Enhance the command to support server certificate management.

drh 2021-12-27 16:13 ssl-server
Commit f6051784c5eef7377e70eed4100584912f9a8f6db272505409749b0f913ed52c
2 files changed +232 -17 +3 -1
+232 -17
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -697,13 +697,13 @@
697697
** of disk files that hold the certificate and private-key for the
698698
** server. If zCertFile is not NULL but zKeyFile is NULL, then
699699
** zCertFile is assumed to be a concatenation of the certificate and
700700
** the private-key in the PEM format.
701701
**
702
-** If zCertFile is NULL, then "tls-server-cert" setting is consulted
702
+** If zCertFile is NULL, then "ssl-cert" setting is consulted
703703
** to get the certificate and private-key (concatenated together, in
704
-** the PEM format). If there is no tls-server-cert setting, then
704
+** the PEM format). If there is no ssl-cert setting, then
705705
** a built-in self-signed cert is used.
706706
*/
707707
void ssl_init_server(const char *zCertFile, const char *zKeyFile){
708708
if( sslIsInit==0 ){
709709
const char *zTlsCert;
@@ -724,16 +724,16 @@
724724
if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
725725
ERR_print_errors_fp(stderr);
726726
fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile);
727727
}
728728
}else
729
- if( (zTlsCert = db_get("tls-server-cert",0))!=0 ){
729
+ if( (zTlsCert = db_get("ssl-cert",0))!=0 ){
730730
if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1)
731731
|| sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1)
732732
){
733733
fossil_fatal("Error loading the CERT from the"
734
- " 'tls-server-cert' setting");
734
+ " 'ssl-cert' setting");
735735
}
736736
}else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
737737
|| sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){
738738
fossil_fatal("Error loading self-signed CERT");
739739
}
@@ -846,25 +846,41 @@
846846
847847
#endif /* FOSSIL_ENABLE_SSL */
848848
849849
/*
850850
** COMMAND: tls-config*
851
+** COMMAND: ssl-config
851852
**
852
-** Usage: %fossil tls-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
853
+** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
853854
**
854855
** This command is used to view or modify the TLS (Transport Layer
855856
** Security) configuration for Fossil. TLS (formerly SSL) is the
856857
** encryption technology used for secure HTTPS transport.
857858
**
858859
** Sub-commands:
859860
**
860
-** show Show the TLS configuration
861
+** clear-cert Remove information about server certificates.
862
+** This is a subset of the "scrub" command.
863
+**
864
+** load-cert PEM-FILES... Identify server certificate files. These
865
+** should be in the PEM format. There are
866
+** normally two files, the certificate and the
867
+** private-key. By default, the text of both
868
+** files is concatenated and added to the
869
+** "ssl-cert" setting. Use --filename to store
870
+** just the filenames.
871
+**
872
+** remove-exception DOMAINS Remove TLS cert exceptions for the domains
873
+** listed. Or remove them all if the --all
874
+** option is specified.
875
+**
876
+** scrub ?--force? Remove all SSL configuration data from the
877
+** repository. Use --force to omit the
878
+** confirmation.
861879
**
862
-** remove-exception DOMAIN... Remove TLS cert exceptions
863
-** for the domains listed. Or if
864
-** the --all option is specified,
865
-** remove all TLS cert exceptions.
880
+** show ?-v? Show the TLS configuration. Add -v to see
881
+** additional explaination
866882
*/
867883
void test_tlsconfig_info(void){
868884
#if !defined(FOSSIL_ENABLE_SSL)
869885
fossil_print("TLS disabled in this build\n");
870886
#else
@@ -871,20 +887,159 @@
871887
const char *zCmd;
872888
size_t nCmd;
873889
int nHit = 0;
874890
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
875891
db_open_config(1,0);
876
- zCmd = g.argc>=3 ? g.argv[2] : "show";
877
- nCmd = strlen(zCmd);
892
+ if( g.argc==2 || (g.argc>=3 && g.argv[2][0]=='-') ){
893
+ zCmd = "show";
894
+ nCmd = 4;
895
+ }else{
896
+ zCmd = g.argv[2];
897
+ nCmd = strlen(zCmd);
898
+ }
899
+ if( strncmp("clear-cert",zCmd,nCmd)==0 && nCmd>=4 ){
900
+ int bForce = find_option("force","f",0)!=0;
901
+ verify_all_options();
902
+ if( !bForce ){
903
+ Blob ans;
904
+ char cReply;
905
+ prompt_user(
906
+ "Confirm removing of the SSL server certificate from this repository.\n"
907
+ "The removal cannot be undone. Continue (y/N)? ", &ans);
908
+ cReply = blob_str(&ans)[0];
909
+ if( cReply!='y' && cReply!='Y' ){
910
+ fossil_exit(1);
911
+ }
912
+ }
913
+ db_unprotect(PROTECT_ALL);
914
+ db_multi_exec(
915
+ "PRAGMA secure_delete=ON;"
916
+ "DELETE FROM config "
917
+ " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
918
+ );
919
+ db_protect_pop();
920
+ }else
921
+ if( strncmp("load-cert",zCmd,nCmd)==0 && nCmd>=4 ){
922
+ int bFN = find_option("filename",0,0)!=0;
923
+ int i;
924
+ Blob allText = BLOB_INITIALIZER;
925
+ int haveCert = 0;
926
+ int haveKey = 0;
927
+ verify_all_options();
928
+ db_begin_transaction();
929
+ db_unprotect(PROTECT_ALL);
930
+ db_multi_exec(
931
+ "PRAGMA secure_delete=ON;"
932
+ "DELETE FROM config "
933
+ " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
934
+ );
935
+ nHit = 0;
936
+ for(i=3; i<g.argc; i++){
937
+ Blob x;
938
+ int isCert;
939
+ int isKey;
940
+ if( !file_isfile(g.argv[i], ExtFILE) ){
941
+ fossil_fatal("no such file: \"%s\"", g.argv[i]);
942
+ }
943
+ blob_read_from_file(&x, g.argv[i], ExtFILE);
944
+ isCert = strstr(blob_str(&x),"-----BEGIN CERTIFICATE-----")!=0;
945
+ isKey = strstr(blob_str(&x),"-----BEGIN PRIVATE KEY-----")!=0;
946
+ if( !isCert && !isKey ){
947
+ fossil_fatal("not a certificate or a private key: \"%s\"", g.argv[i]);
948
+ }
949
+ if( isCert ){
950
+ if( haveCert ){
951
+ fossil_fatal("more than one certificate provided");
952
+ }
953
+ haveCert = 1;
954
+ if( bFN ){
955
+ db_set("ssl-cert-file", file_canonical_name_dup(g.argv[i]), 0);
956
+ }else{
957
+ blob_append(&allText, blob_buffer(&x), blob_size(&x));
958
+ }
959
+ if( isKey && !haveKey ){
960
+ haveKey = 1;
961
+ isKey = 0;
962
+ }
963
+ }
964
+ if( isKey ){
965
+ if( haveKey ){
966
+ fossil_fatal("more than one private key provided");
967
+ }
968
+ haveKey = 1;
969
+ if( bFN ){
970
+ db_set("ssl-key-file", file_canonical_name_dup(g.argv[i]), 0);
971
+ }else{
972
+ blob_append(&allText, blob_buffer(&x), blob_size(&x));
973
+ }
974
+ }
975
+ }
976
+ db_protect_pop();
977
+ if( !haveCert ){
978
+ if( !haveKey ){
979
+ fossil_fatal("missing certificate and private-key");
980
+ }else{
981
+ fossil_fatal("missing certificate");
982
+ }
983
+ }else if( !haveKey ){
984
+ fossil_fatal("missing private-key");
985
+ }
986
+ if( !bFN ){
987
+ db_set("ssl-cert", blob_str(&allText), 0);
988
+ }
989
+ db_commit_transaction();
990
+ }else
991
+ if( strncmp("scrub",zCmd,nCmd)==0 && nCmd>4 ){
992
+ int bForce = find_option("force","f",0)!=0;
993
+ verify_all_options();
994
+ if( !bForce ){
995
+ Blob ans;
996
+ char cReply;
997
+ prompt_user(
998
+ "Scrubbing the SSL configuration will permanently delete information.\n"
999
+ "Changes cannot be undone. Continue (y/N)? ", &ans);
1000
+ cReply = blob_str(&ans)[0];
1001
+ if( cReply!='y' && cReply!='Y' ){
1002
+ fossil_exit(1);
1003
+ }
1004
+ }
1005
+ db_unprotect(PROTECT_ALL);
1006
+ db_multi_exec(
1007
+ "PRAGMA secure_delete=ON;"
1008
+ "DELETE FROM config WHERE name GLOB 'ssl-*';"
1009
+ );
1010
+ db_protect_pop();
1011
+ }else
8781012
if( strncmp("show",zCmd,nCmd)==0 ){
8791013
const char *zName, *zValue;
8801014
size_t nName;
8811015
Stmt q;
1016
+ int verbose = find_option("verbose","v",0)!=0;
1017
+ verify_all_options();
1018
+
8821019
fossil_print("OpenSSL-version: %s (0x%09x)\n",
8831020
SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
1021
+ if( verbose ){
1022
+ fossil_print("\n"
1023
+ " The version of the OpenSSL library being used\n"
1024
+ " by this instance of Fossil. Version 3.0.0 or\n"
1025
+ " later is recommended.\n\n"
1026
+ );
1027
+ }
1028
+
8841029
fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
8851030
fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1031
+ if( verbose ){
1032
+ fossil_print("\n"
1033
+ " The default locations for the set of root certificates\n"
1034
+ " used by the \"fossil sync\" and similar commands to verify\n"
1035
+ " the identity of servers for \"https:\" URLs. These values\n"
1036
+ " come into play when Fossil is used as a TLS client. These\n"
1037
+ " values are built into your OpenSSL library.\n\n"
1038
+ );
1039
+ }
1040
+
8861041
zName = X509_get_default_cert_file_env();
8871042
zValue = fossil_getenv(zName);
8881043
if( zValue==0 ) zValue = "";
8891044
nName = strlen(zName);
8901045
fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
@@ -891,25 +1046,85 @@
8911046
zName = X509_get_default_cert_dir_env();
8921047
zValue = fossil_getenv(zName);
8931048
if( zValue==0 ) zValue = "";
8941049
nName = strlen(zName);
8951050
fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
896
- nHit++;
1051
+ if( verbose ){
1052
+ fossil_print("\n"
1053
+ " Alternative locations for the root certificates used by Fossil\n"
1054
+ " when it is acting as a SSL client in order to verify the identity\n"
1055
+ " of servers. If specified, these alternative locations override\n"
1056
+ " the built-in locations.\n\n"
1057
+ );
1058
+ }
1059
+
8971060
fossil_print("ssl-ca-location: %s\n", db_get("ssl-ca-location",""));
1061
+ if( verbose ){
1062
+ fossil_print("\n"
1063
+ " This setting is the name of a file or directory that contains\n"
1064
+ " the complete set of root certificates to used by Fossil when it\n"
1065
+ " is acting as a SSL client. If defined, this setting takes\n"
1066
+ " priority over built-in paths and environment variables\n\n"
1067
+ );
1068
+ }
1069
+
8981070
fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1071
+ if( verbose ){
1072
+ fossil_print("\n"
1073
+ " This setting is the name of a file that contains the PEM-format\n"
1074
+ " certificate and private-key used by Fossil clients to authentice\n"
1075
+ " with servers. Few servers actually require this, so this setting\n"
1076
+ " is usually blank.\n\n"
1077
+ );
1078
+ }
1079
+
1080
+ zValue = db_get("ssl-cert",0);
1081
+ if( zValue ){
1082
+ fossil_print("ssl-cert: (%d-byte PEM)\n", (int)strlen(zValue));
1083
+ }else{
1084
+ fossil_print("ssl-cert:\n");
1085
+ }
1086
+ if( verbose ){
1087
+ fossil_print("\n"
1088
+ " This setting is the PEM-formatted value of the SSL server\n"
1089
+ " certificate and private-key, used by Fossil when it is acting\n"
1090
+ " as a server via the \"fossil server\" command or similar.\n\n"
1091
+ );
1092
+ }
1093
+
1094
+ fossil_print("ssl-cert-file: %s\n", db_get("ssl-cert-file",""));
1095
+ fossil_print("ssl-key-file: %s\n", db_get("ssl-key-file",""));
1096
+ if( verbose ){
1097
+ fossil_print("\n"
1098
+ " This settings are the names of files that contin the certificate\n"
1099
+ " private-key used by Fossil when it is acting as a server.\n\n"
1100
+ );
1101
+ }
1102
+
8991103
db_prepare(&q,
900
- "SELECT name FROM global_config"
1104
+ "SELECT name, '' FROM global_config"
9011105
" WHERE name GLOB 'cert:*'"
9021106
"UNION ALL "
903
- "SELECT name FROM config"
1107
+ "SELECT name, date(mtime,'unixepoch') FROM config"
9041108
" WHERE name GLOB 'cert:*'"
9051109
" ORDER BY name"
9061110
);
1111
+ nHit = 0;
9071112
while( db_step(&q)==SQLITE_ROW ){
908
- fossil_print("exception: %s\n", db_column_text(&q,0)+5);
1113
+ fossil_print("exception: %-40s %s\n",
1114
+ db_column_text(&q,0)+5, db_column_text(&q,1));
1115
+ nHit++;
9091116
}
9101117
db_finalize(&q);
1118
+ if( nHit && verbose ){
1119
+ fossil_print("\n"
1120
+ " The exceptions are server certificates that the Fossil client\n"
1121
+ " is unable to verify using root certificates, but which should be\n"
1122
+ " accepted anyhow.\n\n"
1123
+ );
1124
+ }
1125
+
9111126
}else
9121127
if( strncmp("remove-exception",zCmd,nCmd)==0 ){
9131128
int i;
9141129
Blob sql;
9151130
char *zSep = "(";
@@ -948,10 +1163,10 @@
9481163
db_commit_transaction();
9491164
blob_reset(&sql);
9501165
}else
9511166
/*default*/{
9521167
fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
953
- " remove-exception show",
1168
+ " load-certs remove-exception scrub show",
9541169
zCmd);
9551170
}
9561171
#endif
9571172
}
9581173
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -697,13 +697,13 @@
697 ** of disk files that hold the certificate and private-key for the
698 ** server. If zCertFile is not NULL but zKeyFile is NULL, then
699 ** zCertFile is assumed to be a concatenation of the certificate and
700 ** the private-key in the PEM format.
701 **
702 ** If zCertFile is NULL, then "tls-server-cert" setting is consulted
703 ** to get the certificate and private-key (concatenated together, in
704 ** the PEM format). If there is no tls-server-cert setting, then
705 ** a built-in self-signed cert is used.
706 */
707 void ssl_init_server(const char *zCertFile, const char *zKeyFile){
708 if( sslIsInit==0 ){
709 const char *zTlsCert;
@@ -724,16 +724,16 @@
724 if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
725 ERR_print_errors_fp(stderr);
726 fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile);
727 }
728 }else
729 if( (zTlsCert = db_get("tls-server-cert",0))!=0 ){
730 if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1)
731 || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1)
732 ){
733 fossil_fatal("Error loading the CERT from the"
734 " 'tls-server-cert' setting");
735 }
736 }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
737 || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){
738 fossil_fatal("Error loading self-signed CERT");
739 }
@@ -846,25 +846,41 @@
846
847 #endif /* FOSSIL_ENABLE_SSL */
848
849 /*
850 ** COMMAND: tls-config*
 
851 **
852 ** Usage: %fossil tls-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
853 **
854 ** This command is used to view or modify the TLS (Transport Layer
855 ** Security) configuration for Fossil. TLS (formerly SSL) is the
856 ** encryption technology used for secure HTTPS transport.
857 **
858 ** Sub-commands:
859 **
860 ** show Show the TLS configuration
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
861 **
862 ** remove-exception DOMAIN... Remove TLS cert exceptions
863 ** for the domains listed. Or if
864 ** the --all option is specified,
865 ** remove all TLS cert exceptions.
866 */
867 void test_tlsconfig_info(void){
868 #if !defined(FOSSIL_ENABLE_SSL)
869 fossil_print("TLS disabled in this build\n");
870 #else
@@ -871,20 +887,159 @@
871 const char *zCmd;
872 size_t nCmd;
873 int nHit = 0;
874 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
875 db_open_config(1,0);
876 zCmd = g.argc>=3 ? g.argv[2] : "show";
877 nCmd = strlen(zCmd);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
878 if( strncmp("show",zCmd,nCmd)==0 ){
879 const char *zName, *zValue;
880 size_t nName;
881 Stmt q;
 
 
 
882 fossil_print("OpenSSL-version: %s (0x%09x)\n",
883 SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
 
 
 
 
 
 
 
 
884 fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
885 fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
 
 
 
 
 
 
 
 
 
 
886 zName = X509_get_default_cert_file_env();
887 zValue = fossil_getenv(zName);
888 if( zValue==0 ) zValue = "";
889 nName = strlen(zName);
890 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
@@ -891,25 +1046,85 @@
891 zName = X509_get_default_cert_dir_env();
892 zValue = fossil_getenv(zName);
893 if( zValue==0 ) zValue = "";
894 nName = strlen(zName);
895 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
896 nHit++;
 
 
 
 
 
 
 
 
897 fossil_print("ssl-ca-location: %s\n", db_get("ssl-ca-location",""));
 
 
 
 
 
 
 
 
 
898 fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
899 db_prepare(&q,
900 "SELECT name FROM global_config"
901 " WHERE name GLOB 'cert:*'"
902 "UNION ALL "
903 "SELECT name FROM config"
904 " WHERE name GLOB 'cert:*'"
905 " ORDER BY name"
906 );
 
907 while( db_step(&q)==SQLITE_ROW ){
908 fossil_print("exception: %s\n", db_column_text(&q,0)+5);
 
 
909 }
910 db_finalize(&q);
 
 
 
 
 
 
 
 
911 }else
912 if( strncmp("remove-exception",zCmd,nCmd)==0 ){
913 int i;
914 Blob sql;
915 char *zSep = "(";
@@ -948,10 +1163,10 @@
948 db_commit_transaction();
949 blob_reset(&sql);
950 }else
951 /*default*/{
952 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
953 " remove-exception show",
954 zCmd);
955 }
956 #endif
957 }
958
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -697,13 +697,13 @@
697 ** of disk files that hold the certificate and private-key for the
698 ** server. If zCertFile is not NULL but zKeyFile is NULL, then
699 ** zCertFile is assumed to be a concatenation of the certificate and
700 ** the private-key in the PEM format.
701 **
702 ** If zCertFile is NULL, then "ssl-cert" setting is consulted
703 ** to get the certificate and private-key (concatenated together, in
704 ** the PEM format). If there is no ssl-cert setting, then
705 ** a built-in self-signed cert is used.
706 */
707 void ssl_init_server(const char *zCertFile, const char *zKeyFile){
708 if( sslIsInit==0 ){
709 const char *zTlsCert;
@@ -724,16 +724,16 @@
724 if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){
725 ERR_print_errors_fp(stderr);
726 fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile);
727 }
728 }else
729 if( (zTlsCert = db_get("ssl-cert",0))!=0 ){
730 if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1)
731 || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1)
732 ){
733 fossil_fatal("Error loading the CERT from the"
734 " 'ssl-cert' setting");
735 }
736 }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1)
737 || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){
738 fossil_fatal("Error loading self-signed CERT");
739 }
@@ -846,25 +846,41 @@
846
847 #endif /* FOSSIL_ENABLE_SSL */
848
849 /*
850 ** COMMAND: tls-config*
851 ** COMMAND: ssl-config
852 **
853 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
854 **
855 ** This command is used to view or modify the TLS (Transport Layer
856 ** Security) configuration for Fossil. TLS (formerly SSL) is the
857 ** encryption technology used for secure HTTPS transport.
858 **
859 ** Sub-commands:
860 **
861 ** clear-cert Remove information about server certificates.
862 ** This is a subset of the "scrub" command.
863 **
864 ** load-cert PEM-FILES... Identify server certificate files. These
865 ** should be in the PEM format. There are
866 ** normally two files, the certificate and the
867 ** private-key. By default, the text of both
868 ** files is concatenated and added to the
869 ** "ssl-cert" setting. Use --filename to store
870 ** just the filenames.
871 **
872 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
873 ** listed. Or remove them all if the --all
874 ** option is specified.
875 **
876 ** scrub ?--force? Remove all SSL configuration data from the
877 ** repository. Use --force to omit the
878 ** confirmation.
879 **
880 ** show ?-v? Show the TLS configuration. Add -v to see
881 ** additional explaination
 
 
882 */
883 void test_tlsconfig_info(void){
884 #if !defined(FOSSIL_ENABLE_SSL)
885 fossil_print("TLS disabled in this build\n");
886 #else
@@ -871,20 +887,159 @@
887 const char *zCmd;
888 size_t nCmd;
889 int nHit = 0;
890 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
891 db_open_config(1,0);
892 if( g.argc==2 || (g.argc>=3 && g.argv[2][0]=='-') ){
893 zCmd = "show";
894 nCmd = 4;
895 }else{
896 zCmd = g.argv[2];
897 nCmd = strlen(zCmd);
898 }
899 if( strncmp("clear-cert",zCmd,nCmd)==0 && nCmd>=4 ){
900 int bForce = find_option("force","f",0)!=0;
901 verify_all_options();
902 if( !bForce ){
903 Blob ans;
904 char cReply;
905 prompt_user(
906 "Confirm removing of the SSL server certificate from this repository.\n"
907 "The removal cannot be undone. Continue (y/N)? ", &ans);
908 cReply = blob_str(&ans)[0];
909 if( cReply!='y' && cReply!='Y' ){
910 fossil_exit(1);
911 }
912 }
913 db_unprotect(PROTECT_ALL);
914 db_multi_exec(
915 "PRAGMA secure_delete=ON;"
916 "DELETE FROM config "
917 " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
918 );
919 db_protect_pop();
920 }else
921 if( strncmp("load-cert",zCmd,nCmd)==0 && nCmd>=4 ){
922 int bFN = find_option("filename",0,0)!=0;
923 int i;
924 Blob allText = BLOB_INITIALIZER;
925 int haveCert = 0;
926 int haveKey = 0;
927 verify_all_options();
928 db_begin_transaction();
929 db_unprotect(PROTECT_ALL);
930 db_multi_exec(
931 "PRAGMA secure_delete=ON;"
932 "DELETE FROM config "
933 " WHERE name IN ('ssl-cert','ssl-cert-file','ssl-cert-key');"
934 );
935 nHit = 0;
936 for(i=3; i<g.argc; i++){
937 Blob x;
938 int isCert;
939 int isKey;
940 if( !file_isfile(g.argv[i], ExtFILE) ){
941 fossil_fatal("no such file: \"%s\"", g.argv[i]);
942 }
943 blob_read_from_file(&x, g.argv[i], ExtFILE);
944 isCert = strstr(blob_str(&x),"-----BEGIN CERTIFICATE-----")!=0;
945 isKey = strstr(blob_str(&x),"-----BEGIN PRIVATE KEY-----")!=0;
946 if( !isCert && !isKey ){
947 fossil_fatal("not a certificate or a private key: \"%s\"", g.argv[i]);
948 }
949 if( isCert ){
950 if( haveCert ){
951 fossil_fatal("more than one certificate provided");
952 }
953 haveCert = 1;
954 if( bFN ){
955 db_set("ssl-cert-file", file_canonical_name_dup(g.argv[i]), 0);
956 }else{
957 blob_append(&allText, blob_buffer(&x), blob_size(&x));
958 }
959 if( isKey && !haveKey ){
960 haveKey = 1;
961 isKey = 0;
962 }
963 }
964 if( isKey ){
965 if( haveKey ){
966 fossil_fatal("more than one private key provided");
967 }
968 haveKey = 1;
969 if( bFN ){
970 db_set("ssl-key-file", file_canonical_name_dup(g.argv[i]), 0);
971 }else{
972 blob_append(&allText, blob_buffer(&x), blob_size(&x));
973 }
974 }
975 }
976 db_protect_pop();
977 if( !haveCert ){
978 if( !haveKey ){
979 fossil_fatal("missing certificate and private-key");
980 }else{
981 fossil_fatal("missing certificate");
982 }
983 }else if( !haveKey ){
984 fossil_fatal("missing private-key");
985 }
986 if( !bFN ){
987 db_set("ssl-cert", blob_str(&allText), 0);
988 }
989 db_commit_transaction();
990 }else
991 if( strncmp("scrub",zCmd,nCmd)==0 && nCmd>4 ){
992 int bForce = find_option("force","f",0)!=0;
993 verify_all_options();
994 if( !bForce ){
995 Blob ans;
996 char cReply;
997 prompt_user(
998 "Scrubbing the SSL configuration will permanently delete information.\n"
999 "Changes cannot be undone. Continue (y/N)? ", &ans);
1000 cReply = blob_str(&ans)[0];
1001 if( cReply!='y' && cReply!='Y' ){
1002 fossil_exit(1);
1003 }
1004 }
1005 db_unprotect(PROTECT_ALL);
1006 db_multi_exec(
1007 "PRAGMA secure_delete=ON;"
1008 "DELETE FROM config WHERE name GLOB 'ssl-*';"
1009 );
1010 db_protect_pop();
1011 }else
1012 if( strncmp("show",zCmd,nCmd)==0 ){
1013 const char *zName, *zValue;
1014 size_t nName;
1015 Stmt q;
1016 int verbose = find_option("verbose","v",0)!=0;
1017 verify_all_options();
1018
1019 fossil_print("OpenSSL-version: %s (0x%09x)\n",
1020 SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
1021 if( verbose ){
1022 fossil_print("\n"
1023 " The version of the OpenSSL library being used\n"
1024 " by this instance of Fossil. Version 3.0.0 or\n"
1025 " later is recommended.\n\n"
1026 );
1027 }
1028
1029 fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
1030 fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
1031 if( verbose ){
1032 fossil_print("\n"
1033 " The default locations for the set of root certificates\n"
1034 " used by the \"fossil sync\" and similar commands to verify\n"
1035 " the identity of servers for \"https:\" URLs. These values\n"
1036 " come into play when Fossil is used as a TLS client. These\n"
1037 " values are built into your OpenSSL library.\n\n"
1038 );
1039 }
1040
1041 zName = X509_get_default_cert_file_env();
1042 zValue = fossil_getenv(zName);
1043 if( zValue==0 ) zValue = "";
1044 nName = strlen(zName);
1045 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
@@ -891,25 +1046,85 @@
1046 zName = X509_get_default_cert_dir_env();
1047 zValue = fossil_getenv(zName);
1048 if( zValue==0 ) zValue = "";
1049 nName = strlen(zName);
1050 fossil_print("%s:%*s%s\n", zName, 18-nName, "", zValue);
1051 if( verbose ){
1052 fossil_print("\n"
1053 " Alternative locations for the root certificates used by Fossil\n"
1054 " when it is acting as a SSL client in order to verify the identity\n"
1055 " of servers. If specified, these alternative locations override\n"
1056 " the built-in locations.\n\n"
1057 );
1058 }
1059
1060 fossil_print("ssl-ca-location: %s\n", db_get("ssl-ca-location",""));
1061 if( verbose ){
1062 fossil_print("\n"
1063 " This setting is the name of a file or directory that contains\n"
1064 " the complete set of root certificates to used by Fossil when it\n"
1065 " is acting as a SSL client. If defined, this setting takes\n"
1066 " priority over built-in paths and environment variables\n\n"
1067 );
1068 }
1069
1070 fossil_print("ssl-identity: %s\n", db_get("ssl-identity",""));
1071 if( verbose ){
1072 fossil_print("\n"
1073 " This setting is the name of a file that contains the PEM-format\n"
1074 " certificate and private-key used by Fossil clients to authentice\n"
1075 " with servers. Few servers actually require this, so this setting\n"
1076 " is usually blank.\n\n"
1077 );
1078 }
1079
1080 zValue = db_get("ssl-cert",0);
1081 if( zValue ){
1082 fossil_print("ssl-cert: (%d-byte PEM)\n", (int)strlen(zValue));
1083 }else{
1084 fossil_print("ssl-cert:\n");
1085 }
1086 if( verbose ){
1087 fossil_print("\n"
1088 " This setting is the PEM-formatted value of the SSL server\n"
1089 " certificate and private-key, used by Fossil when it is acting\n"
1090 " as a server via the \"fossil server\" command or similar.\n\n"
1091 );
1092 }
1093
1094 fossil_print("ssl-cert-file: %s\n", db_get("ssl-cert-file",""));
1095 fossil_print("ssl-key-file: %s\n", db_get("ssl-key-file",""));
1096 if( verbose ){
1097 fossil_print("\n"
1098 " This settings are the names of files that contin the certificate\n"
1099 " private-key used by Fossil when it is acting as a server.\n\n"
1100 );
1101 }
1102
1103 db_prepare(&q,
1104 "SELECT name, '' FROM global_config"
1105 " WHERE name GLOB 'cert:*'"
1106 "UNION ALL "
1107 "SELECT name, date(mtime,'unixepoch') FROM config"
1108 " WHERE name GLOB 'cert:*'"
1109 " ORDER BY name"
1110 );
1111 nHit = 0;
1112 while( db_step(&q)==SQLITE_ROW ){
1113 fossil_print("exception: %-40s %s\n",
1114 db_column_text(&q,0)+5, db_column_text(&q,1));
1115 nHit++;
1116 }
1117 db_finalize(&q);
1118 if( nHit && verbose ){
1119 fossil_print("\n"
1120 " The exceptions are server certificates that the Fossil client\n"
1121 " is unable to verify using root certificates, but which should be\n"
1122 " accepted anyhow.\n\n"
1123 );
1124 }
1125
1126 }else
1127 if( strncmp("remove-exception",zCmd,nCmd)==0 ){
1128 int i;
1129 Blob sql;
1130 char *zSep = "(";
@@ -948,10 +1163,10 @@
1163 db_commit_transaction();
1164 blob_reset(&sql);
1165 }else
1166 /*default*/{
1167 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
1168 " load-certs remove-exception scrub show",
1169 zCmd);
1170 }
1171 #endif
1172 }
1173
+3 -1
--- src/rebuild.c
+++ src/rebuild.c
@@ -916,10 +916,11 @@
916916
delete_private_content();
917917
}
918918
if( !privateOnly ){
919919
db_unprotect(PROTECT_ALL);
920920
db_multi_exec(
921
+ "PRAGMA secure_delete=ON;"
921922
"UPDATE user SET pw='';"
922923
"DELETE FROM config WHERE name IN"
923924
"(WITH pattern(x) AS (VALUES"
924925
" ('baseurl:*'),"
925926
" ('cert:*'),"
@@ -933,11 +934,12 @@
933934
" ('peer-*'),"
934935
" ('skin:*'),"
935936
" ('subrepo:*'),"
936937
" ('sync-*'),"
937938
" ('syncfrom:*'),"
938
- " ('syncwith:*')"
939
+ " ('syncwith:*'),"
940
+ " ('ssl-*')"
939941
") SELECT name FROM config, pattern WHERE name GLOB x);"
940942
);
941943
if( bVerily ){
942944
db_multi_exec(
943945
"DELETE FROM concealed;\n"
944946
--- src/rebuild.c
+++ src/rebuild.c
@@ -916,10 +916,11 @@
916 delete_private_content();
917 }
918 if( !privateOnly ){
919 db_unprotect(PROTECT_ALL);
920 db_multi_exec(
 
921 "UPDATE user SET pw='';"
922 "DELETE FROM config WHERE name IN"
923 "(WITH pattern(x) AS (VALUES"
924 " ('baseurl:*'),"
925 " ('cert:*'),"
@@ -933,11 +934,12 @@
933 " ('peer-*'),"
934 " ('skin:*'),"
935 " ('subrepo:*'),"
936 " ('sync-*'),"
937 " ('syncfrom:*'),"
938 " ('syncwith:*')"
 
939 ") SELECT name FROM config, pattern WHERE name GLOB x);"
940 );
941 if( bVerily ){
942 db_multi_exec(
943 "DELETE FROM concealed;\n"
944
--- src/rebuild.c
+++ src/rebuild.c
@@ -916,10 +916,11 @@
916 delete_private_content();
917 }
918 if( !privateOnly ){
919 db_unprotect(PROTECT_ALL);
920 db_multi_exec(
921 "PRAGMA secure_delete=ON;"
922 "UPDATE user SET pw='';"
923 "DELETE FROM config WHERE name IN"
924 "(WITH pattern(x) AS (VALUES"
925 " ('baseurl:*'),"
926 " ('cert:*'),"
@@ -933,11 +934,12 @@
934 " ('peer-*'),"
935 " ('skin:*'),"
936 " ('subrepo:*'),"
937 " ('sync-*'),"
938 " ('syncfrom:*'),"
939 " ('syncwith:*'),"
940 " ('ssl-*')"
941 ") SELECT name FROM config, pattern WHERE name GLOB x);"
942 );
943 if( bVerily ){
944 db_multi_exec(
945 "DELETE FROM concealed;\n"
946

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button