Fossil SCM

Add support for HTTP Basic Authentication to clone and sync.

drh 2014-03-13 12:23 trunk merge
Commit 5d536c51b6b977af612c35eb881c8fc332c8db3f
+51
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
109109
** --admin-user|-A USERNAME Make USERNAME the administrator
110110
** --once Don't save url.
111111
** --private Also clone private branches
112112
** --ssl-identity=filename Use the SSL identity if requested by the server
113113
** --ssh-command|-c 'command' Use this SSH command
114
+** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
114115
**
115116
** See also: init
116117
*/
117118
void clone_cmd(void){
118119
char *zPassword;
119120
const char *zDefaultUser; /* Optional name of the default user */
121
+ const char *zHttpAuth; /* HTTP Authorization user:pass information */
120122
int nErr = 0;
121123
int bPrivate = 0; /* Also clone private branches */
122124
int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
123125
124126
if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125127
if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
128
+ zHttpAuth = find_option("httpauth","B",1);
126129
zDefaultUser = find_option("admin-user","A",1);
127130
clone_ssh_find_options();
128131
url_proxy_options();
129132
if( g.argc < 4 ){
130133
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
@@ -159,10 +162,11 @@
159162
db_initial_setup(0, 0, zDefaultUser, 0);
160163
user_select();
161164
db_set("content-schema", CONTENT_SCHEMA, 0);
162165
db_set("aux-schema", AUX_SCHEMA, 0);
163166
db_set("rebuilt", get_version(), 0);
167
+ remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
164168
url_remember();
165169
if( g.zSSLIdentity!=0 ){
166170
/* If the --ssl-identity option was specified, store it as a setting */
167171
Blob fn;
168172
blob_zero(&fn);
@@ -195,10 +199,57 @@
195199
fossil_print("project-id: %s\n", db_get("project-code", 0));
196200
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
197201
fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
198202
db_end_transaction(0);
199203
}
204
+
205
+/*
206
+** If user chooses to use HTTP Authentication over unencrypted HTTP,
207
+** remember decision. Otherwise, if the URL is being changed and no
208
+** preference has been indicated, err on the safe side and revert the
209
+** decision. Set the global preference if the URL is not being changed.
210
+*/
211
+void remember_or_get_http_auth(
212
+ const char *zHttpAuth, /* Credentials in the form "user:password" */
213
+ int fRemember, /* True to remember credentials for later reuse */
214
+ const char *zUrl /* URL for which these credentials apply */
215
+){
216
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
217
+ if( zHttpAuth && zHttpAuth[0] ){
218
+ g.zHttpAuth = mprintf("%s", zHttpAuth);
219
+ }
220
+ if( fRemember ){
221
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
222
+ set_httpauth(g.zHttpAuth);
223
+ }else if( zUrl && zUrl[0] ){
224
+ db_unset(zKey, 0);
225
+ }else{
226
+ g.zHttpAuth = get_httpauth();
227
+ }
228
+ }else if( g.zHttpAuth==0 && zUrl==0 ){
229
+ g.zHttpAuth = get_httpauth();
230
+ }
231
+ free(zKey);
232
+}
233
+
234
+/*
235
+** Get the HTTP Authorization preference from db.
236
+*/
237
+char *get_httpauth(void){
238
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
239
+ return unobscure(db_get(zKey, 0));
240
+ free(zKey);
241
+}
242
+
243
+/*
244
+** Set the HTTP Authorization preference in db.
245
+*/
246
+void set_httpauth(const char *zHttpAuth){
247
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
248
+ db_set(zKey, obscure(zHttpAuth), 0);
249
+ free(zKey);
250
+}
200251
201252
/*
202253
** Look for SSH clone command line options and setup in globals.
203254
*/
204255
void clone_ssh_find_options(void){
205256
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
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;
119 const char *zDefaultUser; /* Optional name of the default user */
 
120 int nErr = 0;
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");
@@ -159,10 +162,11 @@
159 db_initial_setup(0, 0, zDefaultUser, 0);
160 user_select();
161 db_set("content-schema", CONTENT_SCHEMA, 0);
162 db_set("aux-schema", AUX_SCHEMA, 0);
163 db_set("rebuilt", get_version(), 0);
 
164 url_remember();
165 if( g.zSSLIdentity!=0 ){
166 /* If the --ssl-identity option was specified, store it as a setting */
167 Blob fn;
168 blob_zero(&fn);
@@ -195,10 +199,57 @@
195 fossil_print("project-id: %s\n", db_get("project-code", 0));
196 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
197 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
198 db_end_transaction(0);
199 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
201 /*
202 ** Look for SSH clone command line options and setup in globals.
203 */
204 void clone_ssh_find_options(void){
205
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
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|-B 'user:pass' Add HTTP Basic Authorization to requests
115 **
116 ** See also: init
117 */
118 void clone_cmd(void){
119 char *zPassword;
120 const char *zDefaultUser; /* Optional name of the default user */
121 const char *zHttpAuth; /* HTTP Authorization user:pass information */
122 int nErr = 0;
123 int bPrivate = 0; /* Also clone private branches */
124 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
125
126 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
127 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
128 zHttpAuth = find_option("httpauth","B",1);
129 zDefaultUser = find_option("admin-user","A",1);
130 clone_ssh_find_options();
131 url_proxy_options();
132 if( g.argc < 4 ){
133 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
@@ -159,10 +162,11 @@
162 db_initial_setup(0, 0, zDefaultUser, 0);
163 user_select();
164 db_set("content-schema", CONTENT_SCHEMA, 0);
165 db_set("aux-schema", AUX_SCHEMA, 0);
166 db_set("rebuilt", get_version(), 0);
167 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
168 url_remember();
169 if( g.zSSLIdentity!=0 ){
170 /* If the --ssl-identity option was specified, store it as a setting */
171 Blob fn;
172 blob_zero(&fn);
@@ -195,10 +199,57 @@
199 fossil_print("project-id: %s\n", db_get("project-code", 0));
200 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
201 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
202 db_end_transaction(0);
203 }
204
205 /*
206 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
207 ** remember decision. Otherwise, if the URL is being changed and no
208 ** preference has been indicated, err on the safe side and revert the
209 ** decision. Set the global preference if the URL is not being changed.
210 */
211 void remember_or_get_http_auth(
212 const char *zHttpAuth, /* Credentials in the form "user:password" */
213 int fRemember, /* True to remember credentials for later reuse */
214 const char *zUrl /* URL for which these credentials apply */
215 ){
216 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
217 if( zHttpAuth && zHttpAuth[0] ){
218 g.zHttpAuth = mprintf("%s", zHttpAuth);
219 }
220 if( fRemember ){
221 if( g.zHttpAuth && g.zHttpAuth[0] ){
222 set_httpauth(g.zHttpAuth);
223 }else if( zUrl && zUrl[0] ){
224 db_unset(zKey, 0);
225 }else{
226 g.zHttpAuth = get_httpauth();
227 }
228 }else if( g.zHttpAuth==0 && zUrl==0 ){
229 g.zHttpAuth = get_httpauth();
230 }
231 free(zKey);
232 }
233
234 /*
235 ** Get the HTTP Authorization preference from db.
236 */
237 char *get_httpauth(void){
238 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
239 return unobscure(db_get(zKey, 0));
240 free(zKey);
241 }
242
243 /*
244 ** Set the HTTP Authorization preference in db.
245 */
246 void set_httpauth(const char *zHttpAuth){
247 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
248 db_set(zKey, obscure(zHttpAuth), 0);
249 free(zKey);
250 }
251
252 /*
253 ** Look for SSH clone command line options and setup in globals.
254 */
255 void clone_ssh_find_options(void){
256
+51
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
109109
** --admin-user|-A USERNAME Make USERNAME the administrator
110110
** --once Don't save url.
111111
** --private Also clone private branches
112112
** --ssl-identity=filename Use the SSL identity if requested by the server
113113
** --ssh-command|-c 'command' Use this SSH command
114
+** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
114115
**
115116
** See also: init
116117
*/
117118
void clone_cmd(void){
118119
char *zPassword;
119120
const char *zDefaultUser; /* Optional name of the default user */
121
+ const char *zHttpAuth; /* HTTP Authorization user:pass information */
120122
int nErr = 0;
121123
int bPrivate = 0; /* Also clone private branches */
122124
int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
123125
124126
if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125127
if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
128
+ zHttpAuth = find_option("httpauth","B",1);
126129
zDefaultUser = find_option("admin-user","A",1);
127130
clone_ssh_find_options();
128131
url_proxy_options();
129132
if( g.argc < 4 ){
130133
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
@@ -159,10 +162,11 @@
159162
db_initial_setup(0, 0, zDefaultUser, 0);
160163
user_select();
161164
db_set("content-schema", CONTENT_SCHEMA, 0);
162165
db_set("aux-schema", AUX_SCHEMA, 0);
163166
db_set("rebuilt", get_version(), 0);
167
+ remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
164168
url_remember();
165169
if( g.zSSLIdentity!=0 ){
166170
/* If the --ssl-identity option was specified, store it as a setting */
167171
Blob fn;
168172
blob_zero(&fn);
@@ -195,10 +199,57 @@
195199
fossil_print("project-id: %s\n", db_get("project-code", 0));
196200
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
197201
fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
198202
db_end_transaction(0);
199203
}
204
+
205
+/*
206
+** If user chooses to use HTTP Authentication over unencrypted HTTP,
207
+** remember decision. Otherwise, if the URL is being changed and no
208
+** preference has been indicated, err on the safe side and revert the
209
+** decision. Set the global preference if the URL is not being changed.
210
+*/
211
+void remember_or_get_http_auth(
212
+ const char *zHttpAuth, /* Credentials in the form "user:password" */
213
+ int fRemember, /* True to remember credentials for later reuse */
214
+ const char *zUrl /* URL for which these credentials apply */
215
+){
216
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
217
+ if( zHttpAuth && zHttpAuth[0] ){
218
+ g.zHttpAuth = mprintf("%s", zHttpAuth);
219
+ }
220
+ if( fRemember ){
221
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
222
+ set_httpauth(g.zHttpAuth);
223
+ }else if( zUrl && zUrl[0] ){
224
+ db_unset(zKey, 0);
225
+ }else{
226
+ g.zHttpAuth = get_httpauth();
227
+ }
228
+ }else if( g.zHttpAuth==0 && zUrl==0 ){
229
+ g.zHttpAuth = get_httpauth();
230
+ }
231
+ free(zKey);
232
+}
233
+
234
+/*
235
+** Get the HTTP Authorization preference from db.
236
+*/
237
+char *get_httpauth(void){
238
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
239
+ return unobscure(db_get(zKey, 0));
240
+ free(zKey);
241
+}
242
+
243
+/*
244
+** Set the HTTP Authorization preference in db.
245
+*/
246
+void set_httpauth(const char *zHttpAuth){
247
+ char *zKey = mprintf("http-auth:%s", g.urlCanonical);
248
+ db_set(zKey, obscure(zHttpAuth), 0);
249
+ free(zKey);
250
+}
200251
201252
/*
202253
** Look for SSH clone command line options and setup in globals.
203254
*/
204255
void clone_ssh_find_options(void){
205256
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
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;
119 const char *zDefaultUser; /* Optional name of the default user */
 
120 int nErr = 0;
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");
@@ -159,10 +162,11 @@
159 db_initial_setup(0, 0, zDefaultUser, 0);
160 user_select();
161 db_set("content-schema", CONTENT_SCHEMA, 0);
162 db_set("aux-schema", AUX_SCHEMA, 0);
163 db_set("rebuilt", get_version(), 0);
 
164 url_remember();
165 if( g.zSSLIdentity!=0 ){
166 /* If the --ssl-identity option was specified, store it as a setting */
167 Blob fn;
168 blob_zero(&fn);
@@ -195,10 +199,57 @@
195 fossil_print("project-id: %s\n", db_get("project-code", 0));
196 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
197 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
198 db_end_transaction(0);
199 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
201 /*
202 ** Look for SSH clone command line options and setup in globals.
203 */
204 void clone_ssh_find_options(void){
205
--- src/clone.c
+++ src/clone.c
@@ -109,22 +109,25 @@
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|-B 'user:pass' Add HTTP Basic Authorization to requests
115 **
116 ** See also: init
117 */
118 void clone_cmd(void){
119 char *zPassword;
120 const char *zDefaultUser; /* Optional name of the default user */
121 const char *zHttpAuth; /* HTTP Authorization user:pass information */
122 int nErr = 0;
123 int bPrivate = 0; /* Also clone private branches */
124 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
125
126 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
127 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
128 zHttpAuth = find_option("httpauth","B",1);
129 zDefaultUser = find_option("admin-user","A",1);
130 clone_ssh_find_options();
131 url_proxy_options();
132 if( g.argc < 4 ){
133 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
@@ -159,10 +162,11 @@
162 db_initial_setup(0, 0, zDefaultUser, 0);
163 user_select();
164 db_set("content-schema", CONTENT_SCHEMA, 0);
165 db_set("aux-schema", AUX_SCHEMA, 0);
166 db_set("rebuilt", get_version(), 0);
167 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
168 url_remember();
169 if( g.zSSLIdentity!=0 ){
170 /* If the --ssl-identity option was specified, store it as a setting */
171 Blob fn;
172 blob_zero(&fn);
@@ -195,10 +199,57 @@
199 fossil_print("project-id: %s\n", db_get("project-code", 0));
200 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
201 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
202 db_end_transaction(0);
203 }
204
205 /*
206 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
207 ** remember decision. Otherwise, if the URL is being changed and no
208 ** preference has been indicated, err on the safe side and revert the
209 ** decision. Set the global preference if the URL is not being changed.
210 */
211 void remember_or_get_http_auth(
212 const char *zHttpAuth, /* Credentials in the form "user:password" */
213 int fRemember, /* True to remember credentials for later reuse */
214 const char *zUrl /* URL for which these credentials apply */
215 ){
216 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
217 if( zHttpAuth && zHttpAuth[0] ){
218 g.zHttpAuth = mprintf("%s", zHttpAuth);
219 }
220 if( fRemember ){
221 if( g.zHttpAuth && g.zHttpAuth[0] ){
222 set_httpauth(g.zHttpAuth);
223 }else if( zUrl && zUrl[0] ){
224 db_unset(zKey, 0);
225 }else{
226 g.zHttpAuth = get_httpauth();
227 }
228 }else if( g.zHttpAuth==0 && zUrl==0 ){
229 g.zHttpAuth = get_httpauth();
230 }
231 free(zKey);
232 }
233
234 /*
235 ** Get the HTTP Authorization preference from db.
236 */
237 char *get_httpauth(void){
238 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
239 return unobscure(db_get(zKey, 0));
240 free(zKey);
241 }
242
243 /*
244 ** Set the HTTP Authorization preference in db.
245 */
246 void set_httpauth(const char *zHttpAuth){
247 char *zKey = mprintf("http-auth:%s", g.urlCanonical);
248 db_set(zKey, obscure(zHttpAuth), 0);
249 free(zKey);
250 }
251
252 /*
253 ** Look for SSH clone command line options and setup in globals.
254 */
255 void clone_ssh_find_options(void){
256
+92 -9
--- src/http.c
+++ src/http.c
@@ -19,10 +19,26 @@
1919
*/
2020
#include "config.h"
2121
#include "http.h"
2222
#include <assert.h>
2323
24
+#ifdef _WIN32
25
+#include <io.h>
26
+#ifndef isatty
27
+#define isatty(d) _isatty(d)
28
+#endif
29
+#ifndef fileno
30
+#define fileno(s) _fileno(s)
31
+#endif
32
+#endif
33
+
34
+/* Maximum number of HTTP Authorization attempts */
35
+#define MAX_HTTP_AUTH 2
36
+
37
+/* Keep track of HTTP Basic Authorization failures */
38
+static int fSeenHttpAuth = 0;
39
+
2440
/*
2541
** Construct the "login" card with the client credentials.
2642
**
2743
** login LOGIN NONCE SIGNATURE
2844
**
@@ -62,16 +78,10 @@
6278
/* Password failure while doing a sync from the command-line interface */
6379
url_prompt_for_password();
6480
zPw = g.urlPasswd;
6581
}
6682
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
-
7383
/* The login card wants the SHA1 hash of the password, so convert the
7484
** password to its SHA1 hash it it isn't already a SHA1 hash.
7585
*/
7686
/* fossil_print("\nzPw=[%s]\n", zPw); // TESTING ONLY */
7787
if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0);
@@ -102,16 +112,15 @@
102112
}
103113
blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
104114
if( g.urlProxyAuth ){
105115
blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
106116
}
107
- if( g.urlPasswd && g.urlUser && g.urlPasswd[0]=='#' ){
108
- char *zCredentials = mprintf("%s:%s", g.urlUser, &g.urlPasswd[1]);
117
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
118
+ const char *zCredentials = g.zHttpAuth;
109119
char *zEncoded = encode64(zCredentials, -1);
110120
blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
111121
fossil_free(zEncoded);
112
- fossil_free(zCredentials);
113122
}
114123
blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
115124
blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
116125
if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
117126
if( g.fHttpTrace ){
@@ -119,10 +128,71 @@
119128
}else{
120129
blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
121130
}
122131
blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
123132
}
133
+
134
+/*
135
+** Use Fossil credentials for HTTP Basic Authorization prompt
136
+*/
137
+static int use_fossil_creds_for_httpauth_prompt(void){
138
+ Blob x;
139
+ char c;
140
+ prompt_user("Use Fossil username and password (y/N)? ", &x);
141
+ c = blob_str(&x)[0];
142
+ blob_reset(&x);
143
+ return ( c=='y' || c=='Y' );
144
+}
145
+
146
+/*
147
+** Prompt to save HTTP Basic Authorization information
148
+*/
149
+static int save_httpauth_prompt(void){
150
+ Blob x;
151
+ char c;
152
+ if( (g.urlFlags & URL_REMEMBER)==0 ) return;
153
+ prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x);
154
+ c = blob_str(&x)[0];
155
+ blob_reset(&x);
156
+ return ( c!='n' && c!='N' );
157
+}
158
+
159
+/*
160
+** Get the HTTP Basic Authorization credentials from the user
161
+** when 401 is received.
162
+*/
163
+char *prompt_for_httpauth_creds(void){
164
+ Blob x;
165
+ char *zUser;
166
+ char *zPw;
167
+ char *zPrompt;
168
+ char *zHttpAuth = 0;
169
+ if( !isatty(fileno(stdin)) ) return 0;
170
+ zPrompt = mprintf("\n%s authorization required by\n%s\n",
171
+ g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical);
172
+ fossil_print(zPrompt);
173
+ free(zPrompt);
174
+ if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){
175
+ zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd);
176
+ }else{
177
+ prompt_user("Basic Authorization user: ", &x);
178
+ zUser = mprintf("%b", &x);
179
+ zPrompt = mprintf("HTTP password for %b: ", &x);
180
+ blob_reset(&x);
181
+ prompt_for_password(zPrompt, &x, 1);
182
+ zPw = mprintf("%b", &x);
183
+ zHttpAuth = mprintf("%s:%s", zUser, zPw);
184
+ free(zUser);
185
+ free(zPw);
186
+ free(zPrompt);
187
+ blob_reset(&x);
188
+ }
189
+ if( save_httpauth_prompt() ){
190
+ set_httpauth(zHttpAuth);
191
+ }
192
+ return zHttpAuth;
193
+}
124194
125195
/*
126196
** Sign the content in pSend, compress it, and send it to the server
127197
** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
128198
** in pRecv. pRecv is assumed to be uninitialized when
@@ -205,10 +275,20 @@
205275
iLength = -1;
206276
while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
207277
/* printf("[%s]\n", zLine); fflush(stdout); */
208278
if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
209279
if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
280
+ if( rc==401 ){
281
+ if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){
282
+ if( g.zHttpAuth ){
283
+ if( g.zHttpAuth ) free(g.zHttpAuth);
284
+ }
285
+ g.zHttpAuth = prompt_for_httpauth_creds();
286
+ transport_close(GLOBAL_URL());
287
+ return http_exchange(pSend, pReply, useLogin, maxRedirect);
288
+ }
289
+ }
210290
if( rc!=200 && rc!=302 ){
211291
int ii;
212292
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
213293
while( zLine[ii]==' ' ) ii++;
214294
fossil_warning("server says: %s", &zLine[ii]);
@@ -254,10 +334,13 @@
254334
j -= 4;
255335
zLine[j] = 0;
256336
}
257337
fossil_print("redirect to %s\n", &zLine[i]);
258338
url_parse(&zLine[i], 0);
339
+ fSeenHttpAuth = 0;
340
+ if( g.zHttpAuth ) free(g.zHttpAuth);
341
+ g.zHttpAuth = get_httpauth();
259342
transport_close(GLOBAL_URL());
260343
return http_exchange(pSend, pReply, useLogin, maxRedirect);
261344
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
262345
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
263346
isCompressed = 0;
264347
--- src/http.c
+++ src/http.c
@@ -19,10 +19,26 @@
19 */
20 #include "config.h"
21 #include "http.h"
22 #include <assert.h>
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24 /*
25 ** Construct the "login" card with the client credentials.
26 **
27 ** login LOGIN NONCE SIGNATURE
28 **
@@ -62,16 +78,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);
@@ -102,16 +112,15 @@
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 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
115 blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
116 if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
117 if( g.fHttpTrace ){
@@ -119,10 +128,71 @@
119 }else{
120 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
121 }
122 blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
123 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
125 /*
126 ** Sign the content in pSend, compress it, and send it to the server
127 ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
128 ** in pRecv. pRecv is assumed to be uninitialized when
@@ -205,10 +275,20 @@
205 iLength = -1;
206 while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
207 /* printf("[%s]\n", zLine); fflush(stdout); */
208 if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
209 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
 
 
 
 
 
 
 
 
 
 
210 if( rc!=200 && rc!=302 ){
211 int ii;
212 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
213 while( zLine[ii]==' ' ) ii++;
214 fossil_warning("server says: %s", &zLine[ii]);
@@ -254,10 +334,13 @@
254 j -= 4;
255 zLine[j] = 0;
256 }
257 fossil_print("redirect to %s\n", &zLine[i]);
258 url_parse(&zLine[i], 0);
 
 
 
259 transport_close(GLOBAL_URL());
260 return http_exchange(pSend, pReply, useLogin, maxRedirect);
261 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
262 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
263 isCompressed = 0;
264
--- src/http.c
+++ src/http.c
@@ -19,10 +19,26 @@
19 */
20 #include "config.h"
21 #include "http.h"
22 #include <assert.h>
23
24 #ifdef _WIN32
25 #include <io.h>
26 #ifndef isatty
27 #define isatty(d) _isatty(d)
28 #endif
29 #ifndef fileno
30 #define fileno(s) _fileno(s)
31 #endif
32 #endif
33
34 /* Maximum number of HTTP Authorization attempts */
35 #define MAX_HTTP_AUTH 2
36
37 /* Keep track of HTTP Basic Authorization failures */
38 static int fSeenHttpAuth = 0;
39
40 /*
41 ** Construct the "login" card with the client credentials.
42 **
43 ** login LOGIN NONCE SIGNATURE
44 **
@@ -62,16 +78,10 @@
78 /* Password failure while doing a sync from the command-line interface */
79 url_prompt_for_password();
80 zPw = g.urlPasswd;
81 }
82
 
 
 
 
 
 
83 /* The login card wants the SHA1 hash of the password, so convert the
84 ** password to its SHA1 hash it it isn't already a SHA1 hash.
85 */
86 /* fossil_print("\nzPw=[%s]\n", zPw); // TESTING ONLY */
87 if( zPw && zPw[0] ) zPw = sha1_shared_secret(zPw, zLogin, 0);
@@ -102,16 +112,15 @@
112 }
113 blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
114 if( g.urlProxyAuth ){
115 blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
116 }
117 if( g.zHttpAuth && g.zHttpAuth[0] ){
118 const char *zCredentials = g.zHttpAuth;
119 char *zEncoded = encode64(zCredentials, -1);
120 blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
121 fossil_free(zEncoded);
 
122 }
123 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
124 blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
125 if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
126 if( g.fHttpTrace ){
@@ -119,10 +128,71 @@
128 }else{
129 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
130 }
131 blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
132 }
133
134 /*
135 ** Use Fossil credentials for HTTP Basic Authorization prompt
136 */
137 static int use_fossil_creds_for_httpauth_prompt(void){
138 Blob x;
139 char c;
140 prompt_user("Use Fossil username and password (y/N)? ", &x);
141 c = blob_str(&x)[0];
142 blob_reset(&x);
143 return ( c=='y' || c=='Y' );
144 }
145
146 /*
147 ** Prompt to save HTTP Basic Authorization information
148 */
149 static int save_httpauth_prompt(void){
150 Blob x;
151 char c;
152 if( (g.urlFlags & URL_REMEMBER)==0 ) return;
153 prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x);
154 c = blob_str(&x)[0];
155 blob_reset(&x);
156 return ( c!='n' && c!='N' );
157 }
158
159 /*
160 ** Get the HTTP Basic Authorization credentials from the user
161 ** when 401 is received.
162 */
163 char *prompt_for_httpauth_creds(void){
164 Blob x;
165 char *zUser;
166 char *zPw;
167 char *zPrompt;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 zPrompt = mprintf("\n%s authorization required by\n%s\n",
171 g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical);
172 fossil_print(zPrompt);
173 free(zPrompt);
174 if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){
175 zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd);
176 }else{
177 prompt_user("Basic Authorization user: ", &x);
178 zUser = mprintf("%b", &x);
179 zPrompt = mprintf("HTTP password for %b: ", &x);
180 blob_reset(&x);
181 prompt_for_password(zPrompt, &x, 1);
182 zPw = mprintf("%b", &x);
183 zHttpAuth = mprintf("%s:%s", zUser, zPw);
184 free(zUser);
185 free(zPw);
186 free(zPrompt);
187 blob_reset(&x);
188 }
189 if( save_httpauth_prompt() ){
190 set_httpauth(zHttpAuth);
191 }
192 return zHttpAuth;
193 }
194
195 /*
196 ** Sign the content in pSend, compress it, and send it to the server
197 ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
198 ** in pRecv. pRecv is assumed to be uninitialized when
@@ -205,10 +275,20 @@
275 iLength = -1;
276 while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
277 /* printf("[%s]\n", zLine); fflush(stdout); */
278 if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
279 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
280 if( rc==401 ){
281 if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){
282 if( g.zHttpAuth ){
283 if( g.zHttpAuth ) free(g.zHttpAuth);
284 }
285 g.zHttpAuth = prompt_for_httpauth_creds();
286 transport_close(GLOBAL_URL());
287 return http_exchange(pSend, pReply, useLogin, maxRedirect);
288 }
289 }
290 if( rc!=200 && rc!=302 ){
291 int ii;
292 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
293 while( zLine[ii]==' ' ) ii++;
294 fossil_warning("server says: %s", &zLine[ii]);
@@ -254,10 +334,13 @@
334 j -= 4;
335 zLine[j] = 0;
336 }
337 fossil_print("redirect to %s\n", &zLine[i]);
338 url_parse(&zLine[i], 0);
339 fSeenHttpAuth = 0;
340 if( g.zHttpAuth ) free(g.zHttpAuth);
341 g.zHttpAuth = get_httpauth();
342 transport_close(GLOBAL_URL());
343 return http_exchange(pSend, pReply, useLogin, maxRedirect);
344 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
345 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
346 isCompressed = 0;
347
+2
--- src/main.c
+++ src/main.c
@@ -140,10 +140,11 @@
140140
int fSqlTrace; /* True if --sqltrace flag is present */
141141
int fSqlStats; /* True if --sqltrace or --sqlstats are present */
142142
int fSqlPrint; /* True if -sqlprint flag is present */
143143
int fQuiet; /* True if -quiet flag is present */
144144
int fHttpTrace; /* Trace outbound HTTP requests */
145
+ char *zHttpAuth; /* HTTP Authorization user:pass information */
145146
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
146147
int fSshTrace; /* Trace the SSH setup traffic */
147148
int fSshClient; /* HTTP client flags for SSH client */
148149
char *zSshCmd; /* SSH command string */
149150
int fNoSync; /* Do not do an autosync ever. --nosync */
@@ -651,10 +652,11 @@
651652
g.fSshClient = 0;
652653
g.zSshCmd = 0;
653654
if( g.fSqlTrace ) g.fSqlStats = 1;
654655
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
655656
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
657
+ g.zHttpAuth = 0;
656658
g.zLogin = find_option("user", "U", 1);
657659
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
658660
g.zErrlog = find_option("errorlog", 0, 1);
659661
if( find_option("utc",0,0) ) g.fTimeFormat = 1;
660662
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
661663
--- src/main.c
+++ src/main.c
@@ -140,10 +140,11 @@
140 int fSqlTrace; /* True if --sqltrace flag is present */
141 int fSqlStats; /* True if --sqltrace or --sqlstats are present */
142 int fSqlPrint; /* True if -sqlprint flag is present */
143 int fQuiet; /* True if -quiet flag is present */
144 int fHttpTrace; /* Trace outbound HTTP 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 */
@@ -651,10 +652,11 @@
651 g.fSshClient = 0;
652 g.zSshCmd = 0;
653 if( g.fSqlTrace ) g.fSqlStats = 1;
654 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
655 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
 
