Fossil SCM
Make HTTP authorization a command line option. Choice will be stored in database until another URL change happens. This could potentially break those who currently rely on the special # character in the password.
Commit
e747041a721b7ca1a7c15d01121c604586dd9b50
Parent
f48c84afd1ace49…
5 files changed
+2
+3
-8
+1
+1
+6
+2
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -109,10 +109,11 @@ | ||
| 109 | 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | 110 | ** --once Don't save url. |
| 111 | 111 | ** --private Also clone private branches |
| 112 | 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | +** --httpauth Add HTTP Basic Authorization to requests | |
| 114 | 115 | ** |
| 115 | 116 | ** See also: init |
| 116 | 117 | */ |
| 117 | 118 | void clone_cmd(void){ |
| 118 | 119 | char *zPassword; |
| @@ -121,10 +122,11 @@ | ||
| 121 | 122 | int bPrivate = 0; /* Also clone private branches */ |
| 122 | 123 | int urlFlags = URL_PROMPT_PW | URL_REMEMBER; |
| 123 | 124 | |
| 124 | 125 | if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; |
| 125 | 126 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 127 | + g.fUseHttpAuth = find_option("httpauth",0,0)!=0; | |
| 126 | 128 | zDefaultUser = find_option("admin-user","A",1); |
| 127 | 129 | clone_ssh_find_options(); |
| 128 | 130 | url_proxy_options(); |
| 129 | 131 | if( g.argc < 4 ){ |
| 130 | 132 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 131 | 133 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -109,10 +109,11 @@ | |
| 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | ** --once Don't save url. |
| 111 | ** --private Also clone private branches |
| 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | ** |
| 115 | ** See also: init |
| 116 | */ |
| 117 | void clone_cmd(void){ |
| 118 | char *zPassword; |
| @@ -121,10 +122,11 @@ | |
| 121 | int bPrivate = 0; /* Also clone private branches */ |
| 122 | int urlFlags = URL_PROMPT_PW | URL_REMEMBER; |
| 123 | |
| 124 | if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; |
| 125 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 126 | zDefaultUser = find_option("admin-user","A",1); |
| 127 | clone_ssh_find_options(); |
| 128 | url_proxy_options(); |
| 129 | if( g.argc < 4 ){ |
| 130 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 131 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -109,10 +109,11 @@ | |
| 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | ** --once Don't save url. |
| 111 | ** --private Also clone private branches |
| 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | ** --httpauth Add HTTP Basic Authorization to requests |
| 115 | ** |
| 116 | ** See also: init |
| 117 | */ |
| 118 | void clone_cmd(void){ |
| 119 | char *zPassword; |
| @@ -121,10 +122,11 @@ | |
| 122 | int bPrivate = 0; /* Also clone private branches */ |
| 123 | int urlFlags = URL_PROMPT_PW | URL_REMEMBER; |
| 124 | |
| 125 | if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; |
| 126 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 127 | g.fUseHttpAuth = find_option("httpauth",0,0)!=0; |
| 128 | zDefaultUser = find_option("admin-user","A",1); |
| 129 | clone_ssh_find_options(); |
| 130 | url_proxy_options(); |
| 131 | if( g.argc < 4 ){ |
| 132 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 133 |
+3
-8
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -62,16 +62,10 @@ | ||
| 62 | 62 | /* Password failure while doing a sync from the command-line interface */ |
| 63 | 63 | url_prompt_for_password(); |
| 64 | 64 | zPw = g.urlPasswd; |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | - /* If the first character of the password is "#", then that character is | |
| 68 | - ** not really part of the password - it is an indicator that we should | |
| 69 | - ** use Basic Authentication. So skip that character. | |
| 70 | - */ | |
| 71 | - if( zPw && zPw[0]=='#' ) zPw++; | |
| 72 | - | |
| 73 | 67 | /* The login card wants the SHA1 hash of the password, so convert the |
| 74 | 68 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 75 | 69 | */ |
| 76 | 70 | /* fossil_print("\nzPw=[%s]\n", zPw); // TESTING ONLY */ |
| 77 | 71 | if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0); |
| @@ -90,10 +84,11 @@ | ||
| 90 | 84 | ** the complete payload (including the login card) already compressed. |
| 91 | 85 | */ |
| 92 | 86 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 93 | 87 | int i; |
| 94 | 88 | const char *zSep; |
| 89 | + const int fUseHttpAuth = db_get_boolean("use-http-auth", 0); | |
| 95 | 90 | |
| 96 | 91 | blob_zero(pHdr); |
| 97 | 92 | i = strlen(g.urlPath); |
| 98 | 93 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 99 | 94 | zSep = ""; |
| @@ -102,12 +97,12 @@ | ||
| 102 | 97 | } |
| 103 | 98 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 104 | 99 | if( g.urlProxyAuth ){ |
| 105 | 100 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 106 | 101 | } |
| 107 | - if( g.urlPasswd && g.urlUser && g.urlPasswd[0]=='#' ){ | |
| 108 | - char *zCredentials = mprintf("%s:%s", g.urlUser, &g.urlPasswd[1]); | |
| 102 | + if( g.urlPasswd && g.urlUser && fUseHttpAuth ){ | |
| 103 | + char *zCredentials = mprintf("%s:%s", g.urlUser, g.urlPasswd); | |
| 109 | 104 | char *zEncoded = encode64(zCredentials, -1); |
| 110 | 105 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 111 | 106 | fossil_free(zEncoded); |
| 112 | 107 | fossil_free(zCredentials); |
| 113 | 108 | } |
| 114 | 109 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -62,16 +62,10 @@ | |
| 62 | /* Password failure while doing a sync from the command-line interface */ |
| 63 | url_prompt_for_password(); |
| 64 | zPw = g.urlPasswd; |
| 65 | } |
| 66 | |
| 67 | /* If the first character of the password is "#", then that character is |
| 68 | ** not really part of the password - it is an indicator that we should |
| 69 | ** use Basic Authentication. So skip that character. |
| 70 | */ |
| 71 | if( zPw && zPw[0]=='#' ) zPw++; |
| 72 | |
| 73 | /* The login card wants the SHA1 hash of the password, so convert the |
| 74 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 75 | */ |
| 76 | /* fossil_print("\nzPw=[%s]\n", zPw); // TESTING ONLY */ |
| 77 | if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0); |
| @@ -90,10 +84,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 = ""; |
| @@ -102,12 +97,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 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -62,16 +62,10 @@ | |
| 62 | /* Password failure while doing a sync from the command-line interface */ |
| 63 | url_prompt_for_password(); |
| 64 | zPw = g.urlPasswd; |
| 65 | } |
| 66 | |
| 67 | /* The login card wants the SHA1 hash of the password, so convert the |
| 68 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 69 | */ |
| 70 | /* fossil_print("\nzPw=[%s]\n", zPw); // TESTING ONLY */ |
| 71 | if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0); |
| @@ -90,10 +84,11 @@ | |
| 84 | ** the complete payload (including the login card) already compressed. |
| 85 | */ |
| 86 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 87 | int i; |
| 88 | const char *zSep; |
| 89 | const int fUseHttpAuth = db_get_boolean("use-http-auth", 0); |
| 90 | |
| 91 | blob_zero(pHdr); |
| 92 | i = strlen(g.urlPath); |
| 93 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 94 | zSep = ""; |
| @@ -102,12 +97,12 @@ | |
| 97 | } |
| 98 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 99 | if( g.urlProxyAuth ){ |
| 100 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 101 | } |
| 102 | if( g.urlPasswd && g.urlUser && fUseHttpAuth ){ |
| 103 | char *zCredentials = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 104 | char *zEncoded = encode64(zCredentials, -1); |
| 105 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 106 | fossil_free(zEncoded); |
| 107 | fossil_free(zCredentials); |
| 108 | } |
| 109 |
+1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -139,10 +139,11 @@ | ||
| 139 | 139 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 140 | 140 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 141 | 141 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 142 | 142 | int fQuiet; /* True if -quiet flag is present */ |
| 143 | 143 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 144 | + int fUseHttpAuth; /* Use HTTP Basic Authentication in requests */ | |
| 144 | 145 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 145 | 146 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 146 | 147 | int fSshClient; /* HTTP client flags for SSH client */ |
| 147 | 148 | char *zSshCmd; /* SSH command string */ |
| 148 | 149 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 149 | 150 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -139,10 +139,11 @@ | |
| 139 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 140 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 141 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 142 | int fQuiet; /* True if -quiet flag is present */ |
| 143 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 144 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 145 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 146 | int fSshClient; /* HTTP client flags for SSH client */ |
| 147 | char *zSshCmd; /* SSH command string */ |
| 148 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 149 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -139,10 +139,11 @@ | |
| 139 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 140 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 141 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 142 | int fQuiet; /* True if -quiet flag is present */ |
| 143 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 144 | int fUseHttpAuth; /* Use HTTP Basic Authentication in requests */ |
| 145 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 146 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 147 | int fSshClient; /* HTTP client flags for SSH client */ |
| 148 | char *zSshCmd; /* SSH command string */ |
| 149 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 150 |
+1
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -94,10 +94,11 @@ | ||
| 94 | 94 | } |
| 95 | 95 | if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER; |
| 96 | 96 | if( find_option("private",0,0)!=0 ){ |
| 97 | 97 | *pSyncFlags |= SYNC_PRIVATE; |
| 98 | 98 | } |
| 99 | + g.fUseHttpAuth = find_option("httpauth",0,0)!=0; | |
| 99 | 100 | if( find_option("verbose","v",0)!=0 ){ |
| 100 | 101 | *pSyncFlags |= SYNC_VERBOSE; |
| 101 | 102 | } |
| 102 | 103 | /* The --verily option to sync, push, and pull forces extra igot cards |
| 103 | 104 | ** to be exchanged. This can overcome malfunctions in the sync protocol. |
| 104 | 105 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -94,10 +94,11 @@ | |
| 94 | } |
| 95 | if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER; |
| 96 | if( find_option("private",0,0)!=0 ){ |
| 97 | *pSyncFlags |= SYNC_PRIVATE; |
| 98 | } |
| 99 | if( find_option("verbose","v",0)!=0 ){ |
| 100 | *pSyncFlags |= SYNC_VERBOSE; |
| 101 | } |
| 102 | /* The --verily option to sync, push, and pull forces extra igot cards |
| 103 | ** to be exchanged. This can overcome malfunctions in the sync protocol. |
| 104 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -94,10 +94,11 @@ | |
| 94 | } |
| 95 | if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER; |
| 96 | if( find_option("private",0,0)!=0 ){ |
| 97 | *pSyncFlags |= SYNC_PRIVATE; |
| 98 | } |
| 99 | g.fUseHttpAuth = find_option("httpauth",0,0)!=0; |
| 100 | if( find_option("verbose","v",0)!=0 ){ |
| 101 | *pSyncFlags |= SYNC_VERBOSE; |
| 102 | } |
| 103 | /* The --verily option to sync, push, and pull forces extra igot cards |
| 104 | ** to be exchanged. This can overcome malfunctions in the sync protocol. |
| 105 |
+6
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -104,10 +104,11 @@ | ||
| 104 | 104 | int i, j, c; |
| 105 | 105 | char *zFile = 0; |
| 106 | 106 | |
| 107 | 107 | if( zUrl==0 ){ |
| 108 | 108 | zUrl = db_get("last-sync-url", 0); |
| 109 | + g.fUseHttpAuth = db_get_boolean("use-http-auth", 0); | |
| 109 | 110 | if( zUrl==0 ) return; |
| 110 | 111 | if( pUrlData->passwd==0 ){ |
| 111 | 112 | pUrlData->passwd = unobscure(db_get("last-sync-pw", 0)); |
| 112 | 113 | } |
| 113 | 114 | } |
| @@ -534,10 +535,15 @@ | ||
| 534 | 535 | if( g.urlFlags & URL_REMEMBER ){ |
| 535 | 536 | db_set("last-sync-url", g.urlCanonical, 0); |
| 536 | 537 | if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 537 | 538 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 538 | 539 | } |
| 540 | + if( g.fUseHttpAuth ){ | |
| 541 | + db_set_int("use-http-auth", 1, 0); | |
| 542 | + }else{ | |
| 543 | + db_unset("use-http-auth", 0); | |
| 544 | + } | |
| 539 | 545 | } |
| 540 | 546 | } |
| 541 | 547 | |
| 542 | 548 | /* Preemptively prompt for a password if a username is given in the |
| 543 | 549 | ** URL but no password. |
| 544 | 550 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -104,10 +104,11 @@ | |
| 104 | int i, j, c; |
| 105 | char *zFile = 0; |
| 106 | |
| 107 | if( zUrl==0 ){ |
| 108 | zUrl = db_get("last-sync-url", 0); |
| 109 | if( zUrl==0 ) return; |
| 110 | if( pUrlData->passwd==0 ){ |
| 111 | pUrlData->passwd = unobscure(db_get("last-sync-pw", 0)); |
| 112 | } |
| 113 | } |
| @@ -534,10 +535,15 @@ | |
| 534 | if( g.urlFlags & URL_REMEMBER ){ |
| 535 | db_set("last-sync-url", g.urlCanonical, 0); |
| 536 | if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 537 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | /* Preemptively prompt for a password if a username is given in the |
| 543 | ** URL but no password. |
| 544 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -104,10 +104,11 @@ | |
| 104 | int i, j, c; |
| 105 | char *zFile = 0; |
| 106 | |
| 107 | if( zUrl==0 ){ |
| 108 | zUrl = db_get("last-sync-url", 0); |
| 109 | g.fUseHttpAuth = db_get_boolean("use-http-auth", 0); |
| 110 | if( zUrl==0 ) return; |
| 111 | if( pUrlData->passwd==0 ){ |
| 112 | pUrlData->passwd = unobscure(db_get("last-sync-pw", 0)); |
| 113 | } |
| 114 | } |
| @@ -534,10 +535,15 @@ | |
| 535 | if( g.urlFlags & URL_REMEMBER ){ |
| 536 | db_set("last-sync-url", g.urlCanonical, 0); |
| 537 | if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 538 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 539 | } |
| 540 | if( g.fUseHttpAuth ){ |
| 541 | db_set_int("use-http-auth", 1, 0); |
| 542 | }else{ |
| 543 | db_unset("use-http-auth", 0); |
| 544 | } |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | /* Preemptively prompt for a password if a username is given in the |
| 549 | ** URL but no password. |
| 550 |