Fossil SCM

json: when logging in locally to a server started with the --localauth flag, the authToken is now ignored entirely.

stephan 2020-01-29 06:25 trunk
Commit 6dfc395a4869945a4fd85e2f3913ddb939add1f5dc3995f916d6e162f922b499
+19 -10
--- src/json.c
+++ src/json.c
@@ -282,12 +282,12 @@
282282
** ENV means the system environment (getenv()).
283283
**
284284
** Precedence: POST.payload, GET/COOKIE/non-JSON POST, JSON POST, ENV.
285285
**
286286
** FIXME: the precedence SHOULD be: GET, POST.payload, POST, COOKIE,
287
-** ENV, but the amalgamation of the GET/POST vars makes it difficult
288
-** for me to do that. Since fossil only uses one cookie, cookie
287
+** ENV, but the amalgamation of the GET/POST vars makes it effectively
288
+** impossible to do that. Since fossil only uses one cookie, cookie
289289
** precedence isn't a real/high-priority problem.
290290
*/
291291
cson_value * json_getenv( char const * zKey ){
292292
cson_value * rc;
293293
rc = g.json.reqPayload.o
@@ -630,29 +630,38 @@
630630
** we will not be able to replace fossil's internal idea of the auth
631631
** info in time (and future changes to that state may cause unexpected
632632
** results).
633633
**
634634
** The result of this call are cached for future calls.
635
+**
636
+** Special case: if g.useLocalauth is true (i.e. the --localauth flag
637
+** was used to start the fossil server instance) and the current
638
+** connection is "local", any authToken provided by the user is
639
+** ignored and no new token is created: localauth mode trumps the
640
+** authToken.
635641
*/
636642
cson_value * json_auth_token(){
637
- assert(g.json.gc.a && "json_main_bootstrap() was not called!");
638
- if( !g.json.authToken ){
643
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
644
+ if( g.json.authToken==0 && g.noPswd==0
645
+ /* g.noPswd==0 means the user was logged in via a local
646
+ connection using --localauth. */
647
+ ){
639648
/* Try to get an authorization token from GET parameter, POSTed
640649
JSON, or fossil cookie (in that order). */
641650
g.json.authToken = json_getenv(FossilJsonKeys.authToken);
642651
if(g.json.authToken
643652
&& cson_value_is_string(g.json.authToken)
644653
&& !PD(login_cookie_name(),NULL)){
645654
/* tell fossil to use this login info.
646655
647
- FIXME?: because the JSON bits don't carry around
648
- login_cookie_name(), there is(?) a potential(?) login hijacking
649
- window here. We may need to change the JSON auth token to be in
650
- the form: login_cookie_name()=...
656
+ FIXME?: because the JSON bits don't carry around
657
+ login_cookie_name(), there is(?) a potential(?) login hijacking
658
+ window here. We may need to change the JSON auth token to be in
659
+ the form: login_cookie_name()=...
651660
652
- Then again, the hardened cookie value helps ensure that
653
- only a proper key/value match is valid.
661
+ Then again, the hardened cookie value helps ensure that
662
+ only a proper key/value match is valid.
654663
*/
655664
cgi_replace_parameter( login_cookie_name(), cson_value_get_cstr(g.json.authToken) );
656665
}else if( g.isHTTP ){
657666
/* try fossil's conventional cookie. */
658667
/* Reminder: chicken/egg scenario regarding db access in CLI
659668
--- src/json.c
+++ src/json.c
@@ -282,12 +282,12 @@
282 ** ENV means the system environment (getenv()).
283 **
284 ** Precedence: POST.payload, GET/COOKIE/non-JSON POST, JSON POST, ENV.
285 **
286 ** FIXME: the precedence SHOULD be: GET, POST.payload, POST, COOKIE,
287 ** ENV, but the amalgamation of the GET/POST vars makes it difficult
288 ** for me to do that. Since fossil only uses one cookie, cookie
289 ** precedence isn't a real/high-priority problem.
290 */
291 cson_value * json_getenv( char const * zKey ){
292 cson_value * rc;
293 rc = g.json.reqPayload.o
@@ -630,29 +630,38 @@
630 ** we will not be able to replace fossil's internal idea of the auth
631 ** info in time (and future changes to that state may cause unexpected
632 ** results).
633 **
634 ** The result of this call are cached for future calls.
 
 
 
 
 
 
635 */
636 cson_value * json_auth_token(){
637 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
638 if( !g.json.authToken ){
 
 
 
639 /* Try to get an authorization token from GET parameter, POSTed
640 JSON, or fossil cookie (in that order). */
641 g.json.authToken = json_getenv(FossilJsonKeys.authToken);
642 if(g.json.authToken
643 && cson_value_is_string(g.json.authToken)
644 && !PD(login_cookie_name(),NULL)){
645 /* tell fossil to use this login info.
646
647 FIXME?: because the JSON bits don't carry around
648 login_cookie_name(), there is(?) a potential(?) login hijacking
649 window here. We may need to change the JSON auth token to be in
650 the form: login_cookie_name()=...
651
652 Then again, the hardened cookie value helps ensure that
653 only a proper key/value match is valid.
654 */
655 cgi_replace_parameter( login_cookie_name(), cson_value_get_cstr(g.json.authToken) );
656 }else if( g.isHTTP ){
657 /* try fossil's conventional cookie. */
658 /* Reminder: chicken/egg scenario regarding db access in CLI
659
--- src/json.c
+++ src/json.c
@@ -282,12 +282,12 @@
282 ** ENV means the system environment (getenv()).
283 **
284 ** Precedence: POST.payload, GET/COOKIE/non-JSON POST, JSON POST, ENV.
285 **
286 ** FIXME: the precedence SHOULD be: GET, POST.payload, POST, COOKIE,
287 ** ENV, but the amalgamation of the GET/POST vars makes it effectively
288 ** impossible to do that. Since fossil only uses one cookie, cookie
289 ** precedence isn't a real/high-priority problem.
290 */
291 cson_value * json_getenv( char const * zKey ){
292 cson_value * rc;
293 rc = g.json.reqPayload.o
@@ -630,29 +630,38 @@
630 ** we will not be able to replace fossil's internal idea of the auth
631 ** info in time (and future changes to that state may cause unexpected
632 ** results).
633 **
634 ** The result of this call are cached for future calls.
635 **
636 ** Special case: if g.useLocalauth is true (i.e. the --localauth flag
637 ** was used to start the fossil server instance) and the current
638 ** connection is "local", any authToken provided by the user is
639 ** ignored and no new token is created: localauth mode trumps the
640 ** authToken.
641 */
642 cson_value * json_auth_token(){
643 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
644 if( g.json.authToken==0 && g.noPswd==0
645 /* g.noPswd==0 means the user was logged in via a local
646 connection using --localauth. */
647 ){
648 /* Try to get an authorization token from GET parameter, POSTed
649 JSON, or fossil cookie (in that order). */
650 g.json.authToken = json_getenv(FossilJsonKeys.authToken);
651 if(g.json.authToken
652 && cson_value_is_string(g.json.authToken)
653 && !PD(login_cookie_name(),NULL)){
654 /* tell fossil to use this login info.
655
656 FIXME?: because the JSON bits don't carry around
657 login_cookie_name(), there is(?) a potential(?) login hijacking
658 window here. We may need to change the JSON auth token to be in
659 the form: login_cookie_name()=...
660
661 Then again, the hardened cookie value helps ensure that
662 only a proper key/value match is valid.
663 */
664 cgi_replace_parameter( login_cookie_name(), cson_value_get_cstr(g.json.authToken) );
665 }else if( g.isHTTP ){
666 /* try fossil's conventional cookie. */
667 /* Reminder: chicken/egg scenario regarding db access in CLI
668
--- src/json_login.c
+++ src/json_login.c
@@ -43,19 +43,18 @@
4343
FIXME: we want to check the GET/POST args in this order:
4444
4545
- GET: name, n, password, p
4646
- POST: name, password
4747
48
- but a bug in cgi_parameter() is breaking that, causing PD() to
49
- return the last element of the PATH_INFO instead.
48
+ but fossil's age-old behaviour of treating the last element of
49
+ PATH_INFO as the value for the name parameter breaks that.
5050
51
- Summary: If we check for P("name") first, then P("n"),
52
- then ONLY a GET param of "name" will match ("n"
53
- is not recognized). If we reverse the order of the
54
- checks then both forms work. Strangely enough, the
51
+ Summary: If we check for P("name") first, then P("n"), then ONLY a
52
+ GET param of "name" will match ("n" is not recognized). If we
53
+ reverse the order of the checks then both forms work. The
5554
"p"/"password" check is not affected by this.
56
- */
55
+ */
5756
char const * name = cson_value_get_cstr(json_req_payload_get("name"));
5857
char const * pw = NULL;
5958
char const * anonSeed = NULL;
6059
cson_value * payload = NULL;
6160
int uid = 0;
@@ -231,11 +230,11 @@
231230
*/
232231
cson_value * json_page_whoami(){
233232
cson_value * payload = NULL;
234233
cson_object * obj = NULL;
235234
Stmt q;
236
- if(!g.json.authToken){
235
+ if(!g.json.authToken && g.userUid==0){
237236
/* assume we just logged out. */
238237
db_prepare(&q, "SELECT login, cap FROM user WHERE login='nobody'");
239238
}
240239
else{
241240
db_prepare(&q, "SELECT login, cap FROM user WHERE uid=%d",
242241
--- src/json_login.c
+++ src/json_login.c
@@ -43,19 +43,18 @@
43 FIXME: we want to check the GET/POST args in this order:
44
45 - GET: name, n, password, p
46 - POST: name, password
47
48 but a bug in cgi_parameter() is breaking that, causing PD() to
49 return the last element of the PATH_INFO instead.
50
51 Summary: If we check for P("name") first, then P("n"),
52 then ONLY a GET param of "name" will match ("n"
53 is not recognized). If we reverse the order of the
54 checks then both forms work. Strangely enough, the
55 "p"/"password" check is not affected by this.
56 */
57 char const * name = cson_value_get_cstr(json_req_payload_get("name"));
58 char const * pw = NULL;
59 char const * anonSeed = NULL;
60 cson_value * payload = NULL;
61 int uid = 0;
@@ -231,11 +230,11 @@
231 */
232 cson_value * json_page_whoami(){
233 cson_value * payload = NULL;
234 cson_object * obj = NULL;
235 Stmt q;
236 if(!g.json.authToken){
237 /* assume we just logged out. */
238 db_prepare(&q, "SELECT login, cap FROM user WHERE login='nobody'");
239 }
240 else{
241 db_prepare(&q, "SELECT login, cap FROM user WHERE uid=%d",
242
--- src/json_login.c
+++ src/json_login.c
@@ -43,19 +43,18 @@
43 FIXME: we want to check the GET/POST args in this order:
44
45 - GET: name, n, password, p
46 - POST: name, password
47
48 but fossil's age-old behaviour of treating the last element of
49 PATH_INFO as the value for the name parameter breaks that.
50
51 Summary: If we check for P("name") first, then P("n"), then ONLY a
52 GET param of "name" will match ("n" is not recognized). If we
53 reverse the order of the checks then both forms work. The
 
54 "p"/"password" check is not affected by this.
55 */
56 char const * name = cson_value_get_cstr(json_req_payload_get("name"));
57 char const * pw = NULL;
58 char const * anonSeed = NULL;
59 cson_value * payload = NULL;
60 int uid = 0;
@@ -231,11 +230,11 @@
230 */
231 cson_value * json_page_whoami(){
232 cson_value * payload = NULL;
233 cson_object * obj = NULL;
234 Stmt q;
235 if(!g.json.authToken && g.userUid==0){
236 /* assume we just logged out. */
237 db_prepare(&q, "SELECT login, cap FROM user WHERE login='nobody'");
238 }
239 else{
240 db_prepare(&q, "SELECT login, cap FROM user WHERE uid=%d",
241
--- www/json-api/api-auth.md
+++ www/json-api/api-auth.md
@@ -148,25 +148,31 @@
148148
The response *also* sets the conventional fossil login cookie (for
149149
clients which can make use of cookies), using fossil's existing
150150
mechanism for this.
151151
152152
Further requests which require authentication must include the
153
-"authToken" (from the returned payload value) in the request (or it must
153
+`authToken` (from the returned payload value) in the request (or it must
154154
be available via fossil's standard cookie) or access may (depending on
155
-the request) be denied. The authToken may optionally be set in the
155
+the request) be denied. The `authToken` may optionally be set in the
156156
request envelope or as a GET parameter, and it *must* be given if the
157157
request requires restricted access to a resource. e.g. if reading
158158
tickets is disabled for the guest user then all non-guest users must
159159
send authentication info in their requests in order to be able to fetch
160160
ticket info.
161161
162162
Cookie-aware clients should send the login-generated cookie with each
163
-request, in which case they do not need explicitly include the auth
164
-token in the JSON envelope/GET arguments. Note that fossil uses a
165
-project-dependent cookie name in order to help thwart attacks, so there
166
-is no simple mapping of cookie *name* to auth token. That said, the
167
-cookie's *value* is also the auth token's value.
163
+request, in which case they do not need explicitly include the
164
+`authToken` in the JSON envelope/GET arguments. If submitted, the
165
+`authToken` is used, otherwise the cookie, if set, is used. Note that
166
+fossil uses a project-dependent cookie name in order to help thwart
167
+attacks, so there is no simple mapping of cookie *name* to auth
168
+token. That said, the cookie's *value* is also the auth token's value.
169
+
170
+> Special case: when accessing fossil over a local server instance
171
+which was started with the `--localauth` flag, the `authToken` is ignored
172
+(neither validated nor used for any form of authentication).
173
+
168174
169175
<a id="login-anonymous"></a>
170176
## Anonymous User Logins
171177
172178
The Anonymous user requires special handling because he has a random
173179
--- www/json-api/api-auth.md
+++ www/json-api/api-auth.md
@@ -148,25 +148,31 @@
148 The response *also* sets the conventional fossil login cookie (for
149 clients which can make use of cookies), using fossil's existing
150 mechanism for this.
151
152 Further requests which require authentication must include the
153 "authToken" (from the returned payload value) in the request (or it must
154 be available via fossil's standard cookie) or access may (depending on
155 the request) be denied. The authToken may optionally be set in the
156 request envelope or as a GET parameter, and it *must* be given if the
157 request requires restricted access to a resource. e.g. if reading
158 tickets is disabled for the guest user then all non-guest users must
159 send authentication info in their requests in order to be able to fetch
160 ticket info.
161
162 Cookie-aware clients should send the login-generated cookie with each
163 request, in which case they do not need explicitly include the auth
164 token in the JSON envelope/GET arguments. Note that fossil uses a
165 project-dependent cookie name in order to help thwart attacks, so there
166 is no simple mapping of cookie *name* to auth token. That said, the
167 cookie's *value* is also the auth token's value.
 
 
 
 
 
 
168
169 <a id="login-anonymous"></a>
170 ## Anonymous User Logins
171
172 The Anonymous user requires special handling because he has a random
173
--- www/json-api/api-auth.md
+++ www/json-api/api-auth.md
@@ -148,25 +148,31 @@
148 The response *also* sets the conventional fossil login cookie (for
149 clients which can make use of cookies), using fossil's existing
150 mechanism for this.
151
152 Further requests which require authentication must include the
153 `authToken` (from the returned payload value) in the request (or it must
154 be available via fossil's standard cookie) or access may (depending on
155 the request) be denied. The `authToken` may optionally be set in the
156 request envelope or as a GET parameter, and it *must* be given if the
157 request requires restricted access to a resource. e.g. if reading
158 tickets is disabled for the guest user then all non-guest users must
159 send authentication info in their requests in order to be able to fetch
160 ticket info.
161
162 Cookie-aware clients should send the login-generated cookie with each
163 request, in which case they do not need explicitly include the
164 `authToken` in the JSON envelope/GET arguments. If submitted, the
165 `authToken` is used, otherwise the cookie, if set, is used. Note that
166 fossil uses a project-dependent cookie name in order to help thwart
167 attacks, so there is no simple mapping of cookie *name* to auth
168 token. That said, the cookie's *value* is also the auth token's value.
169
170 > Special case: when accessing fossil over a local server instance
171 which was started with the `--localauth` flag, the `authToken` is ignored
172 (neither validated nor used for any form of authentication).
173
174
175 <a id="login-anonymous"></a>
176 ## Anonymous User Logins
177
178 The Anonymous user requires special handling because he has a random
179
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -73,14 +73,15 @@
7373
request. Determines what access rights the user has, and any given
7474
request may require specific rights. In principle this is required
7575
by any request which needs non-guest privileges, but cookie-aware
7676
clients do not manually need to track this (it is managed as a
7777
cookie by the agent/browser).
78
- - Note that when using a fossil server with the `--localauth` option,
79
- the `authToken` should not be used. FIXME: have the JSON API simply ignore
80
- the `authToken` for this case, rather than failing if the `authToken`
81
- is missing or invalid.
78
+ - Note that when accessing fossil over a local server instance
79
+ which was started with the `--localauth` flag, the `authToken`
80
+ will be ignored and need not be sent with any requests. The user
81
+ will automatically be given full privileges, as if they were
82
+ using CLI mode.
8283
- `payload`: Command-specific parameters. Most can optionally come in
8384
via GET parameters, but those taking complex structures expect them
8485
to be placed here.
8586
- `indent`: Optionally specifies indentation for the output. 0=no
8687
indention. 1=a single TAB character for each level of
8788
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -73,14 +73,15 @@
73 request. Determines what access rights the user has, and any given
74 request may require specific rights. In principle this is required
75 by any request which needs non-guest privileges, but cookie-aware
76 clients do not manually need to track this (it is managed as a
77 cookie by the agent/browser).
78 - Note that when using a fossil server with the `--localauth` option,
79 the `authToken` should not be used. FIXME: have the JSON API simply ignore
80 the `authToken` for this case, rather than failing if the `authToken`
81 is missing or invalid.
 
82 - `payload`: Command-specific parameters. Most can optionally come in
83 via GET parameters, but those taking complex structures expect them
84 to be placed here.
85 - `indent`: Optionally specifies indentation for the output. 0=no
86 indention. 1=a single TAB character for each level of
87
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -73,14 +73,15 @@
73 request. Determines what access rights the user has, and any given
74 request may require specific rights. In principle this is required
75 by any request which needs non-guest privileges, but cookie-aware
76 clients do not manually need to track this (it is managed as a
77 cookie by the agent/browser).
78 - Note that when accessing fossil over a local server instance
79 which was started with the `--localauth` flag, the `authToken`
80 will be ignored and need not be sent with any requests. The user
81 will automatically be given full privileges, as if they were
82 using CLI mode.
83 - `payload`: Command-specific parameters. Most can optionally come in
84 via GET parameters, but those taking complex structures expect them
85 to be placed here.
86 - `indent`: Optionally specifies indentation for the output. 0=no
87 indention. 1=a single TAB character for each level of
88

Keyboard Shortcuts

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