656 g.zLogin = find_option("user", "U", 1);
657 g.zSSLIdentity = find_option("ssl-identity", 0, 1);
658 g.zErrlog = find_option("errorlog", 0, 1);
659 if( find_option("utc",0,0) ) g.fTimeFormat = 1;
660 if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
661
--- src/main.c
+++ src/main.c
@@ -140,10 +140,11 @@
140 int fSqlTrace; /* True if --sqltrace flag is present */
141 int fSqlStats; /* True if --sqltrace or --sqlstats are present */
142 int fSqlPrint; /* True if -sqlprint flag is present */
143 int fQuiet; /* True if -quiet flag is present */
144 int fHttpTrace; /* Trace outbound HTTP requests */
145 char *zHttpAuth; /* HTTP Authorization user:pass information */
146 int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
147 int fSshTrace; /* Trace the SSH setup traffic */
148 int fSshClient; /* HTTP client flags for SSH client */
149 char *zSshCmd; /* SSH command string */
150 int fNoSync; /* Do not do an autosync ever. --nosync */
@@ -651,10 +652,11 @@
652 g.fSshClient = 0;
653 g.zSshCmd = 0;
654 if( g.fSqlTrace ) g.fSqlStats = 1;
655 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
656 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
657 g.zHttpAuth = 0;
658 g.zLogin = find_option("user", "U", 1);
659 g.zSSLIdentity = find_option("ssl-identity", 0, 1);
660 g.zErrlog = find_option("errorlog", 0, 1);
661 if( find_option("utc",0,0) ) g.fTimeFormat = 1;
662 if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
663
+5
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
5454
if( g.urlUser!=0 && g.urlPasswd==0 ){
5555
g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
5656
g.urlFlags |= URL_PROMPT_PW;
5757
url_prompt_for_password();
5858
}
59
+ g.zHttpAuth = get_httpauth();
5960
url_remember();
6061
#if 0 /* Disabled for now */
6162
if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
6263
/* When doing an automatic pull, also automatically pull shuns from
6364
** the server if pull_shuns is enabled.
@@ -83,17 +84,19 @@
8384
** of a server to sync against. If no argument is given, use the
8485
** most recently synced URL. Remember the current URL for next time.
8586
*/
8687
static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
8788
const char *zUrl = 0;
89
+ const char *zHttpAuth = 0;
8890
unsigned configSync = 0;
8991
unsigned urlFlags = URL_REMEMBER | URL_PROMPT_PW;
9092
int urlOptional = 0;
9193
if( find_option("autourl",0,0)!=0 ){
9294
urlOptional = 1;
9395
urlFlags = 0;
9496
}
97
+ zHttpAuth = find_option("httpauth","B",1);
9598
if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
9699
if( find_option("private",0,0)!=0 ){
97100
*pSyncFlags |= SYNC_PRIVATE;
98101
}
99102
if( find_option("verbose","v",0)!=0 ){
@@ -116,10 +119,11 @@
116119
}
117120
if( urlFlags & URL_REMEMBER ){
118121
clone_ssh_db_set_options();
119122
}
120123
url_parse(zUrl, urlFlags);
124
+ remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
121125
url_remember();
122126
if( g.urlProtocol==0 ){
123127
if( urlOptional ) fossil_exit(0);
124128
usage("URL");
125129
}
@@ -263,10 +267,11 @@
263267
usage("remote-url ?URL|off?");
264268
}
265269
if( g.argc==3 ){
266270
db_unset("last-sync-url", 0);
267271
db_unset("last-sync-pw", 0);
272
+ db_unset("http-auth", 0);
268273
if( is_false(g.argv[2]) ) return;
269274
url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
270275
}
271276
url_remember();
272277
zUrl = db_get("last-sync-url", 0);
273278
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
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 url_remember();
60 #if 0 /* Disabled for now */
61 if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
62 /* When doing an automatic pull, also automatically pull shuns from
63 ** the server if pull_shuns is enabled.
@@ -83,17 +84,19 @@
83 ** of a server to sync against. If no argument is given, use the
84 ** most recently synced URL. Remember the current URL for next time.
85 */
86 static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
87 const char *zUrl = 0;
 
