Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Show the parent-project-* CONFIG entries (if they exist) with the "fossil remote config-data" command. When parsing a URL, if the URL comes from the CONFIG table, remember the CONFIG table entry that supplied the password. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
6d0083adce5597e106f50369522311d9 |
| User & Date: | drh 2022-12-30 16:32:24.666 |
Context
|
2022-12-30
| ||
| 20:54 | Security enhancement: Do not store the passwords for remote URLs directly, but instead store the sha1_shared_secret() encoding of those passwords. It is the SHA1 encoding that gets transmitted to the server anyhow, so we might as well just store that. The SHA1 encoding cannot be used to log in. The password is still protected using obscure() ev... check-in: 41ba6ea7db user: drh tags: trunk | |
| 16:32 | Show the parent-project-* CONFIG entries (if they exist) with the "fossil remote config-data" command. When parsing a URL, if the URL comes from the CONFIG table, remember the CONFIG table entry that supplied the password. check-in: 6d0083adce user: drh tags: trunk | |
| 12:26 | Fix minor typos in the diff source code. check-in: 4e169542ae user: drh tags: trunk | |
Changes
Changes to src/sync.c.
| ︙ | ︙ | |||
767 768 769 770 771 772 773 |
** Show the CONFIG table entries that relate to remembering remote URLs
*/
Stmt q;
int n;
n = db_int(13,
"SELECT max(length(name))"
" FROM config"
| | > > | | > > | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
** Show the CONFIG table entries that relate to remembering remote URLs
*/
Stmt q;
int n;
n = db_int(13,
"SELECT max(length(name))"
" FROM config"
" WHERE name GLOB 'sync-*:*'"
" OR name GLOB 'last-sync-*'"
" OR name GLOB 'parent-project-*'"
);
db_prepare(&q,
"SELECT name,"
" CASE WHEN name LIKE '%%sync-pw%%' OR name='parent-project-pw'"
" THEN printf('%%.*c',length(value),'*') ELSE value END"
" FROM config"
" WHERE name GLOB 'sync-*:*'"
" OR name GLOB 'last-sync-*'"
" OR name GLOB 'parent-project-*'"
" ORDER BY name LIKE '%%sync-pw%%' OR name='parent-project-pw', name"
);
while( db_step(&q)==SQLITE_ROW ){
fossil_print("%-*s %s\n",
n, db_column_text(&q,0),
db_column_text(&q,1)
);
}
|
| ︙ | ︙ |
Changes to src/url.c.
| ︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 | int dfltPort; /* The default port for the given protocol */ char *path; /* Pathname for http: */ char *user; /* User id for http: */ char *passwd; /* Password for http: */ char *canonical; /* Canonical representation of the URL */ char *proxyAuth; /* Proxy-Authorizer: string */ char *fossil; /* The fossil query parameter on ssh: */ unsigned flags; /* Boolean flags controlling URL processing */ int useProxy; /* Used to remember that a proxy is in use */ | > > | < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | int dfltPort; /* The default port for the given protocol */ char *path; /* Pathname for http: */ char *user; /* User id for http: */ char *passwd; /* Password for http: */ char *canonical; /* Canonical representation of the URL */ char *proxyAuth; /* Proxy-Authorizer: string */ char *fossil; /* The fossil query parameter on ssh: */ char *pwConfig; /* CONFIG table entry that gave us the password */ unsigned flags; /* Boolean flags controlling URL processing */ int useProxy; /* Used to remember that a proxy is in use */ int proxyOrigPort; /* Tunneled port number for https through proxy */ char *proxyUrlPath; /* Remember path when proxy is use */ char *proxyUrlCanonical; /* Remember canonical path when proxy is use */ }; #endif /* INTERFACE */ /* ** Parse the URL in the zUrl argument. Store results in the pUrlData object. ** Populate members of pUrlData as follows: |
| ︙ | ︙ | |||
85 86 87 88 89 90 91 | ** dfltPort Default TCP port number (80 or 443). ** path Path name for HTTP or HTTPS. ** user Userid. ** passwd Password. ** hostname HOST:PORT or just HOST if port is the default. ** canonical The URL in canonical form, omitting the password ** | | | | > > < > > | 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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
** dfltPort Default TCP port number (80 or 443).
** path Path name for HTTP or HTTPS.
** user Userid.
** passwd Password.
** hostname HOST:PORT or just HOST if port is the default.
** canonical The URL in canonical form, omitting the password
**
** If URL_USECONFIG is set and zUrl is NULL or "default", then parse the
** URL stored in last-sync-url and last-sync-pw of the CONFIG table. Or if
** URL_USE_PARENT is also set, then use parent-project-url and
** parent-project-pw from the CONFIG table instead of last-sync-url
** and last-sync-pw.
**
** If URL_USE_CONFIG is set and zUrl is a symbolic name, then look up
** the URL in sync-url:%Q and sync-pw:%Q elements of the CONFIG table where
** %Q is the symbolic name.
**
** This routine differs from url_parse() in that this routine stores the
** results in pUrlData and does not change the values of global variables.
** The url_parse() routine puts its result in g.url.
*/
void url_parse_local(
const char *zUrl,
unsigned int urlFlags,
UrlData *pUrlData
){
int i, j, c;
char *zFile = 0;
pUrlData->pwConfig = 0;
if( urlFlags & URL_USE_CONFIG ){
if( zUrl==0 || strcmp(zUrl,"default")==0 ){
const char *zPwConfig = "last-sync-pw";
if( urlFlags & URL_USE_PARENT ){
zUrl = db_get("parent-project-url", 0);
if( zUrl==0 ){
zUrl = db_get("last-sync-url",0);
}else{
zPwConfig = "parent-project-pw";
}
}else{
zUrl = db_get("last-sync-url", 0);
}
if( zUrl==0 ) return;
if( pUrlData->passwd==0 ){
pUrlData->passwd = unobscure(db_get(zPwConfig, 0));
pUrlData->pwConfig = fossil_strdup(zPwConfig);
}
pUrlData->isAlias = 1;
}else{
char *zKey = sqlite3_mprintf("sync-url:%q", zUrl);
char *zAlt = db_get(zKey, 0);
if( zAlt ){
pUrlData->pwConfig = mprintf("sync-pw:%q", zUrl);
pUrlData->passwd = unobscure(
db_text(0, "SELECT value FROM config WHERE name='sync-pw:%q'",zUrl)
);
zUrl = zAlt;
urlFlags |= URL_REMEMBER_PW;
pUrlData->isAlias = 1;
}else{
pUrlData->isAlias = 0;
}
sqlite3_free(zKey);
}
}else{
if( zUrl==0 ) return;
}
if( strncmp(zUrl, "http://", 7)==0
|| strncmp(zUrl, "https://", 8)==0
|
| ︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 | } fossil_free(p->canonical); fossil_free(p->name); fossil_free(p->path); fossil_free(p->user); fossil_free(p->passwd); fossil_free(p->fossil); memset(p, 0, sizeof(*p)); } /* ** Parse the given URL, which describes a sync server. Populate variables ** in the global "g.url" structure as shown below. If zUrl is NULL, then ** parse the URL given in the last-sync-url setting, taking the password | > | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | } fossil_free(p->canonical); fossil_free(p->name); fossil_free(p->path); fossil_free(p->user); fossil_free(p->passwd); fossil_free(p->fossil); fossil_free(p->pwConfig); memset(p, 0, sizeof(*p)); } /* ** Parse the given URL, which describes a sync server. Populate variables ** in the global "g.url" structure as shown below. If zUrl is NULL, then ** parse the URL given in the last-sync-url setting, taking the password |
| ︙ | ︙ | |||
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
** g.url.port TCP port number for HTTP or HTTPS.
** g.url.dfltPort Default TCP port number (80 or 443).
** g.url.path Path name for HTTP or HTTPS.
** g.url.user Userid.
** g.url.passwd Password.
** g.url.hostname HOST:PORT or just HOST if port is the default.
** g.url.canonical The URL in canonical form, omitting the password
**
** HTTP url format as follows (HTTPS is the same with a different scheme):
**
** http://userid:password@host:port/path
**
** SSH url format is:
**
** ssh://userid@host:port/path?fossil=path/to/fossil.exe
**
*/
void url_parse(const char *zUrl, unsigned int urlFlags){
url_parse_local(zUrl, urlFlags, &g.url);
}
/*
** COMMAND: test-urlparser
**
** Usage: %fossil test-urlparser URL ?options?
**
** --remember Store results in last-sync-url
| > > > > > > > > > > > > > | > > | < < < | > > > > > | > > > > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
** g.url.port TCP port number for HTTP or HTTPS.
** g.url.dfltPort Default TCP port number (80 or 443).
** g.url.path Path name for HTTP or HTTPS.
** g.url.user Userid.
** g.url.passwd Password.
** g.url.hostname HOST:PORT or just HOST if port is the default.
** g.url.canonical The URL in canonical form, omitting the password
** g.url.pwConfig Name of CONFIG table entry containing the password
**
** HTTP url format as follows (HTTPS is the same with a different scheme):
**
** http://userid:password@host:port/path
**
** SSH url format is:
**
** ssh://userid@host:port/path?fossil=path/to/fossil.exe
**
** If URL_USE_CONFIG is set then the URL and password might be pulled from
** the CONFIG table rather than from the zUrl parameter. If zUrl is NULL
** or "default" then the URL is given by the "last-sync-url" setting and
** the password comes form the "last-sync-pw" setting. If zUrl is a symbolic
** name, then the URL comes from "sync-url:NAME" and the password from
** "sync-pw:NAME" where NAME is the input zUrl string. Whenever the
** password is taken from the CONFIG table, the g.url.pwConfig field is
** set to the CONFIG.NAME value from which that password is taken. Otherwise,
** g.url.pwConfig is NULL.
*/
void url_parse(const char *zUrl, unsigned int urlFlags){
url_parse_local(zUrl, urlFlags, &g.url);
}
/*
** COMMAND: test-urlparser
**
** Usage: %fossil test-urlparser URL ?options?
**
** --prompt-pw Prompt for password if missing
** --remember Store results in last-sync-url
** --show-pw Show the CONFIG-derived password in the output
** --use-config Pull URL and password from the CONFIG table
** --use-parent Use the parent project URL
*/
void cmd_test_urlparser(void){
int i;
unsigned fg = 0;
int showPw = 0;
db_must_be_within_tree();
url_proxy_options();
if( find_option("remember",0,0) ) fg |= URL_REMEMBER;
if( find_option("prompt-pw",0,0) ) fg |= URL_PROMPT_PW;
if( find_option("use-parent",0,0) ) fg |= URL_USE_PARENT|URL_USE_CONFIG;
if( find_option("use-config",0,0) ) fg |= URL_USE_CONFIG;
if( find_option("show-pw",0,0) ) showPw = 1;
if( (fg & URL_USE_CONFIG)==0 ) showPw = 1;
if( g.argc!=3 && g.argc!=4 ){
usage("URL");
}
url_parse(g.argv[2], fg);
for(i=0; i<2; i++){
fossil_print("g.url.isFile = %d\n", g.url.isFile);
fossil_print("g.url.isHttps = %d\n", g.url.isHttps);
fossil_print("g.url.isSsh = %d\n", g.url.isSsh);
fossil_print("g.url.protocol = %s\n", g.url.protocol);
fossil_print("g.url.name = %s\n", g.url.name);
fossil_print("g.url.port = %d\n", g.url.port);
fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort);
fossil_print("g.url.hostname = %s\n", g.url.hostname);
fossil_print("g.url.path = %s\n", g.url.path);
fossil_print("g.url.user = %s\n", g.url.user);
if( showPw || g.url.pwConfig==0 ){
fossil_print("g.url.passwd = %s\n", g.url.passwd);
}else{
fossil_print("g.url.passwd = ************\n");
}
fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
fossil_print("g.url.canonical = %s\n", g.url.canonical);
fossil_print("g.url.fossil = %s\n", g.url.fossil);
fossil_print("g.url.flags = 0x%02x\n", g.url.flags);
fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
if( g.url.isFile || g.url.isSsh ) break;
if( i==0 ){
fossil_print("********\n");
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
812 813 814 815 816 817 818 | ** If anything fails to check out, no changes are made to privileges. ** ** Signature generation on the client side is handled by the ** http_exchange() routine. ** ** Return non-zero for a login failure and zero for success. */ | | | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
** If anything fails to check out, no changes are made to privileges.
**
** Signature generation on the client side is handled by the
** http_exchange() routine.
**
** Return non-zero for a login failure and zero for success.
*/
static int check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){
Stmt q;
int rc = -1;
char *zLogin = blob_terminate(pLogin);
defossilize(zLogin);
if( fossil_strcmp(zLogin, "nobody")==0
|| fossil_strcmp(zLogin,"anonymous")==0
|
| ︙ | ︙ |