| | @@ -17,10 +17,16 @@ |
| 17 | 17 | ** |
| 18 | 18 | ** This file contains code for parsing URLs that appear on the command-line |
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "url.h" |
| 22 | +#include <stdio.h> |
| 23 | +#ifdef _WIN32 |
| 24 | +#include <io.h> |
| 25 | +#define isatty(d) _isatty(d) |
| 26 | +#define fileno(s) _fileno(s) |
| 27 | +#endif |
| 22 | 28 | |
| 23 | 29 | #if INTERFACE |
| 24 | 30 | /* |
| 25 | 31 | ** Flags for url_parse() |
| 26 | 32 | */ |
| | @@ -64,24 +70,23 @@ |
| 64 | 70 | ** |
| 65 | 71 | ** http://userid:password@host:port/path |
| 66 | 72 | ** |
| 67 | 73 | ** SSH url format is: |
| 68 | 74 | ** |
| 69 | | -** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe |
| 75 | +** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 70 | 76 | ** |
| 71 | 77 | */ |
| 72 | 78 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 73 | 79 | int i, j, c; |
| 74 | 80 | char *zFile = 0; |
| 75 | | - int bPrompted = 0; |
| 76 | | - int bSetUrl = 1; |
| 77 | 81 | |
| 78 | 82 | if( zUrl==0 ){ |
| 79 | 83 | zUrl = db_get("last-sync-url", 0); |
| 80 | 84 | if( zUrl==0 ) return; |
| 81 | | - g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 82 | | - bSetUrl = 0; |
| 85 | + if( g.urlPasswd==0 ){ |
| 86 | + g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 87 | + } |
| 83 | 88 | } |
| 84 | 89 | |
| 85 | 90 | if( strncmp(zUrl, "http://", 7)==0 |
| 86 | 91 | || strncmp(zUrl, "https://", 8)==0 |
| 87 | 92 | || strncmp(zUrl, "ssh://", 6)==0 |
| | @@ -114,18 +119,20 @@ |
| 114 | 119 | /* Parse up the user-id and password */ |
| 115 | 120 | for(j=iStart; j<i && zUrl[j]!=':'; j++){} |
| 116 | 121 | g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]); |
| 117 | 122 | dehttpize(g.urlUser); |
| 118 | 123 | if( j<i ){ |
| 124 | + if( ( urlFlags & URL_REMEMBER ) && g.urlIsSsh==0 ){ |
| 125 | + urlFlags |= URL_ASK_REMEMBER_PW; |
| 126 | + } |
| 119 | 127 | g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]); |
| 120 | 128 | dehttpize(g.urlPasswd); |
| 121 | 129 | } |
| 122 | | - if( g.urlIsSsh && g.urlPasswd ){ |
| 123 | | - zLogin = mprintf("%t:*@", g.urlUser); |
| 124 | | - }else{ |
| 125 | | - zLogin = mprintf("%t@", g.urlUser); |
| 130 | + if( g.urlIsSsh ){ |
| 131 | + urlFlags &= ~URL_ASK_REMEMBER_PW; |
| 126 | 132 | } |
| 133 | + zLogin = mprintf("%t@", g.urlUser); |
| 127 | 134 | for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} |
| 128 | 135 | g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]); |
| 129 | 136 | i = j; |
| 130 | 137 | }else{ |
| 131 | 138 | for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){} |
| | @@ -210,11 +217,11 @@ |
| 210 | 217 | fossil_fatal("unknown repository: %s", zUrl); |
| 211 | 218 | } |
| 212 | 219 | }else{ |
| 213 | 220 | fossil_fatal("unknown repository: %s", zUrl); |
| 214 | 221 | } |
| 215 | | - g.urlFlags = urlFlags; |
| 222 | + if( urlFlags ) g.urlFlags = urlFlags; |
| 216 | 223 | if( g.urlIsFile ){ |
| 217 | 224 | Blob cfile; |
| 218 | 225 | dehttpize(zFile); |
| 219 | 226 | file_canonical_name(zFile, &cfile, 0); |
| 220 | 227 | free(zFile); |
| | @@ -223,18 +230,17 @@ |
| 223 | 230 | g.urlName = mprintf("%b", &cfile); |
| 224 | 231 | g.urlCanonical = mprintf("file://%T", g.urlName); |
| 225 | 232 | blob_reset(&cfile); |
| 226 | 233 | }else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){ |
| 227 | 234 | 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); |
| 235 | + }else if( g.urlUser!=0 && ( urlFlags & URL_ASK_REMEMBER_PW ) ){ |
| 236 | + if( isatty(fileno(stdin)) ){ |
| 237 | + if( save_password_prompt() ){ |
| 238 | + g.urlFlags = urlFlags |= URL_REMEMBER_PW; |
| 239 | + }else{ |
| 240 | + g.urlFlags = urlFlags &= ~URL_REMEMBER_PW; |
| 241 | + } |
| 236 | 242 | } |
| 237 | 243 | } |
| 238 | 244 | } |
| 239 | 245 | |
| 240 | 246 | /* |
| | @@ -444,38 +450,38 @@ |
| 444 | 450 | if( g.urlPasswd[0] |
| 445 | 451 | && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0 |
| 446 | 452 | ){ |
| 447 | 453 | if( save_password_prompt() ){ |
| 448 | 454 | g.urlFlags |= URL_REMEMBER_PW; |
| 449 | | - if( g.urlFlags & URL_REMEMBER ){ |
| 450 | | - db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 451 | | - } |
| 455 | + }else{ |
| 456 | + g.urlFlags &= ~URL_REMEMBER_PW; |
| 452 | 457 | } |
| 453 | 458 | } |
| 454 | 459 | }else{ |
| 455 | 460 | fossil_fatal("missing or incorrect password for user \"%s\"", |
| 456 | 461 | g.urlUser); |
| 457 | 462 | } |
| 458 | 463 | } |
| 459 | 464 | |
| 460 | 465 | /* |
| 461 | | -** Remember the URL if requested. |
| 466 | +** Remember the URL and password if requested. |
| 462 | 467 | */ |
| 463 | 468 | void url_remember(void){ |
| 464 | | - db_set("last-sync-url", g.urlCanonical, 0); |
| 465 | | - if( g.urlFlags & URL_REMEMBER_PW ){ |
| 466 | | - db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 469 | + if( g.urlFlags & URL_REMEMBER ){ |
| 470 | + db_set("last-sync-url", g.urlCanonical, 0); |
| 471 | + if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 472 | + db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 473 | + } |
| 467 | 474 | } |
| 468 | | - g.urlFlags |= URL_REMEMBER; |
| 469 | 475 | } |
| 470 | 476 | |
| 471 | 477 | /* Preemptively prompt for a password if a username is given in the |
| 472 | 478 | ** URL but no password. |
| 473 | 479 | */ |
| 474 | 480 | void url_get_password_if_needed(void){ |
| 475 | 481 | if( (g.urlUser && g.urlUser[0]) |
| 476 | 482 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 477 | | - && isatty(fileno(stdin)) |
| 483 | + && isatty(fileno(stdin)) |
| 478 | 484 | ){ |
| 479 | 485 | url_prompt_for_password(); |
| 480 | 486 | } |
| 481 | 487 | } |
| 482 | 488 | |