88 unsigned configSync = 0;
89 unsigned urlFlags = URL_REMEMBER | URL_PROMPT_PW;
90 int urlOptional = 0;
91 if( find_option("autourl",0,0)!=0 ){
92 urlOptional = 1;
93 urlFlags = 0;
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 ){
@@ -116,10 +119,11 @@
116 }
117 if( urlFlags & URL_REMEMBER ){
118 clone_ssh_db_set_options();
119 }
120 url_parse(zUrl, urlFlags);
 
121 url_remember();
122 if( g.urlProtocol==0 ){
123 if( urlOptional ) fossil_exit(0);
124 usage("URL");
125 }
@@ -263,10 +267,11 @@
263 usage("remote-url ?URL|off?");
264 }
265 if( g.argc==3 ){
266 db_unset("last-sync-url", 0);
267 db_unset("last-sync-pw", 0);
 
268 if( is_false(g.argv[2]) ) return;
269 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
270 }
271 url_remember();
272 zUrl = db_get("last-sync-url", 0);
273
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
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 g.zHttpAuth = get_httpauth();
60 url_remember();
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.
@@ -83,17 +84,19 @@
84 ** of a server to sync against. If no argument is given, use the
85 ** most recently synced URL. Remember the current URL for next time.
86 */
87 static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
88 const char *zUrl = 0;
89 const char *zHttpAuth = 0;
90 unsigned configSync = 0;
91 unsigned urlFlags = URL_REMEMBER | URL_PROMPT_PW;
92 int urlOptional = 0;
93 if( find_option("autourl",0,0)!=0 ){
94 urlOptional = 1;
95 urlFlags = 0;
96 }
97 zHttpAuth = find_option("httpauth","B",1);
98 if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
99 if( find_option("private",0,0)!=0 ){
100 *pSyncFlags |= SYNC_PRIVATE;
101 }
102 if( find_option("verbose","v",0)!=0 ){
@@ -116,10 +119,11 @@
119 }
120 if( urlFlags & URL_REMEMBER ){
121 clone_ssh_db_set_options();
122 }
123 url_parse(zUrl, urlFlags);
124 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
125 url_remember();
126 if( g.urlProtocol==0 ){
127 if( urlOptional ) fossil_exit(0);
128 usage("URL");
129 }
@@ -263,10 +267,11 @@
267 usage("remote-url ?URL|off?");
268 }
269 if( g.argc==3 ){
270 db_unset("last-sync-url", 0);
271 db_unset("last-sync-pw", 0);
272 db_unset("http-auth", 0);
273 if( is_false(g.argv[2]) ) return;
274 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
275 }
276 url_remember();
277 zUrl = db_get("last-sync-url", 0);
278
+2 -1
--- src/xfer.c
+++ src/xfer.c
@@ -578,11 +578,12 @@
578578
defossilize(zLogin);
579579
580580
if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){
581581
return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */
582582
}
583
- if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){
583
+ if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0
584
+ && db_get_boolean("remote_user_ok",0) ){
584585
return 0; /* Accept Basic Authorization */
585586
}
586587
db_prepare(&q,
587588
"SELECT pw, cap, uid FROM user"
588589
" WHERE login=%Q"
589590
--- src/xfer.c
+++ src/xfer.c
@@ -578,11 +578,12 @@
578 defossilize(zLogin);
579
580 if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){
581 return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */
582 }
583 if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){
 
584 return 0; /* Accept Basic Authorization */
585 }
586 db_prepare(&q,
587 "SELECT pw, cap, uid FROM user"
588 " WHERE login=%Q"
589
--- src/xfer.c
+++ src/xfer.c
@@ -578,11 +578,12 @@
578 defossilize(zLogin);
579
580 if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){
581 return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */
582 }
583 if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0
584 && db_get_boolean("remote_user_ok",0) ){
585 return 0; /* Accept Basic Authorization */
586 }
587 db_prepare(&q,
588 "SELECT pw, cap, uid FROM user"
589 " WHERE login=%Q"
590

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button