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