Fossil SCM

Enable an /xfer login card to be delivered via the X-Fossil-Xfer-Login HTTP header, which is expected to be in the same format as the sync protocol's login card. The purpose of this is to simplify generation of the login card from non-fossil(1) clients, namely libfossil. This is untested until libfossil can generate such cards (it's just missing a bit of glue for that).

stephan 2025-07-21 18:38 trunk
Commit cfddded40e91f9c9b360134be0e61f5abb39e043d6059fe8021e42babaa2b599
+2
--- src/http.c
+++ src/http.c
@@ -635,10 +635,12 @@
635635
if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
636636
}else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
637637
isError = 1;
638638
}
639639
}
640
+ }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
641
+ g.zLoginCard = fsl_mprintf("%s", &line[21]);
640642
}
641643
}
642644
if( iHttpVersion<0 ){
643645
/* We got nothing back from the server. If using the ssh: protocol,
644646
** this might mean we need to add or remove the PATH=... argument
645647
--- src/http.c
+++ src/http.c
@@ -635,10 +635,12 @@
635 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
636 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
637 isError = 1;
638 }
639 }
 
 
640 }
641 }
642 if( iHttpVersion<0 ){
643 /* We got nothing back from the server. If using the ssh: protocol,
644 ** this might mean we need to add or remove the PATH=... argument
645
--- src/http.c
+++ src/http.c
@@ -635,10 +635,12 @@
635 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
636 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
637 isError = 1;
638 }
639 }
640 }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
641 g.zLoginCard = fsl_mprintf("%s", &line[21]);
642 }
643 }
644 if( iHttpVersion<0 ){
645 /* We got nothing back from the server. If using the ssh: protocol,
646 ** this might mean we need to add or remove the PATH=... argument
647
+1
--- src/main.c
+++ src/main.c
@@ -230,10 +230,11 @@
230230
const char *zReqType; /* Type of request: "HTTP", "CGI", "SCGI" */
231231
#if USE_SEE
232232
const char *zPidKey; /* Saved value of the --usepidkey option. Only
233233
* applicable when using SEE on Windows or Linux. */
234234
#endif
235
+ char *zLoginCard; /* X-Fossil-Xfer-Login request header value */
235236
int useLocalauth; /* No login required if from 127.0.0.1 */
236237
int noPswd; /* Logged in without password (on 127.0.0.1) */
237238
int userUid; /* Integer user id */
238239
int isHuman; /* True if access by a human, not a spider or bot */
239240
int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
240241
--- src/main.c
+++ src/main.c
@@ -230,10 +230,11 @@
230 const char *zReqType; /* Type of request: "HTTP", "CGI", "SCGI" */
231 #if USE_SEE
232 const char *zPidKey; /* Saved value of the --usepidkey option. Only
233 * applicable when using SEE on Windows or Linux. */
234 #endif
 
235 int useLocalauth; /* No login required if from 127.0.0.1 */
236 int noPswd; /* Logged in without password (on 127.0.0.1) */
237 int userUid; /* Integer user id */
238 int isHuman; /* True if access by a human, not a spider or bot */
239 int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
240
--- src/main.c
+++ src/main.c
@@ -230,10 +230,11 @@
230 const char *zReqType; /* Type of request: "HTTP", "CGI", "SCGI" */
231 #if USE_SEE
232 const char *zPidKey; /* Saved value of the --usepidkey option. Only
233 * applicable when using SEE on Windows or Linux. */
234 #endif
235 char *zLoginCard; /* X-Fossil-Xfer-Login request header value */
236 int useLocalauth; /* No login required if from 127.0.0.1 */
237 int noPswd; /* Logged in without password (on 127.0.0.1) */
238 int userUid; /* Integer user id */
239 int isHuman; /* True if access by a human, not a spider or bot */
240 int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
241
+11
--- src/xfer.c
+++ src/xfer.c
@@ -1314,10 +1314,20 @@
13141314
}
13151315
zScript = xfer_push_code();
13161316
if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
13171317
pzUuidList = &zUuidList;
13181318
pnUuidList = &nUuidList;
1319
+ }
1320
+ if( g.zLoginCard ){
1321
+ /* Login card received via HTTP header X-Fossil-Xfer-Login */
1322
+ blob_init(&xfer.line, g.zLoginCard, -1);
1323
+ xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
1324
+ count(xfer.aToken));
1325
+ if( xfer.nToken==4
1326
+ && blob_eq(&xfer.aToken[0], "login") ){
1327
+ goto handle_login_card;
1328
+ }
13191329
}
13201330
while( blob_line(xfer.pIn, &xfer.line) ){
13211331
if( blob_buffer(&xfer.line)[0]=='#' ) continue;
13221332
if( blob_size(&xfer.line)==0 ) continue;
13231333
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -1555,10 +1565,11 @@
15551565
** The client can send multiple logins. Permissions are cumulative.
15561566
*/
15571567
if( blob_eq(&xfer.aToken[0], "login")
15581568
&& xfer.nToken==4
15591569
){
1570
+ handle_login_card:
15601571
if( disableLogin ){
15611572
g.perm.Read = g.perm.Write = g.perm.Private = g.perm.Admin = 1;
15621573
}else{
15631574
if( check_tail_hash(&xfer.aToken[2], xfer.pIn)
15641575
|| check_login(&xfer.aToken[1], &xfer.aToken[2], &xfer.aToken[3])
15651576
--- src/xfer.c
+++ src/xfer.c
@@ -1314,10 +1314,20 @@
1314 }
1315 zScript = xfer_push_code();
1316 if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
1317 pzUuidList = &zUuidList;
1318 pnUuidList = &nUuidList;
 
 
 
 
 
 
 
 
 
 
1319 }
1320 while( blob_line(xfer.pIn, &xfer.line) ){
1321 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
1322 if( blob_size(&xfer.line)==0 ) continue;
1323 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -1555,10 +1565,11 @@
1555 ** The client can send multiple logins. Permissions are cumulative.
1556 */
1557 if( blob_eq(&xfer.aToken[0], "login")
1558 && xfer.nToken==4
1559 ){
 
1560 if( disableLogin ){
1561 g.perm.Read = g.perm.Write = g.perm.Private = g.perm.Admin = 1;
1562 }else{
1563 if( check_tail_hash(&xfer.aToken[2], xfer.pIn)
1564 || check_login(&xfer.aToken[1], &xfer.aToken[2], &xfer.aToken[3])
1565
--- src/xfer.c
+++ src/xfer.c
@@ -1314,10 +1314,20 @@
1314 }
1315 zScript = xfer_push_code();
1316 if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
1317 pzUuidList = &zUuidList;
1318 pnUuidList = &nUuidList;
1319 }
1320 if( g.zLoginCard ){
1321 /* Login card received via HTTP header X-Fossil-Xfer-Login */
1322 blob_init(&xfer.line, g.zLoginCard, -1);
1323 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
1324 count(xfer.aToken));
1325 if( xfer.nToken==4
1326 && blob_eq(&xfer.aToken[0], "login") ){
1327 goto handle_login_card;
1328 }
1329 }
1330 while( blob_line(xfer.pIn, &xfer.line) ){
1331 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
1332 if( blob_size(&xfer.line)==0 ) continue;
1333 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -1555,10 +1565,11 @@
1565 ** The client can send multiple logins. Permissions are cumulative.
1566 */
1567 if( blob_eq(&xfer.aToken[0], "login")
1568 && xfer.nToken==4
1569 ){
1570 handle_login_card:
1571 if( disableLogin ){
1572 g.perm.Read = g.perm.Write = g.perm.Private = g.perm.Admin = 1;
1573 }else{
1574 if( check_tail_hash(&xfer.aToken[2], xfer.pIn)
1575 || check_login(&xfer.aToken[1], &xfer.aToken[2], &xfer.aToken[3])
1576

Keyboard Shortcuts

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