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
200
201
202
203
204
205
206
207
208
209
210
211
212
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
|
*/
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,
"Set-Cookie: %s=%t; Path=%s; expires=%z; Version=1\r\n",
zName, zValue, zPath, cgi_rfc822_datestamp(lifetime));
}else{
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; Version=1\r\n",
zName, zValue, zPath);
}
}
#if 0
/*
** Add an ETag header line
*/
................................................................................
}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
|
>
>
>
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
...
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
|
*/ 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 */ ................................................................................ }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
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
** 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 */
................................................................................
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;
|
>
>
>
>
>
>
>
>
>
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
** 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 */ ................................................................................ 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
....
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
|
{ "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
................................................................................
** 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,
|
>
>
>
>
>
>
>
>
|
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
....
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
|
{ "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 ................................................................................ ** 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
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
/*
** 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.
*/
................................................................................
}
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!";
}
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
...
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
|
/* ** 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. */ ................................................................................ } 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
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
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 */
................................................................................
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;
|
>
>
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
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 */ ................................................................................ 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; |