Fossil SCM
Enable Basic Authorization during sync operations by prepending a single "#" to the password.
Commit
c1506adbf7a46f7ac4acbaaa69fa2a56319a185e
Parent
b951baa5c90cc54…
2 files changed
+14
-12
+4
+14
-12
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -62,26 +62,21 @@ | ||
| 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 | if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0); |
| 66 | 66 | } |
| 67 | + | |
| 68 | + /* If the first character of the password is "#", then that character is | |
| 69 | + ** not really part of the password - it is an indicator that we should | |
| 70 | + ** use Basic Authentication. So skip that character. | |
| 71 | + */ | |
| 72 | + if( zPw && zPw[0]=='#' ) zPw++; | |
| 67 | 73 | |
| 68 | 74 | /* The login card wants the SHA1 hash of the password, so convert the |
| 69 | 75 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 70 | - ** | |
| 71 | - ** Except, if the password begins with "*" then use the characters | |
| 72 | - ** after the "*" as a cleartext password. Put an "*" at the beginning | |
| 73 | - ** of the password to trick a newer client to use the cleartext password | |
| 74 | - ** protocol required by legacy servers. | |
| 75 | 76 | */ |
| 76 | - if( zPw && zPw[0] ){ | |
| 77 | - if( zPw[0]=='*' ){ | |
| 78 | - zPw++; | |
| 79 | - }else{ | |
| 80 | - zPw = sha1_shared_secret(zPw, zLogin, 0); | |
| 81 | - } | |
| 82 | - } | |
| 77 | + if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0); | |
| 83 | 78 | |
| 84 | 79 | blob_append(&pw, zPw, -1); |
| 85 | 80 | sha1sum_blob(&pw, &sig); |
| 86 | 81 | blob_appendf(pLogin, "login %F %b %b\n", zLogin, &nonce, &sig); |
| 87 | 82 | blob_reset(&pw); |
| @@ -106,10 +101,17 @@ | ||
| 106 | 101 | zSep = "/"; |
| 107 | 102 | } |
| 108 | 103 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 109 | 104 | if( g.urlProxyAuth ){ |
| 110 | 105 | blob_appendf(pHdr, "Proxy-Authorization: %s\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); | |
| 111 | 113 | } |
| 112 | 114 | blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); |
| 113 | 115 | blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n"); |
| 114 | 116 | if( g.fHttpTrace ){ |
| 115 | 117 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 116 | 118 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -62,26 +62,21 @@ | |
| 62 | /* Password failure while doing a sync from the command-line interface */ |
| 63 | url_prompt_for_password(); |
| 64 | zPw = g.urlPasswd; |
| 65 | if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0); |
| 66 | } |
| 67 | |
| 68 | /* The login card wants the SHA1 hash of the password, so convert the |
| 69 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 70 | ** |
| 71 | ** Except, if the password begins with "*" then use the characters |
| 72 | ** after the "*" as a cleartext password. Put an "*" at the beginning |
| 73 | ** of the password to trick a newer client to use the cleartext password |
| 74 | ** protocol required by legacy servers. |
| 75 | */ |
| 76 | if( zPw && zPw[0] ){ |
| 77 | if( zPw[0]=='*' ){ |
| 78 | zPw++; |
| 79 | }else{ |
| 80 | zPw = sha1_shared_secret(zPw, zLogin, 0); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | blob_append(&pw, zPw, -1); |
| 85 | sha1sum_blob(&pw, &sig); |
| 86 | blob_appendf(pLogin, "login %F %b %b\n", zLogin, &nonce, &sig); |
| 87 | blob_reset(&pw); |
| @@ -106,10 +101,17 @@ | |
| 106 | zSep = "/"; |
| 107 | } |
| 108 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 109 | if( g.urlProxyAuth ){ |
| 110 | blob_appendf(pHdr, "Proxy-Authorization: %s\n", g.urlProxyAuth); |
| 111 | } |
| 112 | blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); |
| 113 | blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n"); |
| 114 | if( g.fHttpTrace ){ |
| 115 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 116 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -62,26 +62,21 @@ | |
| 62 | /* Password failure while doing a sync from the command-line interface */ |
| 63 | url_prompt_for_password(); |
| 64 | zPw = g.urlPasswd; |
| 65 | if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0); |
| 66 | } |
| 67 | |
| 68 | /* If the first character of the password is "#", then that character is |
| 69 | ** not really part of the password - it is an indicator that we should |
| 70 | ** use Basic Authentication. So skip that character. |
| 71 | */ |
| 72 | if( zPw && zPw[0]=='#' ) zPw++; |
| 73 | |
| 74 | /* The login card wants the SHA1 hash of the password, so convert the |
| 75 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 76 | */ |
| 77 | if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0); |
| 78 | |
| 79 | blob_append(&pw, zPw, -1); |
| 80 | sha1sum_blob(&pw, &sig); |
| 81 | blob_appendf(pLogin, "login %F %b %b\n", zLogin, &nonce, &sig); |
| 82 | blob_reset(&pw); |
| @@ -106,10 +101,17 @@ | |
| 101 | zSep = "/"; |
| 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\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 | blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); |
| 115 | blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n"); |
| 116 | if( g.fHttpTrace ){ |
| 117 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 118 |
+4
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -552,10 +552,13 @@ | ||
| 552 | 552 | defossilize(zLogin); |
| 553 | 553 | |
| 554 | 554 | if( strcmp(zLogin, "nobody")==0 || strcmp(zLogin,"anonymous")==0 ){ |
| 555 | 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | 556 | } |
| 557 | + if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ | |
| 558 | + return 0; /* Accept Basic Authorization */ | |
| 559 | + } | |
| 557 | 560 | db_prepare(&q, |
| 558 | 561 | "SELECT pw, cap, uid FROM user" |
| 559 | 562 | " WHERE login=%Q" |
| 560 | 563 | " AND login NOT IN ('anonymous','nobody','developer','reader')" |
| 561 | 564 | " AND length(pw)>0", |
| @@ -809,10 +812,11 @@ | ||
| 809 | 812 | if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ |
| 810 | 813 | fossil_redirect_home(); |
| 811 | 814 | } |
| 812 | 815 | g.zLogin = "anonymous"; |
| 813 | 816 | login_set_anon_nobody_capabilities(); |
| 817 | + login_check_credentials(); | |
| 814 | 818 | memset(&xfer, 0, sizeof(xfer)); |
| 815 | 819 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 816 | 820 | cgi_set_content_type(g.zContentType); |
| 817 | 821 | if( db_schema_is_outofdate() ){ |
| 818 | 822 | @ error database\sschema\sis\sout-of-date\son\sthe\sserver. |
| 819 | 823 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -552,10 +552,13 @@ | |
| 552 | defossilize(zLogin); |
| 553 | |
| 554 | if( strcmp(zLogin, "nobody")==0 || strcmp(zLogin,"anonymous")==0 ){ |
| 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | } |
| 557 | db_prepare(&q, |
| 558 | "SELECT pw, cap, uid FROM user" |
| 559 | " WHERE login=%Q" |
| 560 | " AND login NOT IN ('anonymous','nobody','developer','reader')" |
| 561 | " AND length(pw)>0", |
| @@ -809,10 +812,11 @@ | |
| 809 | if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ |
| 810 | fossil_redirect_home(); |
| 811 | } |
| 812 | g.zLogin = "anonymous"; |
| 813 | login_set_anon_nobody_capabilities(); |
| 814 | memset(&xfer, 0, sizeof(xfer)); |
| 815 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 816 | cgi_set_content_type(g.zContentType); |
| 817 | if( db_schema_is_outofdate() ){ |
| 818 | @ error database\sschema\sis\sout-of-date\son\sthe\sserver. |
| 819 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -552,10 +552,13 @@ | |
| 552 | defossilize(zLogin); |
| 553 | |
| 554 | if( strcmp(zLogin, "nobody")==0 || strcmp(zLogin,"anonymous")==0 ){ |
| 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | } |
| 557 | if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ |
| 558 | return 0; /* Accept Basic Authorization */ |
| 559 | } |
| 560 | db_prepare(&q, |
| 561 | "SELECT pw, cap, uid FROM user" |
| 562 | " WHERE login=%Q" |
| 563 | " AND login NOT IN ('anonymous','nobody','developer','reader')" |
| 564 | " AND length(pw)>0", |
| @@ -809,10 +812,11 @@ | |
| 812 | if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ |
| 813 | fossil_redirect_home(); |
| 814 | } |
| 815 | g.zLogin = "anonymous"; |
| 816 | login_set_anon_nobody_capabilities(); |
| 817 | login_check_credentials(); |
| 818 | memset(&xfer, 0, sizeof(xfer)); |
| 819 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 820 | cgi_set_content_type(g.zContentType); |
| 821 | if( db_schema_is_outofdate() ){ |
| 822 | @ error database\sschema\sis\sout-of-date\son\sthe\sserver. |
| 823 |