Fossil SCM
Separate SSH transport changes from shared account features to simplify integration.
Commit
915c79cb4f7af92dd20befea7d650b9647b51d42
Parent
ef8b9da03f05103…
11 files changed
+3
-3
+2
-21
-3
+8
-8
+2
-8
+1
+1
-4
+8
-24
+37
-29
-28
+1
-3
+3
-3
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -460,15 +460,15 @@ | ||
| 460 | 460 | */ |
| 461 | 461 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 462 | 462 | int i; |
| 463 | 463 | for(i=0; i<nUsedQP; i++){ |
| 464 | 464 | if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ |
| 465 | - aParamQP[i].zValue = mprintf("%s",zValue); | |
| 465 | + aParamQP[i].zValue = zValue; | |
| 466 | 466 | return; |
| 467 | 467 | } |
| 468 | 468 | } |
| 469 | - cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0); | |
| 469 | + cgi_set_parameter_nocopy(zName, zValue, 0); | |
| 470 | 470 | } |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** Add a query parameter. The zName portion is fixed but a copy |
| 474 | 474 | ** must be made of zValue. |
| @@ -1391,11 +1391,11 @@ | ||
| 1391 | 1391 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1392 | 1392 | if( zToken[i] ) zToken[i++] = 0; |
| 1393 | 1393 | if( nCycles==0 ){ |
| 1394 | 1394 | cgi_setenv("PATH_INFO", zToken); |
| 1395 | 1395 | }else{ |
| 1396 | - cgi_replace_parameter("PATH_INFO", zToken); | |
| 1396 | + cgi_replace_parameter("PATH_INFO", mprintf("%s",zToken)); | |
| 1397 | 1397 | } |
| 1398 | 1398 | |
| 1399 | 1399 | /* Get all the optional fields that follow the first line. |
| 1400 | 1400 | */ |
| 1401 | 1401 | while( fgets(zLine,sizeof(zLine),g.httpIn) ){ |
| 1402 | 1402 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -460,15 +460,15 @@ | |
| 460 | */ |
| 461 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 462 | int i; |
| 463 | for(i=0; i<nUsedQP; i++){ |
| 464 | if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ |
| 465 | aParamQP[i].zValue = mprintf("%s",zValue); |
| 466 | return; |
| 467 | } |
| 468 | } |
| 469 | cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0); |
| 470 | } |
| 471 | |
| 472 | /* |
| 473 | ** Add a query parameter. The zName portion is fixed but a copy |
| 474 | ** must be made of zValue. |
| @@ -1391,11 +1391,11 @@ | |
| 1391 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1392 | if( zToken[i] ) zToken[i++] = 0; |
| 1393 | if( nCycles==0 ){ |
| 1394 | cgi_setenv("PATH_INFO", zToken); |
| 1395 | }else{ |
| 1396 | cgi_replace_parameter("PATH_INFO", zToken); |
| 1397 | } |
| 1398 | |
| 1399 | /* Get all the optional fields that follow the first line. |
| 1400 | */ |
| 1401 | while( fgets(zLine,sizeof(zLine),g.httpIn) ){ |
| 1402 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -460,15 +460,15 @@ | |
| 460 | */ |
| 461 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 462 | int i; |
| 463 | for(i=0; i<nUsedQP; i++){ |
| 464 | if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ |
| 465 | aParamQP[i].zValue = zValue; |
| 466 | return; |
| 467 | } |
| 468 | } |
| 469 | cgi_set_parameter_nocopy(zName, zValue, 0); |
| 470 | } |
| 471 | |
| 472 | /* |
| 473 | ** Add a query parameter. The zName portion is fixed but a copy |
| 474 | ** must be made of zValue. |
| @@ -1391,11 +1391,11 @@ | |
| 1391 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1392 | if( zToken[i] ) zToken[i++] = 0; |
| 1393 | if( nCycles==0 ){ |
| 1394 | cgi_setenv("PATH_INFO", zToken); |
| 1395 | }else{ |
| 1396 | cgi_replace_parameter("PATH_INFO", mprintf("%s",zToken)); |
| 1397 | } |
| 1398 | |
| 1399 | /* Get all the optional fields that follow the first line. |
| 1400 | */ |
| 1401 | while( fgets(zLine,sizeof(zLine),g.httpIn) ){ |
| 1402 |
+2
-21
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -90,31 +90,28 @@ | ||
| 90 | 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | 91 | ** HTTP/HTTPS protocol: |
| 92 | 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | 93 | ** |
| 94 | 94 | ** SSH protocol: |
| 95 | -** ssh://[userid[:password]@]host[:port]/path/to/repo.fossil | |
| 95 | +** ssh://[userid[:password]@]host[:port]/path/to/repo.fossil\\ | |
| 96 | +** [?fossil=path/to/fossil.exe] | |
| 96 | 97 | ** |
| 97 | 98 | ** Filesystem: |
| 98 | 99 | ** [file://]path/to/repo.fossil |
| 99 | 100 | ** |
| 100 | 101 | ** Note: For ssh and filesystem, path must have an extra leading |
| 101 | 102 | ** '/' to use an absolute path. |
| 102 | 103 | ** |
| 103 | -** Note: the userid for SSH is the SSH account, not the Fossil account. | |
| 104 | -** | |
| 105 | 104 | ** By default, your current login name is used to create the default |
| 106 | 105 | ** admin user. This can be overridden using the -A|--admin-user |
| 107 | 106 | ** parameter. |
| 108 | 107 | ** |
| 109 | 108 | ** Options: |
| 110 | 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 111 | 110 | ** --private Also clone private branches |
| 112 | 111 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | -** --ssh-fossil|-f /fossil Use this path as remote fossil command | |
| 114 | 112 | ** --ssh-command|-c 'command' Use this SSH command |
| 115 | -** --ssh-fossil-user|-l user Fossil user to use for SSH if different. | |
| 116 | 113 | ** |
| 117 | 114 | ** See also: init |
| 118 | 115 | */ |
| 119 | 116 | void clone_cmd(void){ |
| 120 | 117 | char *zPassword; |
| @@ -199,38 +196,22 @@ | ||
| 199 | 196 | |
| 200 | 197 | /* |
| 201 | 198 | ** Look for SSH clone command line options and setup in globals. |
| 202 | 199 | */ |
| 203 | 200 | void clone_ssh_find_options(void){ |
| 204 | - const char *zSshFossilCmd; /* Path to remote fossil command for SSH */ | |
| 205 | 201 | const char *zSshCmd; /* SSH command string */ |
| 206 | - const char *zFossilUser; /* Fossil user if login specified for SSH */ | |
| 207 | 202 | |
| 208 | - zSshFossilCmd = find_option("ssh-fossil","f",1); | |
| 209 | - if( zSshFossilCmd && zSshFossilCmd[0] ){ | |
| 210 | - g.zSshFossilCmd = mprintf("%s", zSshFossilCmd); | |
| 211 | - } | |
| 212 | 203 | zSshCmd = find_option("ssh-command","c",1); |
| 213 | 204 | if( zSshCmd && zSshCmd[0] ){ |
| 214 | 205 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 215 | 206 | } |
| 216 | - zFossilUser = find_option("ssh-fossil-user","l",1); | |
| 217 | - if( zFossilUser && zFossilUser[0] ){ | |
| 218 | - g.zFossilUser = mprintf("%s", zFossilUser); | |
| 219 | - } | |
| 220 | 207 | } |
| 221 | 208 | |
| 222 | 209 | /* |
| 223 | 210 | ** Set SSH options discovered in global variables (set from command line |
| 224 | 211 | ** options). |
| 225 | 212 | */ |
| 226 | 213 | void clone_ssh_db_set_options(void){ |
| 227 | - if( g.zSshFossilCmd && g.zSshFossilCmd[0] ){ | |
| 228 | - db_set("ssh-fossil", g.zSshFossilCmd, 0); | |
| 229 | - } | |
| 230 | 214 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 231 | 215 | db_set("ssh-command", g.zSshCmd, 0); |
| 232 | 216 | } |
| 233 | - if( g.zFossilUser && g.zFossilUser[0] ){ | |
| 234 | - db_set("ssh-fossil-user", g.zFossilUser, 0); | |
| 235 | - } | |
| 236 | 217 | } |
| 237 | 218 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -90,31 +90,28 @@ | |
| 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | ** HTTP/HTTPS protocol: |
| 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | ** |
| 94 | ** SSH protocol: |
| 95 | ** ssh://[userid[:password]@]host[:port]/path/to/repo.fossil |
| 96 | ** |
| 97 | ** Filesystem: |
| 98 | ** [file://]path/to/repo.fossil |
| 99 | ** |
| 100 | ** Note: For ssh and filesystem, path must have an extra leading |
| 101 | ** '/' to use an absolute path. |
| 102 | ** |
| 103 | ** Note: the userid for SSH is the SSH account, not the Fossil account. |
| 104 | ** |
| 105 | ** By default, your current login name is used to create the default |
| 106 | ** admin user. This can be overridden using the -A|--admin-user |
| 107 | ** parameter. |
| 108 | ** |
| 109 | ** Options: |
| 110 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 111 | ** --private Also clone private branches |
| 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | ** --ssh-fossil|-f /fossil Use this path as remote fossil command |
| 114 | ** --ssh-command|-c 'command' Use this SSH command |
| 115 | ** --ssh-fossil-user|-l user Fossil user to use for SSH if different. |
| 116 | ** |
| 117 | ** See also: init |
| 118 | */ |
| 119 | void clone_cmd(void){ |
| 120 | char *zPassword; |
| @@ -199,38 +196,22 @@ | |
| 199 | |
| 200 | /* |
| 201 | ** Look for SSH clone command line options and setup in globals. |
| 202 | */ |
| 203 | void clone_ssh_find_options(void){ |
| 204 | const char *zSshFossilCmd; /* Path to remote fossil command for SSH */ |
| 205 | const char *zSshCmd; /* SSH command string */ |
| 206 | const char *zFossilUser; /* Fossil user if login specified for SSH */ |
| 207 | |
| 208 | zSshFossilCmd = find_option("ssh-fossil","f",1); |
| 209 | if( zSshFossilCmd && zSshFossilCmd[0] ){ |
| 210 | g.zSshFossilCmd = mprintf("%s", zSshFossilCmd); |
| 211 | } |
| 212 | zSshCmd = find_option("ssh-command","c",1); |
| 213 | if( zSshCmd && zSshCmd[0] ){ |
| 214 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 215 | } |
| 216 | zFossilUser = find_option("ssh-fossil-user","l",1); |
| 217 | if( zFossilUser && zFossilUser[0] ){ |
| 218 | g.zFossilUser = mprintf("%s", zFossilUser); |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | /* |
| 223 | ** Set SSH options discovered in global variables (set from command line |
| 224 | ** options). |
| 225 | */ |
| 226 | void clone_ssh_db_set_options(void){ |
| 227 | if( g.zSshFossilCmd && g.zSshFossilCmd[0] ){ |
| 228 | db_set("ssh-fossil", g.zSshFossilCmd, 0); |
| 229 | } |
| 230 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 231 | db_set("ssh-command", g.zSshCmd, 0); |
| 232 | } |
| 233 | if( g.zFossilUser && g.zFossilUser[0] ){ |
| 234 | db_set("ssh-fossil-user", g.zFossilUser, 0); |
| 235 | } |
| 236 | } |
| 237 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -90,31 +90,28 @@ | |
| 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | ** HTTP/HTTPS protocol: |
| 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | ** |
| 94 | ** SSH protocol: |
| 95 | ** ssh://[userid[:password]@]host[:port]/path/to/repo.fossil\\ |
| 96 | ** [?fossil=path/to/fossil.exe] |
| 97 | ** |
| 98 | ** Filesystem: |
| 99 | ** [file://]path/to/repo.fossil |
| 100 | ** |
| 101 | ** Note: For ssh and filesystem, path must have an extra leading |
| 102 | ** '/' to use an absolute path. |
| 103 | ** |
| 104 | ** By default, your current login name is used to create the default |
| 105 | ** admin user. This can be overridden using the -A|--admin-user |
| 106 | ** parameter. |
| 107 | ** |
| 108 | ** Options: |
| 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | ** --private Also clone private branches |
| 111 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 112 | ** --ssh-command|-c 'command' Use this SSH command |
| 113 | ** |
| 114 | ** See also: init |
| 115 | */ |
| 116 | void clone_cmd(void){ |
| 117 | char *zPassword; |
| @@ -199,38 +196,22 @@ | |
| 196 | |
| 197 | /* |
| 198 | ** Look for SSH clone command line options and setup in globals. |
| 199 | */ |
| 200 | void clone_ssh_find_options(void){ |
| 201 | const char *zSshCmd; /* SSH command string */ |
| 202 | |
| 203 | zSshCmd = find_option("ssh-command","c",1); |
| 204 | if( zSshCmd && zSshCmd[0] ){ |
| 205 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | /* |
| 210 | ** Set SSH options discovered in global variables (set from command line |
| 211 | ** options). |
| 212 | */ |
| 213 | void clone_ssh_db_set_options(void){ |
| 214 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 215 | db_set("ssh-command", g.zSshCmd, 0); |
| 216 | } |
| 217 | } |
| 218 |
M
src/db.c
-3
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -2136,11 +2136,10 @@ | ||
| 2136 | 2136 | { "proxy", 0, 32, 0, "off" }, |
| 2137 | 2137 | { "relative-paths",0, 0, 0, "on" }, |
| 2138 | 2138 | { "repo-cksum", 0, 0, 0, "on" }, |
| 2139 | 2139 | { "self-register", 0, 0, 0, "off" }, |
| 2140 | 2140 | { "ssh-command", 0, 40, 0, "" }, |
| 2141 | - { "ssh-fossil", 0, 40, 0, "" }, | |
| 2142 | 2141 | { "ssl-ca-location",0, 40, 0, "" }, |
| 2143 | 2142 | { "ssl-identity", 0, 40, 0, "" }, |
| 2144 | 2143 | #ifdef FOSSIL_ENABLE_TCL |
| 2145 | 2144 | { "tcl", 0, 0, 0, "off" }, |
| 2146 | 2145 | { "tcl-setup", 0, 40, 0, "" }, |
| @@ -2308,12 +2307,10 @@ | ||
| 2308 | 2307 | ** users can not be deleted. Default: off. |
| 2309 | 2308 | ** |
| 2310 | 2309 | ** ssh-command Command used to talk to a remote machine with |
| 2311 | 2310 | ** the "ssh://" protocol. |
| 2312 | 2311 | ** |
| 2313 | -** ssh-fossil Remote fossil command to run with the "ssh://" protocol. | |
| 2314 | -** | |
| 2315 | 2312 | ** ssl-ca-location The full pathname to a file containing PEM encoded |
| 2316 | 2313 | ** CA root certificates, or a directory of certificates |
| 2317 | 2314 | ** with filenames formed from the certificate hashes as |
| 2318 | 2315 | ** required by OpenSSL. |
| 2319 | 2316 | ** If set, this will override the OS default list of |
| 2320 | 2317 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -2136,11 +2136,10 @@ | |
| 2136 | { "proxy", 0, 32, 0, "off" }, |
| 2137 | { "relative-paths",0, 0, 0, "on" }, |
| 2138 | { "repo-cksum", 0, 0, 0, "on" }, |
| 2139 | { "self-register", 0, 0, 0, "off" }, |
| 2140 | { "ssh-command", 0, 40, 0, "" }, |
| 2141 | { "ssh-fossil", 0, 40, 0, "" }, |
| 2142 | { "ssl-ca-location",0, 40, 0, "" }, |
| 2143 | { "ssl-identity", 0, 40, 0, "" }, |
| 2144 | #ifdef FOSSIL_ENABLE_TCL |
| 2145 | { "tcl", 0, 0, 0, "off" }, |
| 2146 | { "tcl-setup", 0, 40, 0, "" }, |
| @@ -2308,12 +2307,10 @@ | |
| 2308 | ** users can not be deleted. Default: off. |
| 2309 | ** |
| 2310 | ** ssh-command Command used to talk to a remote machine with |
| 2311 | ** the "ssh://" protocol. |
| 2312 | ** |
| 2313 | ** ssh-fossil Remote fossil command to run with the "ssh://" protocol. |
| 2314 | ** |
| 2315 | ** ssl-ca-location The full pathname to a file containing PEM encoded |
| 2316 | ** CA root certificates, or a directory of certificates |
| 2317 | ** with filenames formed from the certificate hashes as |
| 2318 | ** required by OpenSSL. |
| 2319 | ** If set, this will override the OS default list of |
| 2320 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -2136,11 +2136,10 @@ | |
| 2136 | { "proxy", 0, 32, 0, "off" }, |
| 2137 | { "relative-paths",0, 0, 0, "on" }, |
| 2138 | { "repo-cksum", 0, 0, 0, "on" }, |
| 2139 | { "self-register", 0, 0, 0, "off" }, |
| 2140 | { "ssh-command", 0, 40, 0, "" }, |
| 2141 | { "ssl-ca-location",0, 40, 0, "" }, |
| 2142 | { "ssl-identity", 0, 40, 0, "" }, |
| 2143 | #ifdef FOSSIL_ENABLE_TCL |
| 2144 | { "tcl", 0, 0, 0, "off" }, |
| 2145 | { "tcl-setup", 0, 40, 0, "" }, |
| @@ -2308,12 +2307,10 @@ | |
| 2307 | ** users can not be deleted. Default: off. |
| 2308 | ** |
| 2309 | ** ssh-command Command used to talk to a remote machine with |
| 2310 | ** the "ssh://" protocol. |
| 2311 | ** |
| 2312 | ** ssl-ca-location The full pathname to a file containing PEM encoded |
| 2313 | ** CA root certificates, or a directory of certificates |
| 2314 | ** with filenames formed from the certificate hashes as |
| 2315 | ** required by OpenSSL. |
| 2316 | ** If set, this will override the OS default list of |
| 2317 |
+8
-8
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -38,20 +38,22 @@ | ||
| 38 | 38 | const char *zLogin; /* The user login name */ |
| 39 | 39 | const char *zPw; /* The user password */ |
| 40 | 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | 41 | Blob sig; /* The signature field */ |
| 42 | 42 | |
| 43 | - zLogin = url_or_fossil_user(); | |
| 44 | 43 | blob_zero(pLogin); |
| 45 | - if( zLogin==0 || fossil_strcmp(g.urlUser, "anonymous")==0 || | |
| 46 | - ( g.urlIsSsh && ! url_ssh_use_http() ) ){ | |
| 47 | - return; /* If no login card for users "nobody" and "anonymous" */ | |
| 44 | + if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ | |
| 45 | + return; /* If no login card for users "nobody" and "anonymous" */ | |
| 46 | + } | |
| 47 | + if( g.urlIsSsh ){ | |
| 48 | + return; /* If no login card for SSH: */ | |
| 48 | 49 | } |
| 49 | 50 | blob_zero(&nonce); |
| 50 | 51 | blob_zero(&pw); |
| 51 | 52 | sha1sum_blob(pPayload, &nonce); |
| 52 | 53 | blob_copy(&pw, &nonce); |
| 54 | + zLogin = g.urlUser; | |
| 53 | 55 | if( g.urlPasswd ){ |
| 54 | 56 | zPw = g.urlPasswd; |
| 55 | 57 | }else if( g.cgiOutput ){ |
| 56 | 58 | /* Password failure while doing a sync from the web interface */ |
| 57 | 59 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| @@ -88,13 +90,11 @@ | ||
| 88 | 90 | ** the complete payload (including the login card) already compressed. |
| 89 | 91 | */ |
| 90 | 92 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 91 | 93 | int i; |
| 92 | 94 | const char *zSep; |
| 93 | - const char *zLogin; | |
| 94 | 95 | |
| 95 | - zLogin = url_or_fossil_user(); | |
| 96 | 96 | blob_zero(pHdr); |
| 97 | 97 | i = strlen(g.urlPath); |
| 98 | 98 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 99 | 99 | zSep = ""; |
| 100 | 100 | }else{ |
| @@ -102,12 +102,12 @@ | ||
| 102 | 102 | } |
| 103 | 103 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 104 | 104 | if( g.urlProxyAuth ){ |
| 105 | 105 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 106 | 106 | } |
| 107 | - if( g.urlPasswd && zLogin && g.urlPasswd[0]=='#' ){ | |
| 108 | - char *zCredentials = mprintf("%s:%s", zLogin, &g.urlPasswd[1]); | |
| 107 | + if( g.urlPasswd && g.urlUser && g.urlPasswd[0]=='#' ){ | |
| 108 | + char *zCredentials = mprintf("%s:%s", g.urlUser, &g.urlPasswd[1]); | |
| 109 | 109 | char *zEncoded = encode64(zCredentials, -1); |
| 110 | 110 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 111 | 111 | fossil_free(zEncoded); |
| 112 | 112 | fossil_free(zCredentials); |
| 113 | 113 | } |
| 114 | 114 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -38,20 +38,22 @@ | |
| 38 | const char *zLogin; /* The user login name */ |
| 39 | const char *zPw; /* The user password */ |
| 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | Blob sig; /* The signature field */ |
| 42 | |
| 43 | zLogin = url_or_fossil_user(); |
| 44 | blob_zero(pLogin); |
| 45 | if( zLogin==0 || fossil_strcmp(g.urlUser, "anonymous")==0 || |
| 46 | ( g.urlIsSsh && ! url_ssh_use_http() ) ){ |
| 47 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 48 | } |
| 49 | blob_zero(&nonce); |
| 50 | blob_zero(&pw); |
| 51 | sha1sum_blob(pPayload, &nonce); |
| 52 | blob_copy(&pw, &nonce); |
| 53 | if( g.urlPasswd ){ |
| 54 | zPw = g.urlPasswd; |
| 55 | }else if( g.cgiOutput ){ |
| 56 | /* Password failure while doing a sync from the web interface */ |
| 57 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| @@ -88,13 +90,11 @@ | |
| 88 | ** the complete payload (including the login card) already compressed. |
| 89 | */ |
| 90 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 91 | int i; |
| 92 | const char *zSep; |
| 93 | const char *zLogin; |
| 94 | |
| 95 | zLogin = url_or_fossil_user(); |
| 96 | blob_zero(pHdr); |
| 97 | i = strlen(g.urlPath); |
| 98 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 99 | zSep = ""; |
| 100 | }else{ |
| @@ -102,12 +102,12 @@ | |
| 102 | } |
| 103 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 104 | if( g.urlProxyAuth ){ |
| 105 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 106 | } |
| 107 | if( g.urlPasswd && zLogin && g.urlPasswd[0]=='#' ){ |
| 108 | char *zCredentials = mprintf("%s:%s", zLogin, &g.urlPasswd[1]); |
| 109 | char *zEncoded = encode64(zCredentials, -1); |
| 110 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 111 | fossil_free(zEncoded); |
| 112 | fossil_free(zCredentials); |
| 113 | } |
| 114 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -38,20 +38,22 @@ | |
| 38 | const char *zLogin; /* The user login name */ |
| 39 | const char *zPw; /* The user password */ |
| 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | Blob sig; /* The signature field */ |
| 42 | |
| 43 | blob_zero(pLogin); |
| 44 | if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ |
| 45 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 46 | } |
| 47 | if( g.urlIsSsh ){ |
| 48 | return; /* If no login card for SSH: */ |
| 49 | } |
| 50 | blob_zero(&nonce); |
| 51 | blob_zero(&pw); |
| 52 | sha1sum_blob(pPayload, &nonce); |
| 53 | blob_copy(&pw, &nonce); |
| 54 | zLogin = g.urlUser; |
| 55 | if( g.urlPasswd ){ |
| 56 | zPw = g.urlPasswd; |
| 57 | }else if( g.cgiOutput ){ |
| 58 | /* Password failure while doing a sync from the web interface */ |
| 59 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| @@ -88,13 +90,11 @@ | |
| 90 | ** the complete payload (including the login card) already compressed. |
| 91 | */ |
| 92 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 93 | int i; |
| 94 | const char *zSep; |
| 95 | |
| 96 | blob_zero(pHdr); |
| 97 | i = strlen(g.urlPath); |
| 98 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 99 | zSep = ""; |
| 100 | }else{ |
| @@ -102,12 +102,12 @@ | |
| 102 | } |
| 103 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 104 | if( g.urlProxyAuth ){ |
| 105 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 106 | } |
| 107 | if( g.urlPasswd && g.urlUser && g.urlPasswd[0]=='#' ){ |
| 108 | char *zCredentials = mprintf("%s:%s", g.urlUser, &g.urlPasswd[1]); |
| 109 | char *zEncoded = encode64(zCredentials, -1); |
| 110 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 111 | fossil_free(zEncoded); |
| 112 | fossil_free(zCredentials); |
| 113 | } |
| 114 |
+2
-8
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -91,19 +91,17 @@ | ||
| 91 | 91 | int transport_ssh_open(void){ |
| 92 | 92 | /* For SSH we need to create and run SSH fossil http |
| 93 | 93 | ** to talk to the remote machine. |
| 94 | 94 | */ |
| 95 | 95 | static int fPrintSshCmd = 1; /* Print SSH command only once */ |
| 96 | - const char *zSshFossilCmd; /* Path to fossil on remote host */ | |
| 97 | 96 | const char *zSsh; /* The base SSH command */ |
| 98 | 97 | Blob zCmd; /* The SSH command */ |
| 99 | 98 | char *zHost; /* The host name to contact */ |
| 100 | 99 | int n; /* Size of prefix string */ |
| 101 | 100 | |
| 102 | 101 | socket_ssh_resolve_addr(); |
| 103 | 102 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 104 | - zSshFossilCmd = db_get("ssh-fossil", "fossil"); | |
| 105 | 103 | blob_init(&zCmd, zSsh, -1); |
| 106 | 104 | if( g.urlPort!=g.urlDfltPort && g.urlPort ){ |
| 107 | 105 | #ifdef __MINGW32__ |
| 108 | 106 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 109 | 107 | #else |
| @@ -121,16 +119,12 @@ | ||
| 121 | 119 | } |
| 122 | 120 | n = blob_size(&zCmd); |
| 123 | 121 | blob_append(&zCmd, " ", 1); |
| 124 | 122 | shell_escape(&zCmd, zHost); |
| 125 | 123 | blob_append(&zCmd, " ", 1); |
| 126 | - shell_escape(&zCmd, mprintf("%s", zSshFossilCmd)); | |
| 127 | - if( url_ssh_use_http() ){ | |
| 128 | - blob_append(&zCmd, " http", 5); | |
| 129 | - }else{ | |
| 130 | - blob_append(&zCmd, " test-http", 10); | |
| 131 | - } | |
| 124 | + shell_escape(&zCmd, mprintf("%s", g.urlFossil)); | |
| 125 | + blob_append(&zCmd, " test-http", 10); | |
| 132 | 126 | if( g.urlPath && g.urlPath[0] ){ |
| 133 | 127 | blob_append(&zCmd, " ", 1); |
| 134 | 128 | shell_escape(&zCmd, mprintf("%s", g.urlPath)); |
| 135 | 129 | } |
| 136 | 130 | if( fPrintSshCmd ){ |
| 137 | 131 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -91,19 +91,17 @@ | |
| 91 | int transport_ssh_open(void){ |
| 92 | /* For SSH we need to create and run SSH fossil http |
| 93 | ** to talk to the remote machine. |
| 94 | */ |
| 95 | static int fPrintSshCmd = 1; /* Print SSH command only once */ |
| 96 | const char *zSshFossilCmd; /* Path to fossil on remote host */ |
| 97 | const char *zSsh; /* The base SSH command */ |
| 98 | Blob zCmd; /* The SSH command */ |
| 99 | char *zHost; /* The host name to contact */ |
| 100 | int n; /* Size of prefix string */ |
| 101 | |
| 102 | socket_ssh_resolve_addr(); |
| 103 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 104 | zSshFossilCmd = db_get("ssh-fossil", "fossil"); |
| 105 | blob_init(&zCmd, zSsh, -1); |
| 106 | if( g.urlPort!=g.urlDfltPort && g.urlPort ){ |
| 107 | #ifdef __MINGW32__ |
| 108 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 109 | #else |
| @@ -121,16 +119,12 @@ | |
| 121 | } |
| 122 | n = blob_size(&zCmd); |
| 123 | blob_append(&zCmd, " ", 1); |
| 124 | shell_escape(&zCmd, zHost); |
| 125 | blob_append(&zCmd, " ", 1); |
| 126 | shell_escape(&zCmd, mprintf("%s", zSshFossilCmd)); |
| 127 | if( url_ssh_use_http() ){ |
| 128 | blob_append(&zCmd, " http", 5); |
| 129 | }else{ |
| 130 | blob_append(&zCmd, " test-http", 10); |
| 131 | } |
| 132 | if( g.urlPath && g.urlPath[0] ){ |
| 133 | blob_append(&zCmd, " ", 1); |
| 134 | shell_escape(&zCmd, mprintf("%s", g.urlPath)); |
| 135 | } |
| 136 | if( fPrintSshCmd ){ |
| 137 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -91,19 +91,17 @@ | |
| 91 | int transport_ssh_open(void){ |
| 92 | /* For SSH we need to create and run SSH fossil http |
| 93 | ** to talk to the remote machine. |
| 94 | */ |
| 95 | static int fPrintSshCmd = 1; /* Print SSH command only once */ |
| 96 | const char *zSsh; /* The base SSH command */ |
| 97 | Blob zCmd; /* The SSH command */ |
| 98 | char *zHost; /* The host name to contact */ |
| 99 | int n; /* Size of prefix string */ |
| 100 | |
| 101 | socket_ssh_resolve_addr(); |
| 102 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 103 | blob_init(&zCmd, zSsh, -1); |
| 104 | if( g.urlPort!=g.urlDfltPort && g.urlPort ){ |
| 105 | #ifdef __MINGW32__ |
| 106 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 107 | #else |
| @@ -121,16 +119,12 @@ | |
| 119 | } |
| 120 | n = blob_size(&zCmd); |
| 121 | blob_append(&zCmd, " ", 1); |
| 122 | shell_escape(&zCmd, zHost); |
| 123 | blob_append(&zCmd, " ", 1); |
| 124 | shell_escape(&zCmd, mprintf("%s", g.urlFossil)); |
| 125 | blob_append(&zCmd, " test-http", 10); |
| 126 | if( g.urlPath && g.urlPath[0] ){ |
| 127 | blob_append(&zCmd, " ", 1); |
| 128 | shell_escape(&zCmd, mprintf("%s", g.urlPath)); |
| 129 | } |
| 130 | if( fPrintSshCmd ){ |
| 131 |
+1
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -1307,10 +1307,11 @@ | ||
| 1307 | 1307 | CSTR(g, urlPath); |
| 1308 | 1308 | CSTR(g, urlUser); |
| 1309 | 1309 | CSTR(g, urlPasswd); |
| 1310 | 1310 | CSTR(g, urlCanonical); |
| 1311 | 1311 | CSTR(g, urlProxyAuth); |
| 1312 | + CSTR(g, urlFossil); | |
| 1312 | 1313 | CSTR(g, zLogin); |
| 1313 | 1314 | CSTR(g, zSSLIdentity); |
| 1314 | 1315 | CSTR(g, zIpAddr); |
| 1315 | 1316 | CSTR(g, zNonce); |
| 1316 | 1317 | CSTR(g, zCsrfToken); |
| 1317 | 1318 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1307,10 +1307,11 @@ | |
| 1307 | CSTR(g, urlPath); |
| 1308 | CSTR(g, urlUser); |
| 1309 | CSTR(g, urlPasswd); |
| 1310 | CSTR(g, urlCanonical); |
| 1311 | CSTR(g, urlProxyAuth); |
| 1312 | CSTR(g, zLogin); |
| 1313 | CSTR(g, zSSLIdentity); |
| 1314 | CSTR(g, zIpAddr); |
| 1315 | CSTR(g, zNonce); |
| 1316 | CSTR(g, zCsrfToken); |
| 1317 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1307,10 +1307,11 @@ | |
| 1307 | CSTR(g, urlPath); |
| 1308 | CSTR(g, urlUser); |
| 1309 | CSTR(g, urlPasswd); |
| 1310 | CSTR(g, urlCanonical); |
| 1311 | CSTR(g, urlProxyAuth); |
| 1312 | CSTR(g, urlFossil); |
| 1313 | CSTR(g, zLogin); |
| 1314 | CSTR(g, zSSLIdentity); |
| 1315 | CSTR(g, zIpAddr); |
| 1316 | CSTR(g, zNonce); |
| 1317 | CSTR(g, zCsrfToken); |
| 1318 |
+1
-4
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -136,13 +136,11 @@ | ||
| 136 | 136 | int fQuiet; /* True if -quiet flag is present */ |
| 137 | 137 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 138 | 138 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 139 | 139 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 140 | 140 | int fSshClient; /* HTTP client flags for SSH client */ |
| 141 | - char *zSshFossilCmd; /* Path to remoe fossil command for SSH */ | |
| 142 | 141 | char *zSshCmd; /* SSH command string */ |
| 143 | - char *zFossilUser; /* Fossil user if different from URL user */ | |
| 144 | 142 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 145 | 143 | char *zPath; /* Name of webpage being served */ |
| 146 | 144 | char *zExtra; /* Extra path information past the webpage name */ |
| 147 | 145 | char *zBaseURL; /* Full text of the URL being served */ |
| 148 | 146 | char *zTop; /* Parent directory of zPath */ |
| @@ -179,10 +177,11 @@ | ||
| 179 | 177 | char *urlPath; /* Pathname for http: */ |
| 180 | 178 | char *urlUser; /* User id for http: */ |
| 181 | 179 | char *urlPasswd; /* Password for http: */ |
| 182 | 180 | char *urlCanonical; /* Canonical representation of the URL */ |
| 183 | 181 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 182 | + char *urlFossil; /* The fossil query parameter on ssh: */ | |
| 184 | 183 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 185 | 184 | |
| 186 | 185 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 187 | 186 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 188 | 187 | ** SSL client identity */ |
| @@ -585,13 +584,11 @@ | ||
| 585 | 584 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 586 | 585 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 587 | 586 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 588 | 587 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 589 | 588 | g.fSshClient = 0; |
| 590 | - g.zSshFossilCmd = 0; | |
| 591 | 589 | g.zSshCmd = 0; |
| 592 | - g.zFossilUser = 0; | |
| 593 | 590 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 594 | 591 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 595 | 592 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 596 | 593 | g.zLogin = find_option("user", "U", 1); |
| 597 | 594 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 598 | 595 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -136,13 +136,11 @@ | |
| 136 | int fQuiet; /* True if -quiet flag is present */ |
| 137 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 138 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 139 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 140 | int fSshClient; /* HTTP client flags for SSH client */ |
| 141 | char *zSshFossilCmd; /* Path to remoe fossil command for SSH */ |
| 142 | char *zSshCmd; /* SSH command string */ |
| 143 | char *zFossilUser; /* Fossil user if different from URL user */ |
| 144 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 145 | char *zPath; /* Name of webpage being served */ |
| 146 | char *zExtra; /* Extra path information past the webpage name */ |
| 147 | char *zBaseURL; /* Full text of the URL being served */ |
| 148 | char *zTop; /* Parent directory of zPath */ |
| @@ -179,10 +177,11 @@ | |
| 179 | char *urlPath; /* Pathname for http: */ |
| 180 | char *urlUser; /* User id for http: */ |
| 181 | char *urlPasswd; /* Password for http: */ |
| 182 | char *urlCanonical; /* Canonical representation of the URL */ |
| 183 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 184 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 185 | |
| 186 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 187 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 188 | ** SSL client identity */ |
| @@ -585,13 +584,11 @@ | |
| 585 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 586 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 587 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 588 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 589 | g.fSshClient = 0; |
| 590 | g.zSshFossilCmd = 0; |
| 591 | g.zSshCmd = 0; |
| 592 | g.zFossilUser = 0; |
| 593 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 594 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 595 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 596 | g.zLogin = find_option("user", "U", 1); |
| 597 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 598 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -136,13 +136,11 @@ | |
| 136 | int fQuiet; /* True if -quiet flag is present */ |
| 137 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 138 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 139 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 140 | int fSshClient; /* HTTP client flags for SSH client */ |
| 141 | char *zSshCmd; /* SSH command string */ |
| 142 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 143 | char *zPath; /* Name of webpage being served */ |
| 144 | char *zExtra; /* Extra path information past the webpage name */ |
| 145 | char *zBaseURL; /* Full text of the URL being served */ |
| 146 | char *zTop; /* Parent directory of zPath */ |
| @@ -179,10 +177,11 @@ | |
| 177 | char *urlPath; /* Pathname for http: */ |
| 178 | char *urlUser; /* User id for http: */ |
| 179 | char *urlPasswd; /* Password for http: */ |
| 180 | char *urlCanonical; /* Canonical representation of the URL */ |
| 181 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 182 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 183 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 184 | |
| 185 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 186 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 187 | ** SSL client identity */ |
| @@ -585,13 +584,11 @@ | |
| 584 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 585 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 586 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 587 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 588 | g.fSshClient = 0; |
| 589 | g.zSshCmd = 0; |
| 590 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 591 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 592 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 593 | g.zLogin = find_option("user", "U", 1); |
| 594 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 595 |
+8
-24
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -49,16 +49,14 @@ | ||
| 49 | 49 | }else{ |
| 50 | 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | 51 | } |
| 52 | 52 | url_parse(0, URL_REMEMBER); |
| 53 | 53 | if( g.urlProtocol==0 ) return 0; |
| 54 | - if( ( url_or_fossil_user()!=0 ) && g.urlPasswd==0 ){ | |
| 54 | + if( g.urlUser!=0 && g.urlPasswd==0 ){ | |
| 55 | 55 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | - if( g.urlIsSsh && g.urlPasswd==0 ){ | |
| 57 | - g.urlFlags |= URL_PROMPT_PW; | |
| 58 | - url_prompt_for_password(); | |
| 59 | - } | |
| 56 | + g.urlFlags |= URL_PROMPT_PW; | |
| 57 | + url_prompt_for_password(); | |
| 60 | 58 | } |
| 61 | 59 | #if 0 /* Disabled for now */ |
| 62 | 60 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 63 | 61 | /* When doing an automatic pull, also automatically pull shuns from |
| 64 | 62 | ** the server if pull_shuns is enabled. |
| @@ -69,13 +67,11 @@ | ||
| 69 | 67 | */ |
| 70 | 68 | configSync = CONFIGSET_SHUN; |
| 71 | 69 | } |
| 72 | 70 | #endif |
| 73 | 71 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | - is_fossil_user() ? | |
| 75 | - fossil_print("Autosync: (%s) %s\n", get_fossil_user(), g.urlCanonical) : | |
| 76 | - fossil_print("Autosync: %s\n", g.urlCanonical); | |
| 72 | + fossil_print("Autosync: %s\n", g.urlCanonical); | |
| 77 | 73 | url_enable_proxy("via proxy: "); |
| 78 | 74 | rc = client_sync(flags, configSync, 0); |
| 79 | 75 | if( rc ) fossil_warning("Autosync failed"); |
| 80 | 76 | return rc; |
| 81 | 77 | } |
| @@ -114,13 +110,10 @@ | ||
| 114 | 110 | db_open_config(0); |
| 115 | 111 | if( g.argc==2 ){ |
| 116 | 112 | if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN; |
| 117 | 113 | }else if( g.argc==3 ){ |
| 118 | 114 | zUrl = g.argv[2]; |
| 119 | - if( urlFlags & URL_REMEMBER ){ | |
| 120 | - db_unset("ssh-fossil-user", 0); | |
| 121 | - } | |
| 122 | 115 | } |
| 123 | 116 | if( urlFlags & URL_REMEMBER ){ |
| 124 | 117 | clone_ssh_db_set_options(); |
| 125 | 118 | } |
| 126 | 119 | url_parse(zUrl, urlFlags); |
| @@ -129,21 +122,15 @@ | ||
| 129 | 122 | usage("URL"); |
| 130 | 123 | } |
| 131 | 124 | user_select(); |
| 132 | 125 | if( g.argc==2 ){ |
| 133 | 126 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 134 | - is_fossil_user() ? | |
| 135 | - fossil_print("Sync with (%s) %s\n",get_fossil_user(),g.urlCanonical): | |
| 136 | - fossil_print("Sync with %s\n", g.urlCanonical); | |
| 127 | + fossil_print("Sync with %s\n", g.urlCanonical); | |
| 137 | 128 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 138 | - is_fossil_user() ? | |
| 139 | - fossil_print("Push to (%s) %s\n", get_fossil_user(), g.urlCanonical): | |
| 140 | - fossil_print("Push to %s\n", g.urlCanonical); | |
| 129 | + fossil_print("Push to %s\n", g.urlCanonical); | |
| 141 | 130 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 142 | - is_fossil_user() ? | |
| 143 | - fossil_print("Pull from (%s) %s\n",get_fossil_user(),g.urlCanonical): | |
| 144 | - fossil_print("Pull from %s\n", g.urlCanonical); | |
| 131 | + fossil_print("Pull from %s\n", g.urlCanonical); | |
| 145 | 132 | } |
| 146 | 133 | } |
| 147 | 134 | url_enable_proxy("via proxy: "); |
| 148 | 135 | *pConfigFlags |= configSync; |
| 149 | 136 | } |
| @@ -274,20 +261,17 @@ | ||
| 274 | 261 | usage("remote-url ?URL|off?"); |
| 275 | 262 | } |
| 276 | 263 | if( g.argc==3 ){ |
| 277 | 264 | db_unset("last-sync-url", 0); |
| 278 | 265 | db_unset("last-sync-pw", 0); |
| 279 | - db_unset("ssh-fossil-user", 0); | |
| 280 | 266 | if( is_false(g.argv[2]) ) return; |
| 281 | 267 | url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW); |
| 282 | 268 | } |
| 283 | 269 | zUrl = db_get("last-sync-url", 0); |
| 284 | 270 | if( zUrl==0 ){ |
| 285 | 271 | fossil_print("off\n"); |
| 286 | 272 | return; |
| 287 | 273 | }else{ |
| 288 | 274 | url_parse(zUrl, 0); |
| 289 | - is_fossil_user() ? | |
| 290 | - fossil_print("(%s) %s\n", get_fossil_user(), g.urlCanonical) : | |
| 291 | - fossil_print("%s\n", g.urlCanonical); | |
| 275 | + fossil_print("%s\n", g.urlCanonical); | |
| 292 | 276 | } |
| 293 | 277 | } |
| 294 | 278 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -49,16 +49,14 @@ | |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.urlProtocol==0 ) return 0; |
| 54 | if( ( url_or_fossil_user()!=0 ) && g.urlPasswd==0 ){ |
| 55 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | if( g.urlIsSsh && g.urlPasswd==0 ){ |
| 57 | g.urlFlags |= URL_PROMPT_PW; |
| 58 | url_prompt_for_password(); |
| 59 | } |
| 60 | } |
| 61 | #if 0 /* Disabled for now */ |
| 62 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 63 | /* When doing an automatic pull, also automatically pull shuns from |
| 64 | ** the server if pull_shuns is enabled. |
| @@ -69,13 +67,11 @@ | |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| 72 | #endif |
| 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | is_fossil_user() ? |
| 75 | fossil_print("Autosync: (%s) %s\n", get_fossil_user(), g.urlCanonical) : |
| 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 77 | url_enable_proxy("via proxy: "); |
| 78 | rc = client_sync(flags, configSync, 0); |
| 79 | if( rc ) fossil_warning("Autosync failed"); |
| 80 | return rc; |
| 81 | } |
| @@ -114,13 +110,10 @@ | |
| 114 | db_open_config(0); |
| 115 | if( g.argc==2 ){ |
| 116 | if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN; |
| 117 | }else if( g.argc==3 ){ |
| 118 | zUrl = g.argv[2]; |
| 119 | if( urlFlags & URL_REMEMBER ){ |
| 120 | db_unset("ssh-fossil-user", 0); |
| 121 | } |
| 122 | } |
| 123 | if( urlFlags & URL_REMEMBER ){ |
| 124 | clone_ssh_db_set_options(); |
| 125 | } |
| 126 | url_parse(zUrl, urlFlags); |
| @@ -129,21 +122,15 @@ | |
| 129 | usage("URL"); |
| 130 | } |
| 131 | user_select(); |
| 132 | if( g.argc==2 ){ |
| 133 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 134 | is_fossil_user() ? |
| 135 | fossil_print("Sync with (%s) %s\n",get_fossil_user(),g.urlCanonical): |
| 136 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 137 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 138 | is_fossil_user() ? |
| 139 | fossil_print("Push to (%s) %s\n", get_fossil_user(), g.urlCanonical): |
| 140 | fossil_print("Push to %s\n", g.urlCanonical); |
| 141 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 142 | is_fossil_user() ? |
| 143 | fossil_print("Pull from (%s) %s\n",get_fossil_user(),g.urlCanonical): |
| 144 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 145 | } |
| 146 | } |
| 147 | url_enable_proxy("via proxy: "); |
| 148 | *pConfigFlags |= configSync; |
| 149 | } |
| @@ -274,20 +261,17 @@ | |
| 274 | usage("remote-url ?URL|off?"); |
| 275 | } |
| 276 | if( g.argc==3 ){ |
| 277 | db_unset("last-sync-url", 0); |
| 278 | db_unset("last-sync-pw", 0); |
| 279 | db_unset("ssh-fossil-user", 0); |
| 280 | if( is_false(g.argv[2]) ) return; |
| 281 | url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW); |
| 282 | } |
| 283 | zUrl = db_get("last-sync-url", 0); |
| 284 | if( zUrl==0 ){ |
| 285 | fossil_print("off\n"); |
| 286 | return; |
| 287 | }else{ |
| 288 | url_parse(zUrl, 0); |
| 289 | is_fossil_user() ? |
| 290 | fossil_print("(%s) %s\n", get_fossil_user(), g.urlCanonical) : |
| 291 | fossil_print("%s\n", g.urlCanonical); |
| 292 | } |
| 293 | } |
| 294 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -49,16 +49,14 @@ | |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.urlProtocol==0 ) return 0; |
| 54 | if( g.urlUser!=0 && g.urlPasswd==0 ){ |
| 55 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.urlFlags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| 59 | #if 0 /* Disabled for now */ |
| 60 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 61 | /* When doing an automatic pull, also automatically pull shuns from |
| 62 | ** the server if pull_shuns is enabled. |
| @@ -69,13 +67,11 @@ | |
| 67 | */ |
| 68 | configSync = CONFIGSET_SHUN; |
| 69 | } |
| 70 | #endif |
| 71 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 72 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 73 | url_enable_proxy("via proxy: "); |
| 74 | rc = client_sync(flags, configSync, 0); |
| 75 | if( rc ) fossil_warning("Autosync failed"); |
| 76 | return rc; |
| 77 | } |
| @@ -114,13 +110,10 @@ | |
| 110 | db_open_config(0); |
| 111 | if( g.argc==2 ){ |
| 112 | if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN; |
| 113 | }else if( g.argc==3 ){ |
| 114 | zUrl = g.argv[2]; |
| 115 | } |
| 116 | if( urlFlags & URL_REMEMBER ){ |
| 117 | clone_ssh_db_set_options(); |
| 118 | } |
| 119 | url_parse(zUrl, urlFlags); |
| @@ -129,21 +122,15 @@ | |
| 122 | usage("URL"); |
| 123 | } |
| 124 | user_select(); |
| 125 | if( g.argc==2 ){ |
| 126 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 127 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 128 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 129 | fossil_print("Push to %s\n", g.urlCanonical); |
| 130 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 131 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 132 | } |
| 133 | } |
| 134 | url_enable_proxy("via proxy: "); |
| 135 | *pConfigFlags |= configSync; |
| 136 | } |
| @@ -274,20 +261,17 @@ | |
| 261 | usage("remote-url ?URL|off?"); |
| 262 | } |
| 263 | if( g.argc==3 ){ |
| 264 | db_unset("last-sync-url", 0); |
| 265 | db_unset("last-sync-pw", 0); |
| 266 | if( is_false(g.argv[2]) ) return; |
| 267 | url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW); |
| 268 | } |
| 269 | zUrl = db_get("last-sync-url", 0); |
| 270 | if( zUrl==0 ){ |
| 271 | fossil_print("off\n"); |
| 272 | return; |
| 273 | }else{ |
| 274 | url_parse(zUrl, 0); |
| 275 | fossil_print("%s\n", g.urlCanonical); |
| 276 | } |
| 277 | } |
| 278 |
+37
-29
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -64,11 +64,11 @@ | ||
| 64 | 64 | ** |
| 65 | 65 | ** http://userid:password@host:port/path |
| 66 | 66 | ** |
| 67 | 67 | ** SSH url format is: |
| 68 | 68 | ** |
| 69 | -** ssh://userid:password@host:port/path | |
| 69 | +** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe | |
| 70 | 70 | ** |
| 71 | 71 | */ |
| 72 | 72 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 73 | 73 | int i, j, c; |
| 74 | 74 | char *zFile = 0; |
| @@ -77,18 +77,10 @@ | ||
| 77 | 77 | |
| 78 | 78 | if( zUrl==0 ){ |
| 79 | 79 | zUrl = db_get("last-sync-url", 0); |
| 80 | 80 | if( zUrl==0 ) return; |
| 81 | 81 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 82 | - if( g.zFossilUser==0 ){ | |
| 83 | - g.zFossilUser = db_get("ssh-fossil-user", 0); | |
| 84 | - }else{ | |
| 85 | - if( g.urlPasswd ) { | |
| 86 | - free(g.urlPasswd); | |
| 87 | - g.urlPasswd = 0; | |
| 88 | - } | |
| 89 | - } | |
| 90 | 82 | bSetUrl = 0; |
| 91 | 83 | } |
| 92 | 84 | |
| 93 | 85 | if( strncmp(zUrl, "http://", 7)==0 |
| 94 | 86 | || strncmp(zUrl, "https://", 8)==0 |
| @@ -107,10 +99,11 @@ | ||
| 107 | 99 | iStart = 8; |
| 108 | 100 | }else if( zUrl[0]=='s' ){ |
| 109 | 101 | g.urlIsSsh = 1; |
| 110 | 102 | g.urlProtocol = "ssh"; |
| 111 | 103 | g.urlDfltPort = 22; |
| 104 | + g.urlFossil = "fossil"; | |
| 112 | 105 | iStart = 6; |
| 113 | 106 | }else{ |
| 114 | 107 | g.urlIsHttps = 0; |
| 115 | 108 | g.urlProtocol = "http"; |
| 116 | 109 | g.urlDfltPort = 80; |
| @@ -157,21 +150,44 @@ | ||
| 157 | 150 | for(i=0; g.urlPath[i] && g.urlPath[i]!='?'; i++){} |
| 158 | 151 | if( g.urlPath[i] ){ |
| 159 | 152 | g.urlPath[i] = 0; |
| 160 | 153 | i++; |
| 161 | 154 | } |
| 155 | + zExe = mprintf(""); | |
| 156 | + while( g.urlPath[i]!=0 ){ | |
| 157 | + char *zName, *zValue; | |
| 158 | + zName = &g.urlPath[i]; | |
| 159 | + zValue = zName; | |
| 160 | + while( g.urlPath[i] && g.urlPath[i]!='=' ){ i++; } | |
| 161 | + if( g.urlPath[i]=='=' ){ | |
| 162 | + g.urlPath[i] = 0; | |
| 163 | + i++; | |
| 164 | + zValue = &g.urlPath[i]; | |
| 165 | + while( g.urlPath[i] && g.urlPath[i]!='&' ){ i++; } | |
| 166 | + } | |
| 167 | + if( g.urlPath[i] ){ | |
| 168 | + g.urlPath[i] = 0; | |
| 169 | + i++; | |
| 170 | + } | |
| 171 | + if( fossil_strcmp(zName,"fossil")==0 ){ | |
| 172 | + g.urlFossil = zValue; | |
| 173 | + dehttpize(g.urlFossil); | |
| 174 | + zExe = mprintf("%cfossil=%T", cQuerySep, g.urlFossil); | |
| 175 | + cQuerySep = '&'; | |
| 176 | + } | |
| 177 | + } | |
| 162 | 178 | |
| 163 | 179 | dehttpize(g.urlPath); |
| 164 | 180 | if( g.urlDfltPort==g.urlPort ){ |
| 165 | 181 | g.urlCanonical = mprintf( |
| 166 | - "%s://%s%T%T", | |
| 167 | - g.urlProtocol, zLogin, g.urlName, g.urlPath | |
| 182 | + "%s://%s%T%T%s", | |
| 183 | + g.urlProtocol, zLogin, g.urlName, g.urlPath, zExe | |
| 168 | 184 | ); |
| 169 | 185 | }else{ |
| 170 | 186 | g.urlCanonical = mprintf( |
| 171 | - "%s://%s%T:%d%T", | |
| 172 | - g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath | |
| 187 | + "%s://%s%T:%d%T%s", | |
| 188 | + g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath, zExe | |
| 173 | 189 | ); |
| 174 | 190 | } |
| 175 | 191 | if( g.urlIsSsh && g.urlPath[1] ) g.urlPath++; |
| 176 | 192 | free(zLogin); |
| 177 | 193 | }else if( strncmp(zUrl, "file:", 5)==0 ){ |
| @@ -205,20 +221,19 @@ | ||
| 205 | 221 | g.urlProtocol = "file"; |
| 206 | 222 | g.urlPath = ""; |
| 207 | 223 | g.urlName = mprintf("%b", &cfile); |
| 208 | 224 | g.urlCanonical = mprintf("file://%T", g.urlName); |
| 209 | 225 | blob_reset(&cfile); |
| 210 | - }else if( url_or_fossil_user()!=0 && | |
| 211 | - g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){ | |
| 226 | + }else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){ | |
| 212 | 227 | url_prompt_for_password(); |
| 213 | 228 | bPrompted = 1; |
| 214 | 229 | } |
| 215 | 230 | if( urlFlags & URL_REMEMBER ){ |
| 216 | 231 | if( bSetUrl ){ |
| 217 | 232 | db_set("last-sync-url", g.urlCanonical, 0); |
| 218 | 233 | } |
| 219 | - if( !bPrompted && g.urlPasswd && url_or_fossil_user() ){ | |
| 234 | + if( !bPrompted && g.urlPasswd && g.urlUser ){ | |
| 220 | 235 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 221 | 236 | } |
| 222 | 237 | } |
| 223 | 238 | } |
| 224 | 239 | |
| @@ -254,10 +269,11 @@ | ||
| 254 | 269 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 255 | 270 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 256 | 271 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 257 | 272 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 258 | 273 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 274 | + fossil_print("g.urlFossil = %s\n", g.urlFossil); | |
| 259 | 275 | fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); |
| 260 | 276 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 261 | 277 | if( i==0 ){ |
| 262 | 278 | fossil_print("********\n"); |
| 263 | 279 | url_enable_proxy("Using proxy: "); |
| @@ -416,17 +432,17 @@ | ||
| 416 | 432 | /* |
| 417 | 433 | ** Prompt the user for the password for g.urlUser. Store the result |
| 418 | 434 | ** in g.urlPasswd. |
| 419 | 435 | */ |
| 420 | 436 | void url_prompt_for_password(void){ |
| 421 | - if( g.urlIsFile || ( g.urlIsSsh && ! url_ssh_use_http() ) ) return; | |
| 437 | + if( g.urlIsSsh || g.urlIsFile ) return; | |
| 422 | 438 | if( isatty(fileno(stdin)) |
| 423 | 439 | && (g.urlFlags & URL_PROMPT_PW)!=0 |
| 424 | 440 | && (g.urlFlags & URL_PROMPTED)==0 |
| 425 | 441 | ){ |
| 426 | 442 | g.urlFlags |= URL_PROMPTED; |
| 427 | - g.urlPasswd = prompt_for_user_password(url_or_fossil_user()); | |
| 443 | + g.urlPasswd = prompt_for_user_password(g.urlUser); | |
| 428 | 444 | if( g.urlPasswd[0] |
| 429 | 445 | && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0 |
| 430 | 446 | ){ |
| 431 | 447 | if( save_password_prompt() ){ |
| 432 | 448 | g.urlFlags |= URL_REMEMBER_PW; |
| @@ -435,19 +451,12 @@ | ||
| 435 | 451 | } |
| 436 | 452 | } |
| 437 | 453 | } |
| 438 | 454 | }else{ |
| 439 | 455 | fossil_fatal("missing or incorrect password for user \"%s\"", |
| 440 | - url_or_fossil_user() ); | |
| 441 | - } | |
| 442 | -} | |
| 443 | - | |
| 444 | -/* | |
| 445 | -** Return true if http mode is in use for "ssh://" URL. | |
| 446 | -*/ | |
| 447 | -int url_ssh_use_http(void){ | |
| 448 | - return get_fossil_user()!=0; | |
| 456 | + g.urlUser); | |
| 457 | + } | |
| 449 | 458 | } |
| 450 | 459 | |
| 451 | 460 | /* |
| 452 | 461 | ** Remember the URL if requested. |
| 453 | 462 | */ |
| @@ -461,13 +470,12 @@ | ||
| 461 | 470 | |
| 462 | 471 | /* Preemptively prompt for a password if a username is given in the |
| 463 | 472 | ** URL but no password. |
| 464 | 473 | */ |
| 465 | 474 | void url_get_password_if_needed(void){ |
| 466 | - const char *zFossilUser = url_or_fossil_user(); | |
| 467 | - if( ( zFossilUser && zFossilUser[0] ) | |
| 475 | + if( (g.urlUser && g.urlUser[0]) | |
| 468 | 476 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 469 | 477 | && isatty(fileno(stdin)) |
| 470 | 478 | ){ |
| 471 | 479 | url_prompt_for_password(); |
| 472 | 480 | } |
| 473 | 481 | } |
| 474 | 482 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | ** |
| 65 | ** http://userid:password@host:port/path |
| 66 | ** |
| 67 | ** SSH url format is: |
| 68 | ** |
| 69 | ** ssh://userid:password@host:port/path |
| 70 | ** |
| 71 | */ |
| 72 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 73 | int i, j, c; |
| 74 | char *zFile = 0; |
| @@ -77,18 +77,10 @@ | |
| 77 | |
| 78 | if( zUrl==0 ){ |
| 79 | zUrl = db_get("last-sync-url", 0); |
| 80 | if( zUrl==0 ) return; |
| 81 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 82 | if( g.zFossilUser==0 ){ |
| 83 | g.zFossilUser = db_get("ssh-fossil-user", 0); |
| 84 | }else{ |
| 85 | if( g.urlPasswd ) { |
| 86 | free(g.urlPasswd); |
| 87 | g.urlPasswd = 0; |
| 88 | } |
| 89 | } |
| 90 | bSetUrl = 0; |
| 91 | } |
| 92 | |
| 93 | if( strncmp(zUrl, "http://", 7)==0 |
| 94 | || strncmp(zUrl, "https://", 8)==0 |
| @@ -107,10 +99,11 @@ | |
| 107 | iStart = 8; |
| 108 | }else if( zUrl[0]=='s' ){ |
| 109 | g.urlIsSsh = 1; |
| 110 | g.urlProtocol = "ssh"; |
| 111 | g.urlDfltPort = 22; |
| 112 | iStart = 6; |
| 113 | }else{ |
| 114 | g.urlIsHttps = 0; |
| 115 | g.urlProtocol = "http"; |
| 116 | g.urlDfltPort = 80; |
| @@ -157,21 +150,44 @@ | |
| 157 | for(i=0; g.urlPath[i] && g.urlPath[i]!='?'; i++){} |
| 158 | if( g.urlPath[i] ){ |
| 159 | g.urlPath[i] = 0; |
| 160 | i++; |
| 161 | } |
| 162 | |
| 163 | dehttpize(g.urlPath); |
| 164 | if( g.urlDfltPort==g.urlPort ){ |
| 165 | g.urlCanonical = mprintf( |
| 166 | "%s://%s%T%T", |
| 167 | g.urlProtocol, zLogin, g.urlName, g.urlPath |
| 168 | ); |
| 169 | }else{ |
| 170 | g.urlCanonical = mprintf( |
| 171 | "%s://%s%T:%d%T", |
| 172 | g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath |
| 173 | ); |
| 174 | } |
| 175 | if( g.urlIsSsh && g.urlPath[1] ) g.urlPath++; |
| 176 | free(zLogin); |
| 177 | }else if( strncmp(zUrl, "file:", 5)==0 ){ |
| @@ -205,20 +221,19 @@ | |
| 205 | g.urlProtocol = "file"; |
| 206 | g.urlPath = ""; |
| 207 | g.urlName = mprintf("%b", &cfile); |
| 208 | g.urlCanonical = mprintf("file://%T", g.urlName); |
| 209 | blob_reset(&cfile); |
| 210 | }else if( url_or_fossil_user()!=0 && |
| 211 | g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){ |
| 212 | url_prompt_for_password(); |
| 213 | bPrompted = 1; |
| 214 | } |
| 215 | if( urlFlags & URL_REMEMBER ){ |
| 216 | if( bSetUrl ){ |
| 217 | db_set("last-sync-url", g.urlCanonical, 0); |
| 218 | } |
| 219 | if( !bPrompted && g.urlPasswd && url_or_fossil_user() ){ |
| 220 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| @@ -254,10 +269,11 @@ | |
| 254 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 255 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 256 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 257 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 258 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 259 | fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); |
| 260 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 261 | if( i==0 ){ |
| 262 | fossil_print("********\n"); |
| 263 | url_enable_proxy("Using proxy: "); |
| @@ -416,17 +432,17 @@ | |
| 416 | /* |
| 417 | ** Prompt the user for the password for g.urlUser. Store the result |
| 418 | ** in g.urlPasswd. |
| 419 | */ |
| 420 | void url_prompt_for_password(void){ |
| 421 | if( g.urlIsFile || ( g.urlIsSsh && ! url_ssh_use_http() ) ) return; |
| 422 | if( isatty(fileno(stdin)) |
| 423 | && (g.urlFlags & URL_PROMPT_PW)!=0 |
| 424 | && (g.urlFlags & URL_PROMPTED)==0 |
| 425 | ){ |
| 426 | g.urlFlags |= URL_PROMPTED; |
| 427 | g.urlPasswd = prompt_for_user_password(url_or_fossil_user()); |
| 428 | if( g.urlPasswd[0] |
| 429 | && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0 |
| 430 | ){ |
| 431 | if( save_password_prompt() ){ |
| 432 | g.urlFlags |= URL_REMEMBER_PW; |
| @@ -435,19 +451,12 @@ | |
| 435 | } |
| 436 | } |
| 437 | } |
| 438 | }else{ |
| 439 | fossil_fatal("missing or incorrect password for user \"%s\"", |
| 440 | url_or_fossil_user() ); |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | /* |
| 445 | ** Return true if http mode is in use for "ssh://" URL. |
| 446 | */ |
| 447 | int url_ssh_use_http(void){ |
| 448 | return get_fossil_user()!=0; |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | ** Remember the URL if requested. |
| 453 | */ |
| @@ -461,13 +470,12 @@ | |
| 461 | |
| 462 | /* Preemptively prompt for a password if a username is given in the |
| 463 | ** URL but no password. |
| 464 | */ |
| 465 | void url_get_password_if_needed(void){ |
| 466 | const char *zFossilUser = url_or_fossil_user(); |
| 467 | if( ( zFossilUser && zFossilUser[0] ) |
| 468 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 469 | && isatty(fileno(stdin)) |
| 470 | ){ |
| 471 | url_prompt_for_password(); |
| 472 | } |
| 473 | } |
| 474 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | ** |
| 65 | ** http://userid:password@host:port/path |
| 66 | ** |
| 67 | ** SSH url format is: |
| 68 | ** |
| 69 | ** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe |
| 70 | ** |
| 71 | */ |
| 72 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 73 | int i, j, c; |
| 74 | char *zFile = 0; |
| @@ -77,18 +77,10 @@ | |
| 77 | |
| 78 | if( zUrl==0 ){ |
| 79 | zUrl = db_get("last-sync-url", 0); |
| 80 | if( zUrl==0 ) return; |
| 81 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 82 | bSetUrl = 0; |
| 83 | } |
| 84 | |
| 85 | if( strncmp(zUrl, "http://", 7)==0 |
| 86 | || strncmp(zUrl, "https://", 8)==0 |
| @@ -107,10 +99,11 @@ | |
| 99 | iStart = 8; |
| 100 | }else if( zUrl[0]=='s' ){ |
| 101 | g.urlIsSsh = 1; |
| 102 | g.urlProtocol = "ssh"; |
| 103 | g.urlDfltPort = 22; |
| 104 | g.urlFossil = "fossil"; |
| 105 | iStart = 6; |
| 106 | }else{ |
| 107 | g.urlIsHttps = 0; |
| 108 | g.urlProtocol = "http"; |
| 109 | g.urlDfltPort = 80; |
| @@ -157,21 +150,44 @@ | |
| 150 | for(i=0; g.urlPath[i] && g.urlPath[i]!='?'; i++){} |
| 151 | if( g.urlPath[i] ){ |
| 152 | g.urlPath[i] = 0; |
| 153 | i++; |
| 154 | } |
| 155 | zExe = mprintf(""); |
| 156 | while( g.urlPath[i]!=0 ){ |
| 157 | char *zName, *zValue; |
| 158 | zName = &g.urlPath[i]; |
| 159 | zValue = zName; |
| 160 | while( g.urlPath[i] && g.urlPath[i]!='=' ){ i++; } |
| 161 | if( g.urlPath[i]=='=' ){ |
| 162 | g.urlPath[i] = 0; |
| 163 | i++; |
| 164 | zValue = &g.urlPath[i]; |
| 165 | while( g.urlPath[i] && g.urlPath[i]!='&' ){ i++; } |
| 166 | } |
| 167 | if( g.urlPath[i] ){ |
| 168 | g.urlPath[i] = 0; |
| 169 | i++; |
| 170 | } |
| 171 | if( fossil_strcmp(zName,"fossil")==0 ){ |
| 172 | g.urlFossil = zValue; |
| 173 | dehttpize(g.urlFossil); |
| 174 | zExe = mprintf("%cfossil=%T", cQuerySep, g.urlFossil); |
| 175 | cQuerySep = '&'; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | dehttpize(g.urlPath); |
| 180 | if( g.urlDfltPort==g.urlPort ){ |
| 181 | g.urlCanonical = mprintf( |
| 182 | "%s://%s%T%T%s", |
| 183 | g.urlProtocol, zLogin, g.urlName, g.urlPath, zExe |
| 184 | ); |
| 185 | }else{ |
| 186 | g.urlCanonical = mprintf( |
| 187 | "%s://%s%T:%d%T%s", |
| 188 | g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath, zExe |
| 189 | ); |
| 190 | } |
| 191 | if( g.urlIsSsh && g.urlPath[1] ) g.urlPath++; |
| 192 | free(zLogin); |
| 193 | }else if( strncmp(zUrl, "file:", 5)==0 ){ |
| @@ -205,20 +221,19 @@ | |
| 221 | g.urlProtocol = "file"; |
| 222 | g.urlPath = ""; |
| 223 | g.urlName = mprintf("%b", &cfile); |
| 224 | g.urlCanonical = mprintf("file://%T", g.urlName); |
| 225 | blob_reset(&cfile); |
| 226 | }else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){ |
| 227 | url_prompt_for_password(); |
| 228 | bPrompted = 1; |
| 229 | } |
| 230 | if( urlFlags & URL_REMEMBER ){ |
| 231 | if( bSetUrl ){ |
| 232 | db_set("last-sync-url", g.urlCanonical, 0); |
| 233 | } |
| 234 | if( !bPrompted && g.urlPasswd && g.urlUser ){ |
| 235 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 236 | } |
| 237 | } |
| 238 | } |
| 239 | |
| @@ -254,10 +269,11 @@ | |
| 269 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 270 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 271 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 272 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 273 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 274 | fossil_print("g.urlFossil = %s\n", g.urlFossil); |
| 275 | fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); |
| 276 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 277 | if( i==0 ){ |
| 278 | fossil_print("********\n"); |
| 279 | url_enable_proxy("Using proxy: "); |
| @@ -416,17 +432,17 @@ | |
| 432 | /* |
| 433 | ** Prompt the user for the password for g.urlUser. Store the result |
| 434 | ** in g.urlPasswd. |
| 435 | */ |
| 436 | void url_prompt_for_password(void){ |
| 437 | if( g.urlIsSsh || g.urlIsFile ) return; |
| 438 | if( isatty(fileno(stdin)) |
| 439 | && (g.urlFlags & URL_PROMPT_PW)!=0 |
| 440 | && (g.urlFlags & URL_PROMPTED)==0 |
| 441 | ){ |
| 442 | g.urlFlags |= URL_PROMPTED; |
| 443 | g.urlPasswd = prompt_for_user_password(g.urlUser); |
| 444 | if( g.urlPasswd[0] |
| 445 | && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0 |
| 446 | ){ |
| 447 | if( save_password_prompt() ){ |
| 448 | g.urlFlags |= URL_REMEMBER_PW; |
| @@ -435,19 +451,12 @@ | |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | }else{ |
| 455 | fossil_fatal("missing or incorrect password for user \"%s\"", |
| 456 | g.urlUser); |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | /* |
| 461 | ** Remember the URL if requested. |
| 462 | */ |
| @@ -461,13 +470,12 @@ | |
| 470 | |
| 471 | /* Preemptively prompt for a password if a username is given in the |
| 472 | ** URL but no password. |
| 473 | */ |
| 474 | void url_get_password_if_needed(void){ |
| 475 | if( (g.urlUser && g.urlUser[0]) |
| 476 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 477 | && isatty(fileno(stdin)) |
| 478 | ){ |
| 479 | url_prompt_for_password(); |
| 480 | } |
| 481 | } |
| 482 |
-28
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -156,34 +156,10 @@ | ||
| 156 | 156 | zPw = mprintf("%b", &x); |
| 157 | 157 | blob_reset(&x); |
| 158 | 158 | return zPw; |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | -/* | |
| 162 | -** Return Fossil user if allocated and URL is SSH or URL user | |
| 163 | -*/ | |
| 164 | -const char *url_or_fossil_user(void){ | |
| 165 | - return is_fossil_user() ? get_fossil_user() : g.urlUser; | |
| 166 | -} | |
| 167 | - | |
| 168 | -/* | |
| 169 | -** Return the Fossil user from global variable (set from command line) | |
| 170 | -** or ssh-fossil-user database setting. | |
| 171 | -*/ | |
| 172 | -const char *get_fossil_user(void){ | |
| 173 | - return ( g.zFossilUser && g.zFossilUser[0] ) ? g.zFossilUser : | |
| 174 | - db_get("ssh-fossil-user", 0); | |
| 175 | -} | |
| 176 | - | |
| 177 | -/* | |
| 178 | -** Return true if URL is SSH and Fossil user is allocated | |
| 179 | -*/ | |
| 180 | -int is_fossil_user(void) { | |
| 181 | - return g.urlIsSsh && ( g.zFossilUser && g.zFossilUser[0] || | |
| 182 | - db_get("ssh-fossil-user", 0)!=0 ); | |
| 183 | -} | |
| 184 | - | |
| 185 | 161 | /* |
| 186 | 162 | ** Prompt the user to enter a single line of text. |
| 187 | 163 | */ |
| 188 | 164 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 189 | 165 | char *z; |
| @@ -370,12 +346,10 @@ | ||
| 370 | 346 | ** |
| 371 | 347 | ** (7) Try the USERNAME environment variable. |
| 372 | 348 | ** |
| 373 | 349 | ** (8) Check if the user can be extracted from the remote URL. |
| 374 | 350 | ** |
| 375 | -** (9) Check if the user was supplied as SSH command-line option. | |
| 376 | -** | |
| 377 | 351 | ** The user name is stored in g.zLogin. The uid is in g.userUid. |
| 378 | 352 | */ |
| 379 | 353 | void user_select(void){ |
| 380 | 354 | if( g.userUid ) return; |
| 381 | 355 | if( g.zLogin ){ |
| @@ -399,12 +373,10 @@ | ||
| 399 | 373 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 400 | 374 | |
| 401 | 375 | url_parse(0, 0); |
| 402 | 376 | if( g.urlUser && attempt_user(g.urlUser) ) return; |
| 403 | 377 | |
| 404 | - if( g.zFossilUser && attempt_user(g.zFossilUser) ) return; | |
| 405 | - | |
| 406 | 378 | fossil_print( |
| 407 | 379 | "Cannot figure out who you are! Consider using the --user\n" |
| 408 | 380 | "command line option, setting your USER environment variable,\n" |
| 409 | 381 | "or setting a default user with \"fossil user default USER\".\n" |
| 410 | 382 | ); |
| 411 | 383 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -156,34 +156,10 @@ | |
| 156 | zPw = mprintf("%b", &x); |
| 157 | blob_reset(&x); |
| 158 | return zPw; |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | ** Return Fossil user if allocated and URL is SSH or URL user |
| 163 | */ |
| 164 | const char *url_or_fossil_user(void){ |
| 165 | return is_fossil_user() ? get_fossil_user() : g.urlUser; |
| 166 | } |
| 167 | |
| 168 | /* |
| 169 | ** Return the Fossil user from global variable (set from command line) |
| 170 | ** or ssh-fossil-user database setting. |
| 171 | */ |
| 172 | const char *get_fossil_user(void){ |
| 173 | return ( g.zFossilUser && g.zFossilUser[0] ) ? g.zFossilUser : |
| 174 | db_get("ssh-fossil-user", 0); |
| 175 | } |
| 176 | |
| 177 | /* |
| 178 | ** Return true if URL is SSH and Fossil user is allocated |
| 179 | */ |
| 180 | int is_fossil_user(void) { |
| 181 | return g.urlIsSsh && ( g.zFossilUser && g.zFossilUser[0] || |
| 182 | db_get("ssh-fossil-user", 0)!=0 ); |
| 183 | } |
| 184 | |
| 185 | /* |
| 186 | ** Prompt the user to enter a single line of text. |
| 187 | */ |
| 188 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 189 | char *z; |
| @@ -370,12 +346,10 @@ | |
| 370 | ** |
| 371 | ** (7) Try the USERNAME environment variable. |
| 372 | ** |
| 373 | ** (8) Check if the user can be extracted from the remote URL. |
| 374 | ** |
| 375 | ** (9) Check if the user was supplied as SSH command-line option. |
| 376 | ** |
| 377 | ** The user name is stored in g.zLogin. The uid is in g.userUid. |
| 378 | */ |
| 379 | void user_select(void){ |
| 380 | if( g.userUid ) return; |
| 381 | if( g.zLogin ){ |
| @@ -399,12 +373,10 @@ | |
| 399 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 400 | |
| 401 | url_parse(0, 0); |
| 402 | if( g.urlUser && attempt_user(g.urlUser) ) return; |
| 403 | |
| 404 | if( g.zFossilUser && attempt_user(g.zFossilUser) ) return; |
| 405 | |
| 406 | fossil_print( |
| 407 | "Cannot figure out who you are! Consider using the --user\n" |
| 408 | "command line option, setting your USER environment variable,\n" |
| 409 | "or setting a default user with \"fossil user default USER\".\n" |
| 410 | ); |
| 411 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -156,34 +156,10 @@ | |
| 156 | zPw = mprintf("%b", &x); |
| 157 | blob_reset(&x); |
| 158 | return zPw; |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | ** Prompt the user to enter a single line of text. |
| 163 | */ |
| 164 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 165 | char *z; |
| @@ -370,12 +346,10 @@ | |
| 346 | ** |
| 347 | ** (7) Try the USERNAME environment variable. |
| 348 | ** |
| 349 | ** (8) Check if the user can be extracted from the remote URL. |
| 350 | ** |
| 351 | ** The user name is stored in g.zLogin. The uid is in g.userUid. |
| 352 | */ |
| 353 | void user_select(void){ |
| 354 | if( g.userUid ) return; |
| 355 | if( g.zLogin ){ |
| @@ -399,12 +373,10 @@ | |
| 373 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 374 | |
| 375 | url_parse(0, 0); |
| 376 | if( g.urlUser && attempt_user(g.urlUser) ) return; |
| 377 | |
| 378 | fossil_print( |
| 379 | "Cannot figure out who you are! Consider using the --user\n" |
| 380 | "command line option, setting your USER environment variable,\n" |
| 381 | "or setting a default user with \"fossil user default USER\".\n" |
| 382 | ); |
| 383 |
+1
-3
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1779,13 +1779,11 @@ | ||
| 1779 | 1779 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1780 | 1780 | if( nCycle<2 ){ |
| 1781 | 1781 | g.urlPasswd = 0; |
| 1782 | 1782 | go = 1; |
| 1783 | 1783 | if( g.cgiOutput==0 ){ |
| 1784 | - if( g.urlIsSsh ){ | |
| 1785 | - g.urlFlags |= URL_PROMPT_PW; | |
| 1786 | - } | |
| 1784 | + g.urlFlags |= URL_PROMPT_PW; | |
| 1787 | 1785 | url_prompt_for_password(); |
| 1788 | 1786 | } |
| 1789 | 1787 | } |
| 1790 | 1788 | }else{ |
| 1791 | 1789 | blob_appendf(&xfer.err, "server says: %s\n", zMsg); |
| 1792 | 1790 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1779,13 +1779,11 @@ | |
| 1779 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1780 | if( nCycle<2 ){ |
| 1781 | g.urlPasswd = 0; |
| 1782 | go = 1; |
| 1783 | if( g.cgiOutput==0 ){ |
| 1784 | if( g.urlIsSsh ){ |
| 1785 | g.urlFlags |= URL_PROMPT_PW; |
| 1786 | } |
| 1787 | url_prompt_for_password(); |
| 1788 | } |
| 1789 | } |
| 1790 | }else{ |
| 1791 | blob_appendf(&xfer.err, "server says: %s\n", zMsg); |
| 1792 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1779,13 +1779,11 @@ | |
| 1779 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1780 | if( nCycle<2 ){ |
| 1781 | g.urlPasswd = 0; |
| 1782 | go = 1; |
| 1783 | if( g.cgiOutput==0 ){ |
| 1784 | g.urlFlags |= URL_PROMPT_PW; |
| 1785 | url_prompt_for_password(); |
| 1786 | } |
| 1787 | } |
| 1788 | }else{ |
| 1789 | blob_appendf(&xfer.err, "server says: %s\n", zMsg); |
| 1790 |