Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch ben-security Excluding Merge-Ins
This is equivalent to a diff from 1343cfad7b to 0bed863b69
2011-06-02
| ||
19:31 | Merge SSL client certificate support from ben-security branch check-in: 397f434a4d user: ben tags: ben-testing | |
2011-05-29
| ||
12:53 | Remove accidentally included line of code. Closed-Leaf check-in: 0bed863b69 user: ben tags: ben-security | |
12:49 | Support for client side SSL certificates for extra authentication to https servers. Adds --ssl-identity command line option and ssl-identity setting to specify the filename of a identity file containing a PEM encoded certificate and private key. check-in: e06ea26e97 user: ben tags: ben-security | |
2011-05-23
| ||
15:06 | Merge the solaris10 branch into the trunk. check-in: 3e0efc3827 user: drh tags: trunk | |
2011-05-22
| ||
14:23 | Create new branch named "ben-security" check-in: 2b4a6a66e1 user: ben tags: ben-security | |
09:11 | Create new branch named "versionable-settings" check-in: 3db75c4803 user: ben tags: versionable-settings | |
07:33 | Create new branch named "solaris10" check-in: eb4b5e3beb user: ben tags: solaris10 | |
2011-05-21
| ||
16:57 | If at the tip of the current branch but there are children in other branches, the "fossil up" command should do nothing. check-in: 1343cfad7b user: drh tags: trunk | |
16:45 | Print an "Internal Error" if the update command is unable to find a version to update to. check-in: 88e9f24aff user: drh tags: trunk | |
Changes to src/cgi.c.
189 189 */ 190 190 void cgi_set_cookie( 191 191 const char *zName, /* Name of the cookie */ 192 192 const char *zValue, /* Value of the cookie. Automatically escaped */ 193 193 const char *zPath, /* Path cookie applies to. NULL means "/" */ 194 194 int lifetime /* Expiration of the cookie in seconds from now */ 195 195 ){ 196 + char *zSecure = ""; 196 197 if( zPath==0 ) zPath = g.zTop; 198 + if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){ 199 + zSecure = " secure;"; 200 + } 197 201 if( lifetime>0 ){ 198 202 lifetime += (int)time(0); 199 203 blob_appendf(&extraHeader, 200 - "Set-Cookie: %s=%t; Path=%s; expires=%z; Version=1\r\n", 201 - zName, zValue, zPath, cgi_rfc822_datestamp(lifetime)); 204 + "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n", 205 + zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure); 202 206 }else{ 203 207 blob_appendf(&extraHeader, 204 - "Set-Cookie: %s=%t; Path=%s; Version=1\r\n", 205 - zName, zValue, zPath); 208 + "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n", 209 + zName, zValue, zPath, zSecure); 206 210 } 207 211 } 208 212 209 213 #if 0 210 214 /* 211 215 ** Add an ETag header line 212 216 */ ................................................................................ 287 291 }else{ 288 292 fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus); 289 293 } 290 294 291 295 if( blob_size(&extraHeader)>0 ){ 292 296 fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); 293 297 } 298 + 299 + /* Add headers to turn on useful security options in browsers. */ 300 + fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); 301 + /* This stops fossil pages appearing in frames or iframes, preventing 302 + ** click-jacking attacks on supporting browsers. 303 + ** 304 + ** Other good headers would be 305 + ** Strict-Transport-Security: max-age=62208000 306 + ** if we're using https. However, this would break sites which serve different 307 + ** content on http and https protocols. Also, 308 + ** X-Content-Security-Policy: allow 'self' 309 + ** would help mitigate some XSS and data injection attacks, but will break 310 + ** deliberate inclusion of external resources, such as JavaScript syntax 311 + ** highlighter scripts. 312 + ** 313 + ** These headers are probably best added by the web server hosting fossil as 314 + ** a CGI script. 315 + */ 294 316 295 317 if( g.isConst ){ 296 318 /* constant means that the input URL will _never_ generate anything 297 319 ** else. In the case of attachments, the contents won't change because 298 320 ** an attempt to change them generates a new attachment number. In the 299 321 ** case of most /getfile calls for specific versions, the only way the 300 322 ** content changes is if someone breaks the SCM. And if that happens, a
Changes to src/clone.c.
35 35 ** admin user. This can be overridden using the -A|--admin-user 36 36 ** parameter. 37 37 ** 38 38 ** Options: 39 39 ** 40 40 ** --admin-user|-A USERNAME Make USERNAME the administrator 41 41 ** --private Also clone private branches 42 +** --ssl-identity=filename Use the SSL identity if requested by the server 42 43 ** 43 44 */ 44 45 void clone_cmd(void){ 45 46 char *zPassword; 46 47 const char *zDefaultUser; /* Optional name of the default user */ 47 48 int nErr = 0; 48 49 int bPrivate; /* Also clone private branches */ ................................................................................ 89 90 db_begin_transaction(); 90 91 db_record_repository_filename(g.argv[3]); 91 92 db_initial_setup(0, zDefaultUser, 0); 92 93 user_select(); 93 94 db_set("content-schema", CONTENT_SCHEMA, 0); 94 95 db_set("aux-schema", AUX_SCHEMA, 0); 95 96 db_set("last-sync-url", g.argv[2], 0); 97 + if( g.zSSLIdentity!=0 ){ 98 + /* If the --ssl-identity option was specified, store it as a setting */ 99 + Blob fn; 100 + blob_zero(&fn); 101 + file_canonical_name(g.zSSLIdentity, &fn); 102 + db_set("ssl-identity", blob_str(&fn), 0); 103 + blob_reset(&fn); 104 + } 96 105 db_multi_exec( 97 106 "REPLACE INTO config(name,value,mtime)" 98 107 " VALUES('server-code', lower(hex(randomblob(20))), now());" 99 108 ); 100 109 url_enable_proxy(0); 101 110 url_get_password_if_needed(); 102 111 g.xlinkClusterOnly = 1;
Changes to src/db.c.
1660 1660 { "manifest", 0, 0, "off" }, 1661 1661 { "max-upload", 0, 25, "250000" }, 1662 1662 { "mtime-changes", 0, 0, "on" }, 1663 1663 { "pgp-command", 0, 32, "gpg --clearsign -o " }, 1664 1664 { "proxy", 0, 32, "off" }, 1665 1665 { "repo-cksum", 0, 0, "on" }, 1666 1666 { "self-register", 0, 0, "off" }, 1667 + { "ssl-identity", 0, 40, "" }, 1667 1668 { "ssh-command", 0, 32, "" }, 1668 1669 { "web-browser", 0, 32, "" }, 1669 1670 { 0,0,0,0 } 1670 1671 }; 1671 1672 1672 1673 /* 1673 1674 ** COMMAND: settings ................................................................................ 1769 1770 ** Disable on large repositories for a performance 1770 1771 ** improvement. 1771 1772 ** 1772 1773 ** self-register Allow users to register themselves through the HTTP UI. 1773 1774 ** This is useful if you want to see other names than 1774 1775 ** "Anonymous" in e.g. ticketing system. On the other hand 1775 1776 ** users can not be deleted. Default: off. 1777 +** 1778 +** ssl-identity The full pathname to a file containing a certificate 1779 +** and private key in PEM format. Create by concatenating 1780 +** the certificate and private key files. 1781 +** This identity will be presented to SSL servers to 1782 +** authenticate this client, in addition to the normal 1783 +** password authentication. 1776 1784 ** 1777 1785 ** ssh-command Command used to talk to a remote machine with 1778 1786 ** the "ssh://" protocol. 1779 1787 ** 1780 1788 ** web-browser A shell command used to launch your preferred 1781 1789 ** web browser when given a URL as an argument. 1782 1790 ** Defaults to "start" on windows, "open" on Mac,
Changes to src/http_ssl.c.
76 76 77 77 /* 78 78 ** Return the current SSL error message 79 79 */ 80 80 const char *ssl_errmsg(void){ 81 81 return sslErrMsg; 82 82 } 83 + 84 +/* 85 +** When a server requests a client certificate that hasn't been provided, 86 +** display a warning message explaining what to do next. 87 +*/ 88 +static int ssl_client_cert_callback(SSL *ssl, X509 **x509, EVP_PKEY **pkey){ 89 + fossil_warning("The remote server requested a client certificate for authentication. Specify the pathname to a file containing the PEM encoded certificate and private key with the --ssl-identity option or the ssl-identity setting."); 90 + return 0; /* no cert available */ 91 +} 83 92 84 93 /* 85 94 ** Call this routine once before any other use of the SSL interface. 86 95 ** This routine does initial configuration of the SSL module. 87 96 */ 88 97 void ssl_global_init(void){ 89 98 if( sslIsInit==0 ){ 90 99 SSL_library_init(); 91 100 SSL_load_error_strings(); 92 101 ERR_load_BIO_strings(); 93 102 OpenSSL_add_all_algorithms(); 94 103 sslCtx = SSL_CTX_new(SSLv23_client_method()); 95 104 X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx)); 105 + 106 + /* Load client SSL identity, preferring the filename specified on the command line */ 107 + const char *identityFile = ( g.zSSLIdentity!= 0) ? g.zSSLIdentity : db_get("ssl-identity", 0); 108 + if( identityFile!=0 && identityFile[0]!='\0' ){ 109 + if( SSL_CTX_use_certificate_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!= 1 110 + || SSL_CTX_use_PrivateKey_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!=1 ){ 111 + fossil_fatal("Could not load SSL identity from %s", identityFile); 112 + } 113 + } 114 + /* Register a callback to tell the user what to do when the server asks for a cert */ 115 + SSL_CTX_set_client_cert_cb(sslCtx, ssl_client_cert_callback); 116 + 96 117 sslIsInit = 1; 97 118 } 98 119 } 99 120 100 121 /* 101 122 ** Call this routine to shutdown the SSL module prior to program exit. 102 123 */ ................................................................................ 180 201 } 181 202 182 203 if( SSL_get_verify_result(ssl) != X509_V_OK ){ 183 204 char *desc, *prompt; 184 205 char *warning = ""; 185 206 Blob ans; 186 207 BIO *mem; 208 + unsigned char md[32]; 209 + unsigned int mdLength = 31; 187 210 188 211 mem = BIO_new(BIO_s_mem()); 189 212 X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); 190 213 BIO_puts(mem, "\n\nIssued By:\n\n"); 191 214 X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); 215 + BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n "); 216 + if(X509_digest(cert, EVP_sha1(), md, &mdLength)){ 217 + int j; 218 + for( j = 0; j < mdLength; ++j ) { 219 + BIO_printf(mem, " %02x", md[j]); 220 + } 221 + } 192 222 BIO_write(mem, "", 1); // null-terminate mem buffer 193 223 BIO_get_mem_data(mem, &desc); 194 224 195 225 if( hasSavedCertificate ){ 196 226 warning = "WARNING: Certificate doesn't match the " 197 227 "saved certificate for this host!"; 198 228 }
Changes to src/main.c.
102 102 char *urlPasswd; /* Password for http: */ 103 103 char *urlCanonical; /* Canonical representation of the URL */ 104 104 char *urlProxyAuth; /* Proxy-Authorizer: string */ 105 105 char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ 106 106 int dontKeepUrl; /* Do not persist the URL */ 107 107 108 108 const char *zLogin; /* Login name. "" if not logged in. */ 109 + const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ 109 110 int useLocalauth; /* No login required if from 127.0.0.1 */ 110 111 int noPswd; /* Logged in without password (on 127.0.0.1) */ 111 112 int userUid; /* Integer user id */ 112 113 113 114 /* Information used to populate the RCVFROM table */ 114 115 int rcvid; /* The rcvid. 0 if not yet defined. */ 115 116 char *zIpAddr; /* The remote IP address */ ................................................................................ 247 248 g.fQuiet = find_option("quiet", 0, 0)!=0; 248 249 g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; 249 250 g.fSqlStats = find_option("sqlstats", 0, 0)!=0; 250 251 if( g.fSqlTrace ) g.fSqlStats = 1; 251 252 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; 252 253 g.fHttpTrace = find_option("httptrace", 0, 0)!=0; 253 254 g.zLogin = find_option("user", "U", 1); 255 + g.zSSLIdentity = find_option("ssl-identity", 0, 1); 254 256 if( find_option("help",0,0)!=0 ){ 255 257 /* --help anywhere on the command line is translated into 256 258 ** "fossil help argv[1] argv[2]..." */ 257 259 int i; 258 260 char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) ); 259 261 for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i]; 260 262 zNewArgv[i+1] = 0;