Fossil

Check-in [cfddded40e]
Login

Check-in [cfddded40e]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | xfer-login-card
Files: files | file ages | folders
SHA3-256: cfddded40e91f9c9b360134be0e61f5abb39e043d6059fe8021e42babaa2b599
User & Date: stephan 2025-07-21 18:38:54.126
Context
2025-07-21
18:40
And this time compile before committing. ... (check-in: a62ffc1922 user: stephan tags: xfer-login-card)
18:38
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). ... (check-in: cfddded40e user: stephan tags: xfer-login-card)
17:16
Account for [638b7e094b899a] when building with --json, as reported in [forum:9acc3d0022407bfe | forum post 9acc3d0022]. ... (check-in: c6f0d7aecd user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/http.c.
633
634
635
636
637
638
639


640
641
642
643
644
645
646
      }else{
        if( mHttpFlags & HTTP_GENERIC ){
          if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
        }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
          isError = 1;
        }
      }


    }
  }
  if( iHttpVersion<0 ){
    /* We got nothing back from the server.  If using the ssh: protocol,
    ** this might mean we need to add or remove the PATH=... argument
    ** to the SSH command being sent.  If that is the case, retry the
    ** request after adding or removing the PATH= argument.







>
>







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
      }else{
        if( mHttpFlags & HTTP_GENERIC ){
          if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
        }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
          isError = 1;
        }
      }
    }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
      g.zLoginCard = fsl_mprintf("%s", &line[21]);
    }
  }
  if( iHttpVersion<0 ){
    /* We got nothing back from the server.  If using the ssh: protocol,
    ** this might mean we need to add or remove the PATH=... argument
    ** to the SSH command being sent.  If that is the case, retry the
    ** request after adding or removing the PATH= argument.
Changes to src/main.c.
228
229
230
231
232
233
234

235
236
237
238
239
240
241
                             ** SSL client identity */
  const char *zCgiFile;      /* Name of the CGI file */
  const char *zReqType;      /* Type of request: "HTTP", "CGI", "SCGI" */
#if USE_SEE
  const char *zPidKey;    /* Saved value of the --usepidkey option.  Only
                           * applicable when using SEE on Windows or Linux. */
#endif

  int useLocalauth;       /* No login required if from 127.0.0.1 */
  int noPswd;             /* Logged in without password (on 127.0.0.1) */
  int userUid;            /* Integer user id */
  int isHuman;            /* True if access by a human, not a spider or bot */
  int comFmtFlags;        /* Zero or more "COMMENT_PRINT_*" bit flags, should be
                          ** accessed through get_comment_format(). */
  const char *zSockName;  /* Name of the unix-domain socket file */







>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
                             ** SSL client identity */
  const char *zCgiFile;      /* Name of the CGI file */
  const char *zReqType;      /* Type of request: "HTTP", "CGI", "SCGI" */
#if USE_SEE
  const char *zPidKey;    /* Saved value of the --usepidkey option.  Only
                           * applicable when using SEE on Windows or Linux. */
#endif
  char *zLoginCard;       /* X-Fossil-Xfer-Login request header value */
  int useLocalauth;       /* No login required if from 127.0.0.1 */
  int noPswd;             /* Logged in without password (on 127.0.0.1) */
  int userUid;            /* Integer user id */
  int isHuman;            /* True if access by a human, not a spider or bot */
  int comFmtFlags;        /* Zero or more "COMMENT_PRINT_*" bit flags, should be
                          ** accessed through get_comment_format(). */
  const char *zSockName;  /* Name of the unix-domain socket file */
Changes to src/xfer.c.
1312
1313
1314
1315
1316
1317
1318










1319
1320
1321
1322
1323
1324
1325
    @ error common\sscript\sfailed:\s%F(g.zErrMsg)
    nErr++;
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;










  }
  while( blob_line(xfer.pIn, &xfer.line) ){
    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));

    /*   file HASH SIZE \n CONTENT







>
>
>
>
>
>
>
>
>
>







1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
    @ error common\sscript\sfailed:\s%F(g.zErrMsg)
    nErr++;
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;
  }
  if( g.zLoginCard ){
    /* Login card received via HTTP header X-Fossil-Xfer-Login */
    blob_init(&xfer.line, g.zLoginCard, -1);
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
                                count(xfer.aToken));
    if( xfer.nToken==4
        && blob_eq(&xfer.aToken[0], "login") ){
      goto handle_login_card;
    }
  }
  while( blob_line(xfer.pIn, &xfer.line) ){
    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));

    /*   file HASH SIZE \n CONTENT
1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
    ** The client has sent login credentials to the server.
    ** Validate the login.  This has to happen before anything else.
    ** The client can send multiple logins.  Permissions are cumulative.
    */
    if( blob_eq(&xfer.aToken[0], "login")
     && xfer.nToken==4
    ){

      if( disableLogin ){
        g.perm.Read = g.perm.Write = g.perm.Private = g.perm.Admin = 1;
      }else{
        if( check_tail_hash(&xfer.aToken[2], xfer.pIn)
         || check_login(&xfer.aToken[1], &xfer.aToken[2], &xfer.aToken[3])
        ){
          cgi_reset_content();







>







1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
    ** The client has sent login credentials to the server.
    ** Validate the login.  This has to happen before anything else.
    ** The client can send multiple logins.  Permissions are cumulative.
    */
    if( blob_eq(&xfer.aToken[0], "login")
     && xfer.nToken==4
    ){
    handle_login_card:
      if( disableLogin ){
        g.perm.Read = g.perm.Write = g.perm.Private = g.perm.Admin = 1;
      }else{
        if( check_tail_hash(&xfer.aToken[2], xfer.pIn)
         || check_login(&xfer.aToken[1], &xfer.aToken[2], &xfer.aToken[3])
        ){
          cgi_reset_content();