Fossil SCM

Don't send Basic Authorization except after prompting user. This is done by detecting 401 Authorization Required. It also allows the HTTP Authorization credentials to be different from the Fossil user which means the integrity of the Fossil password can be maintained if so desired.

andybradford 2014-02-03 07:03 http-auth
Commit c61554976dde870c8b5dcbbdead5977a4cb77cd7
4 files changed +14 -10 +96 -14 +2 -1 +3 -2
+14 -10
--- src/clone.c
+++ src/clone.c
@@ -109,24 +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 Add HTTP Basic Authorization to requests
114
+** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
115115
**
116116
** See also: init
117117
*/
118118
void clone_cmd(void){
119119
char *zPassword;
120120
const char *zDefaultUser; /* Optional name of the default user */
121
+ const char *zHttpAuth; /* HTTP Authorization user:pass information */
121122
int nErr = 0;
122123
int bPrivate = 0; /* Also clone private branches */
123124
int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
124125
125126
if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
126127
if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
127
- g.fUseHttpAuth = find_option("httpauth","B",0)!=0;
128
+ zHttpAuth = find_option("httpauth","B",1);
128129
zDefaultUser = find_option("admin-user","A",1);
129130
clone_ssh_find_options();
130131
url_proxy_options();
131132
if( g.argc < 4 ){
132133
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
@@ -161,11 +162,11 @@
161162
db_initial_setup(0, 0, zDefaultUser, 0);
162163
user_select();
163164
db_set("content-schema", CONTENT_SCHEMA, 0);
164165
db_set("aux-schema", AUX_SCHEMA, 0);
165166
db_set("rebuilt", get_version(), 0);
166
- remember_or_get_http_auth(urlFlags & URL_REMEMBER, g.argv[2]);
167
+ remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
167168
url_remember();
168169
if( g.zSSLIdentity!=0 ){
169170
/* If the --ssl-identity option was specified, store it as a setting */
170171
Blob fn;
171172
blob_zero(&fn);
@@ -205,21 +206,24 @@
205206
** If user chooses to use HTTP Authentication over unencrypted HTTP,
206207
** remember decision. Otherwise, if the URL is being changed and no preference
207208
** has been indicated, err on the safe side and revert the decision.
208209
** Set the global preference if the URL is not being changed.
209210
*/
210
-void remember_or_get_http_auth(int fRemember, const char *zUrl){
211
+void remember_or_get_http_auth(const char *zHttpAuth, int fRemember, const char *zUrl){
212
+ if( zHttpAuth && zHttpAuth[0] ){
213
+ g.zHttpAuth = mprintf("%s", zHttpAuth);
214
+ }
211215
if( fRemember ){
212
- if( g.fUseHttpAuth==1 ){
213
- db_set_int("use-http-auth", 1, 0);
216
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
217
+ db_set("http-auth", obscure(g.zHttpAuth), 0);
214218
}else if( zUrl && zUrl[0] ){
215
- db_unset("use-http-auth", 0);
219
+ db_unset("http-auth", 0);
216220
}else{
217
- g.fUseHttpAuth = db_get_boolean("use-http-auth",0)!=0;
221
+ g.zHttpAuth = unobscure(db_get("http-auth",0));
218222
}
219
- }else if( g.fUseHttpAuth==0 && zUrl==0 ){
220
- g.fUseHttpAuth = db_get_boolean("use-http-auth",0)!=0;
223
+ }else if( g.zHttpAuth==0 && zUrl==0 ){
224
+ g.zHttpAuth = unobscure(db_get("http-auth",0));
221225
}
222226
}
223227
224228
/*
225229
** Look for SSH clone command line options and setup in globals.
226230
--- src/clone.c
+++ src/clone.c
@@ -109,24 +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 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 int nErr = 0;
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","B",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");
@@ -161,11 +162,11 @@
161 db_initial_setup(0, 0, zDefaultUser, 0);
162 user_select();
163 db_set("content-schema", CONTENT_SCHEMA, 0);
164 db_set("aux-schema", AUX_SCHEMA, 0);
165 db_set("rebuilt", get_version(), 0);
166 remember_or_get_http_auth(urlFlags & URL_REMEMBER, g.argv[2]);
167 url_remember();
168 if( g.zSSLIdentity!=0 ){
169 /* If the --ssl-identity option was specified, store it as a setting */
170 Blob fn;
171 blob_zero(&fn);
@@ -205,21 +206,24 @@
205 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
206 ** remember decision. Otherwise, if the URL is being changed and no preference
207 ** has been indicated, err on the safe side and revert the decision.
208 ** Set the global preference if the URL is not being changed.
209 */
210 void remember_or_get_http_auth(int fRemember, const char *zUrl){
 
 
 
211 if( fRemember ){
212 if( g.fUseHttpAuth==1 ){
213 db_set_int("use-http-auth", 1, 0);
214 }else if( zUrl && zUrl[0] ){
215 db_unset("use-http-auth", 0);
216 }else{
217 g.fUseHttpAuth = db_get_boolean("use-http-auth",0)!=0;
218 }
219 }else if( g.fUseHttpAuth==0 && zUrl==0 ){
220 g.fUseHttpAuth = db_get_boolean("use-http-auth",0)!=0;
221 }
222 }
223
224 /*
225 ** Look for SSH clone command line options and setup in globals.
226
--- src/clone.c
+++ src/clone.c
@@ -109,24 +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");
@@ -161,11 +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);
@@ -205,21 +206,24 @@
206 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
207 ** remember decision. Otherwise, if the URL is being changed and no preference
208 ** has been indicated, err on the safe side and revert the decision.
209 ** Set the global preference if the URL is not being changed.
210 */
211 void remember_or_get_http_auth(const char *zHttpAuth, int fRemember, const char *zUrl){
212 if( zHttpAuth && zHttpAuth[0] ){
213 g.zHttpAuth = mprintf("%s", zHttpAuth);
214 }
215 if( fRemember ){
216 if( g.zHttpAuth && g.zHttpAuth[0] ){
217 db_set("http-auth", obscure(g.zHttpAuth), 0);
218 }else if( zUrl && zUrl[0] ){
219 db_unset("http-auth", 0);
220 }else{
221 g.zHttpAuth = unobscure(db_get("http-auth",0));
222 }
223 }else if( g.zHttpAuth==0 && zUrl==0 ){
224 g.zHttpAuth = unobscure(db_get("http-auth",0));
225 }
226 }
227
228 /*
229 ** Look for SSH clone command line options and setup in globals.
230
+96 -14
--- src/http.c
+++ src/http.c
@@ -1,7 +1,6 @@
1
-/*
2
-** Copyright (c) 2007 D. Richard Hipp
1
+/* ** Copyright (c) 2007 D. Richard Hipp
32
**
43
** This program is free software; you can redistribute it and/or
54
** modify it under the terms of the Simplified BSD License (also
65
** known as the "2-Clause License" or "FreeBSD License".)
76
@@ -19,10 +18,23 @@
1918
*/
2019
#include "config.h"
2120
#include "http.h"
2221
#include <assert.h>
2322
23
+#ifdef _WIN32
24
+#include <io.h>
25
+#ifndef isatty
26
+#define isatty(d) _isatty(d)
27
+#endif
28
+#ifndef fileno
29
+#define fileno(s) _fileno(s)
30
+#endif
31
+#endif
32
+
33
+/* Keep track of HTTP Basic Authorization failures */
34
+static int fSeenHttpAuth = 0;
35
+
2436
/*
2537
** Construct the "login" card with the client credentials.
2638
**
2739
** login LOGIN NONCE SIGNATURE
2840
**
@@ -96,16 +108,15 @@
96108
}
97109
blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
98110
if( g.urlProxyAuth ){
99111
blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
100112
}
101
- if( g.urlPasswd && g.urlUser && g.fUseHttpAuth ){
102
- char *zCredentials = mprintf("%s:%s", g.urlUser, g.urlPasswd);
113
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
114
+ const char *zCredentials = g.zHttpAuth;
103115
char *zEncoded = encode64(zCredentials, -1);
104116
blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
105117
fossil_free(zEncoded);
106
- fossil_free(zCredentials);
107118
}
108119
blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
109120
blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
110121
if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
111122
if( g.fHttpTrace ){
@@ -113,10 +124,69 @@
113124
}else{
114125
blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
115126
}
116127
blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
117128
}
129
+
130
+/*
131
+** Use Fossil credentials for HTTP Basic Authorization prompt
132
+*/
133
+static int use_fossil_creds_for_httpauth_prompt(void){
134
+ Blob x;
135
+ char c;
136
+ char *zPrompt = mprintf(
137
+ "\nBasic Authorization over %s required to continue.\n"
138
+ "Use Fossil username and password (y/N)? ",
139
+ g.urlIsHttps==1 ? "encrypted HTTPS" : "unencrypted HTTP");
140
+ prompt_user(zPrompt, &x);
141
+ c = blob_str(&x)[0];
142
+ blob_reset(&x);
143
+ free(zPrompt);
144
+ return ( c=='y' || c=='Y' );
145
+}
146
+
147
+/*
148
+** Prompt to save HTTP Basic Authorization information
149
+*/
150
+static int save_httpauth_prompt(void){
151
+ Blob x;
152
+ char c;
153
+ if( (g.urlFlags & URL_REMEMBER)==0 ) return;
154
+ prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x);
155
+ c = blob_str(&x)[0];
156
+ blob_reset(&x);
157
+ return ( c!='n' && c!='N' );
158
+}
159
+
160
+/*
161
+** Get the HTTP Basic Authorization credentials from the user
162
+** when 401 is received.
163
+*/
164
+char *prompt_for_httpauth_creds(void){
165
+ Blob x;
166
+ char *zUser;
167
+ char *zPw;
168
+ char *zHttpAuth = 0;
169
+ if( !isatty(fileno(stdin)) ) return 0;
170
+ if ( use_fossil_creds_for_httpauth_prompt() ){
171
+ if( g.urlUser && g.urlPasswd ){
172
+ zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd);
173
+ }
174
+ }else{
175
+ prompt_user("Basic Authorization user: ", &x);
176
+ zUser = mprintf("%b", &x);
177
+ zPw = prompt_for_user_password(zUser);
178
+ zHttpAuth = mprintf("%s:%s", zUser, zPw);
179
+ blob_reset(&x);
180
+ free(zUser);
181
+ free(zPw);
182
+ }
183
+ if( save_httpauth_prompt() ){
184
+ db_set("http-auth", obscure(zHttpAuth), 0);
185
+ }
186
+ return zHttpAuth;
187
+}
118188
119189
/*
120190
** Sign the content in pSend, compress it, and send it to the server
121191
** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
122192
** in pRecv. pRecv is assumed to be uninitialized when
@@ -200,22 +270,34 @@
200270
while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
201271
/* printf("[%s]\n", zLine); fflush(stdout); */
202272
if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
203273
if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
204274
if( rc==401 ){
205
- if( g.urlIsHttps || g.fUseHttpAuth ){
206
- /* set g.fUseHttpAuth to avoid loop when doing HTTPS */
207
- g.fUseHttpAuth = 1;
208
- transport_close(GLOBAL_URL());
209
- if( --maxRedirect == 0 ){
210
- fossil_fatal("http authorization limit exceeded");
275
+ transport_close(GLOBAL_URL());
276
+ if( --maxRedirect == 0 ){
277
+ fossil_fatal("http authorization limit exceeded");
278
+ }
279
+ if( g.zHttpAuth==0 ){
280
+ g.zHttpAuth = prompt_for_httpauth_creds();
281
+ }
282
+ if( g.zHttpAuth && g.zHttpAuth[0] ){
283
+ if( fSeenHttpAuth ){
284
+ free(g.zHttpAuth);
285
+ g.zHttpAuth = 0;
286
+ fSeenHttpAuth = 0;
287
+ }else{
288
+ fSeenHttpAuth = 1;
211289
}
212290
return http_exchange(pSend, pReply, useLogin, maxRedirect);
213291
}else{
214
- fossil_warning(
215
- "Authorization over unencrypted HTTP requested; "
216
- "use --httpauth if appropriate.");
292
+ fossil_warning("HTTP Basic Authorization failed.");
293
+ if( g.zHttpAuth ){
294
+ free(g.zHttpAuth);
295
+ g.zHttpAuth = 0;
296
+ }
297
+ transport_close(GLOBAL_URL());
298
+ return http_exchange(pSend, pReply, useLogin, maxRedirect);
217299
}
218300
}
219301
if( rc!=200 && rc!=302 ){
220302
int ii;
221303
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
222304
--- src/http.c
+++ src/http.c
@@ -1,7 +1,6 @@
1 /*
2 ** Copyright (c) 2007 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7
@@ -19,10 +18,23 @@
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 **
@@ -96,16 +108,15 @@
96 }
97 blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
98 if( g.urlProxyAuth ){
99 blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
100 }
101 if( g.urlPasswd && g.urlUser && g.fUseHttpAuth ){
102 char *zCredentials = mprintf("%s:%s", g.urlUser, g.urlPasswd);
103 char *zEncoded = encode64(zCredentials, -1);
104 blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
105 fossil_free(zEncoded);
106 fossil_free(zCredentials);
107 }
108 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
109 blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
110 if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
111 if( g.fHttpTrace ){
@@ -113,10 +124,69 @@
113 }else{
114 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
115 }
116 blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
117 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
119 /*
120 ** Sign the content in pSend, compress it, and send it to the server
121 ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
122 ** in pRecv. pRecv is assumed to be uninitialized when
@@ -200,22 +270,34 @@
200 while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
201 /* printf("[%s]\n", zLine); fflush(stdout); */
202 if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
203 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
204 if( rc==401 ){
205 if( g.urlIsHttps || g.fUseHttpAuth ){
206 /* set g.fUseHttpAuth to avoid loop when doing HTTPS */
207 g.fUseHttpAuth = 1;
208 transport_close(GLOBAL_URL());
209 if( --maxRedirect == 0 ){
210 fossil_fatal("http authorization limit exceeded");
 
 
 
 
 
 
 
 
211 }
212 return http_exchange(pSend, pReply, useLogin, maxRedirect);
213 }else{
214 fossil_warning(
215 "Authorization over unencrypted HTTP requested; "
216 "use --httpauth if appropriate.");
 
 
 
 
217 }
218 }
219 if( rc!=200 && rc!=302 ){
220 int ii;
221 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
222
--- src/http.c
+++ src/http.c
@@ -1,7 +1,6 @@
1 /* ** Copyright (c) 2007 D. Richard Hipp
 
2 **
3 ** This program is free software; you can redistribute it and/or
4 ** modify it under the terms of the Simplified BSD License (also
5 ** known as the "2-Clause License" or "FreeBSD License".)
6
@@ -19,10 +18,23 @@
18 */
19 #include "config.h"
20 #include "http.h"
21 #include <assert.h>
22
23 #ifdef _WIN32
24 #include <io.h>
25 #ifndef isatty
26 #define isatty(d) _isatty(d)
27 #endif
28 #ifndef fileno
29 #define fileno(s) _fileno(s)
30 #endif
31 #endif
32
33 /* Keep track of HTTP Basic Authorization failures */
34 static int fSeenHttpAuth = 0;
35
36 /*
37 ** Construct the "login" card with the client credentials.
38 **
39 ** login LOGIN NONCE SIGNATURE
40 **
@@ -96,16 +108,15 @@
108 }
109 blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
110 if( g.urlProxyAuth ){
111 blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
112 }
113 if( g.zHttpAuth && g.zHttpAuth[0] ){
114 const char *zCredentials = g.zHttpAuth;
115 char *zEncoded = encode64(zCredentials, -1);
116 blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
117 fossil_free(zEncoded);
 
118 }
119 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
120 blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
121 if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
122 if( g.fHttpTrace ){
@@ -113,10 +124,69 @@
124 }else{
125 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
126 }
127 blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
128 }
129
130 /*
131 ** Use Fossil credentials for HTTP Basic Authorization prompt
132 */
133 static int use_fossil_creds_for_httpauth_prompt(void){
134 Blob x;
135 char c;
136 char *zPrompt = mprintf(
137 "\nBasic Authorization over %s required to continue.\n"
138 "Use Fossil username and password (y/N)? ",
139 g.urlIsHttps==1 ? "encrypted HTTPS" : "unencrypted HTTP");
140 prompt_user(zPrompt, &x);
141 c = blob_str(&x)[0];
142 blob_reset(&x);
143 free(zPrompt);
144 return ( c=='y' || c=='Y' );
145 }
146
147 /*
148 ** Prompt to save HTTP Basic Authorization information
149 */
150 static int save_httpauth_prompt(void){
151 Blob x;
152 char c;
153 if( (g.urlFlags & URL_REMEMBER)==0 ) return;
154 prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x);
155 c = blob_str(&x)[0];
156 blob_reset(&x);
157 return ( c!='n' && c!='N' );
158 }
159
160 /*
161 ** Get the HTTP Basic Authorization credentials from the user
162 ** when 401 is received.
163 */
164 char *prompt_for_httpauth_creds(void){
165 Blob x;
166 char *zUser;
167 char *zPw;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 if ( use_fossil_creds_for_httpauth_prompt() ){
171 if( g.urlUser && g.urlPasswd ){
172 zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd);
173 }
174 }else{
175 prompt_user("Basic Authorization user: ", &x);
176 zUser = mprintf("%b", &x);
177 zPw = prompt_for_user_password(zUser);
178 zHttpAuth = mprintf("%s:%s", zUser, zPw);
179 blob_reset(&x);
180 free(zUser);
181 free(zPw);
182 }
183 if( save_httpauth_prompt() ){
184 db_set("http-auth", obscure(zHttpAuth), 0);
185 }
186 return zHttpAuth;
187 }
188
189 /*
190 ** Sign the content in pSend, compress it, and send it to the server
191 ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
192 ** in pRecv. pRecv is assumed to be uninitialized when
@@ -200,22 +270,34 @@
270 while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){
271 /* printf("[%s]\n", zLine); fflush(stdout); */
272 if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
273 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
274 if( rc==401 ){
275 transport_close(GLOBAL_URL());
276 if( --maxRedirect == 0 ){
277 fossil_fatal("http authorization limit exceeded");
278 }
279 if( g.zHttpAuth==0 ){
280 g.zHttpAuth = prompt_for_httpauth_creds();
281 }
282 if( g.zHttpAuth && g.zHttpAuth[0] ){
283 if( fSeenHttpAuth ){
284 free(g.zHttpAuth);
285 g.zHttpAuth = 0;
286 fSeenHttpAuth = 0;
287 }else{
288 fSeenHttpAuth = 1;
289 }
290 return http_exchange(pSend, pReply, useLogin, maxRedirect);
291 }else{
292 fossil_warning("HTTP Basic Authorization failed.");
293 if( g.zHttpAuth ){
294 free(g.zHttpAuth);
295 g.zHttpAuth = 0;
296 }
297 transport_close(GLOBAL_URL());
298 return http_exchange(pSend, pReply, useLogin, maxRedirect);
299 }
300 }
301 if( rc!=200 && rc!=302 ){
302 int ii;
303 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
304
+2 -1
--- src/main.c
+++ src/main.c
@@ -139,11 +139,11 @@
139139
int fSqlTrace; /* True if --sqltrace flag is present */
140140
int fSqlStats; /* True if --sqltrace or --sqlstats are present */
141141
int fSqlPrint; /* True if -sqlprint flag is present */
142142
int fQuiet; /* True if -quiet flag is present */
143143
int fHttpTrace; /* Trace outbound HTTP requests */
144
- int fUseHttpAuth; /* True if user requests HTTP Authorization */
144
+ char *zHttpAuth; /* HTTP Authorization user:pass information */
145145
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
146146
int fSshTrace; /* Trace the SSH setup traffic */
147147
int fSshClient; /* HTTP client flags for SSH client */
148148
char *zSshCmd; /* SSH command string */
149149
int fNoSync; /* Do not do an autosync ever. --nosync */
@@ -649,10 +649,11 @@
649649
g.fSshClient = 0;
650650
g.zSshCmd = 0;
651651
if( g.fSqlTrace ) g.fSqlStats = 1;
652652
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
653653
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
654
+ g.zHttpAuth = 0;
654655
g.zLogin = find_option("user", "U", 1);
655656
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
656657
g.zErrlog = find_option("errorlog", 0, 1);
657658
if( find_option("utc",0,0) ) g.fTimeFormat = 1;
658659
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
659660
--- src/main.c
+++ src/main.c
@@ -139,11 +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; /* True if user requests HTTP Authorization */
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 */
@@ -649,10 +649,11 @@
649 g.fSshClient = 0;
650 g.zSshCmd = 0;
651 if( g.fSqlTrace ) g.fSqlStats = 1;
652 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
653 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
 
654 g.zLogin = find_option("user", "U", 1);
655 g.zSSLIdentity = find_option("ssl-identity", 0, 1);
656 g.zErrlog = find_option("errorlog", 0, 1);
657 if( find_option("utc",0,0) ) g.fTimeFormat = 1;
658 if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
659
--- src/main.c
+++ src/main.c
@@ -139,11 +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 char *zHttpAuth; /* HTTP Authorization user:pass information */
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 */
@@ -649,10 +649,11 @@
649 g.fSshClient = 0;
650 g.zSshCmd = 0;
651 if( g.fSqlTrace ) g.fSqlStats = 1;
652 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
653 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
654 g.zHttpAuth = 0;
655 g.zLogin = find_option("user", "U", 1);
656 g.zSSLIdentity = find_option("ssl-identity", 0, 1);
657 g.zErrlog = find_option("errorlog", 0, 1);
658 if( find_option("utc",0,0) ) g.fTimeFormat = 1;
659 if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
660
+3 -2
--- src/sync.c
+++ src/sync.c
@@ -83,18 +83,19 @@
8383
** of a server to sync against. If no argument is given, use the
8484
** most recently synced URL. Remember the current URL for next time.
8585
*/
8686
static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
8787
const char *zUrl = 0;
88
+ const char *zHttpAuth = 0;
8889
unsigned configSync = 0;
8990
unsigned urlFlags = URL_REMEMBER | URL_PROMPT_PW;
9091
int urlOptional = 0;
9192
if( find_option("autourl",0,0)!=0 ){
9293
urlOptional = 1;
9394
urlFlags = 0;
9495
}
95
- g.fUseHttpAuth = find_option("httpauth",0,0)!=0;
96
+ zHttpAuth = find_option("httpauth","B",1);
9697
if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
9798
if( find_option("private",0,0)!=0 ){
9899
*pSyncFlags |= SYNC_PRIVATE;
99100
}
100101
if( find_option("verbose","v",0)!=0 ){
@@ -117,11 +118,11 @@
117118
}
118119
if( urlFlags & URL_REMEMBER ){
119120
clone_ssh_db_set_options();
120121
}
121122
url_parse(zUrl, urlFlags);
122
- remember_or_get_http_auth(urlFlags & URL_REMEMBER, zUrl);
123
+ remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
123124
url_remember();
124125
if( g.urlProtocol==0 ){
125126
if( urlOptional ) fossil_exit(0);
126127
usage("URL");
127128
}
128129
--- src/sync.c
+++ src/sync.c
@@ -83,18 +83,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 g.fUseHttpAuth = find_option("httpauth",0,0)!=0;
96 if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
97 if( find_option("private",0,0)!=0 ){
98 *pSyncFlags |= SYNC_PRIVATE;
99 }
100 if( find_option("verbose","v",0)!=0 ){
@@ -117,11 +118,11 @@
117 }
118 if( urlFlags & URL_REMEMBER ){
119 clone_ssh_db_set_options();
120 }
121 url_parse(zUrl, urlFlags);
122 remember_or_get_http_auth(urlFlags & URL_REMEMBER, zUrl);
123 url_remember();
124 if( g.urlProtocol==0 ){
125 if( urlOptional ) fossil_exit(0);
126 usage("URL");
127 }
128
--- src/sync.c
+++ src/sync.c
@@ -83,18 +83,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 const char *zHttpAuth = 0;
89 unsigned configSync = 0;
90 unsigned urlFlags = URL_REMEMBER | URL_PROMPT_PW;
91 int urlOptional = 0;
92 if( find_option("autourl",0,0)!=0 ){
93 urlOptional = 1;
94 urlFlags = 0;
95 }
96 zHttpAuth = find_option("httpauth","B",1);
97 if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
98 if( find_option("private",0,0)!=0 ){
99 *pSyncFlags |= SYNC_PRIVATE;
100 }
101 if( find_option("verbose","v",0)!=0 ){
@@ -117,11 +118,11 @@
118 }
119 if( urlFlags & URL_REMEMBER ){
120 clone_ssh_db_set_options();
121 }
122 url_parse(zUrl, urlFlags);
123 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
124 url_remember();
125 if( g.urlProtocol==0 ){
126 if( urlOptional ) fossil_exit(0);
127 usage("URL");
128 }
129

Keyboard Shortcuts

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