Diff
Not logged in

Differences From Artifact [de22332a94]:

To Artifact [4891650b6b]:


50
51
52
53
54
55
56
57
58

59

60
61

62
63
64
65
66
67
68
69
70
71

/*
** Construct the "login" card with the client credentials.
**
**       login LOGIN NONCE SIGNATURE
**
** The LOGIN is the user id of the client.  NONCE is the sha1 checksum
** of all payload that follows the login card.  Randomness for the NONCE 
** must be provided in the payload (in xfer.c).  SIGNATURE is the sha1

** checksum of the nonce followed by the user password.

**
** Write the constructed login card into pLogin.  pLogin is initialized

** by this routine.
*/
static void http_build_login_card(Blob *pPayload, Blob *pLogin){
  Blob nonce;          /* The nonce */
  const char *zLogin;  /* The user login name */
  const char *zPw;     /* The user password */
  Blob pw;             /* The nonce with user password appended */
  Blob sig;            /* The signature field */

  blob_zero(pLogin);







|
|
>
|
>

|
>
|

|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

/*
** Construct the "login" card with the client credentials.
**
**       login LOGIN NONCE SIGNATURE
**
** The LOGIN is the user id of the client.  NONCE is the sha1 checksum
** of all payload that follows the login card.  Randomness for the
** NONCE must be provided in the payload (in xfer.c) (e.g. by
** appending a timestamp or random bytes as a comment line to the
** payload).  SIGNATURE is the sha1 checksum of the nonce followed by
** the fossil-hashed version of the user's password.
**
** Write the constructed login card into pLogin. The result does not
** have an EOL added to it because which type of EOL it needs has to
** be determined later.  pLogin is initialized by this routine.
*/
static void http_build_login_card(Blob * const pPayload, Blob * const pLogin){
  Blob nonce;          /* The nonce */
  const char *zLogin;  /* The user login name */
  const char *zPw;     /* The user password */
  Blob pw;             /* The nonce with user password appended */
  Blob sig;            /* The signature field */

  blob_zero(pLogin);
126
127
128
129
130
131
132
133

134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  blob_reset(&sig);
  blob_reset(&nonce);
}

/*
** Construct an appropriate HTTP request header.  Write the header
** into pHdr.  This routine initializes the pHdr blob.  pPayload is
** the complete payload (including the login card) already compressed.

*/
static void http_build_header(
  Blob *pLogin,                /* Login card or NULL */
  Blob *pPayload,              /* the payload that will be sent */
  Blob *pHdr,                  /* construct the header here */

  const char *zAltMimetype     /* Alternative mimetype */
){
  int nPayload = pPayload ? blob_size(pPayload) : 0;

  blob_zero(pHdr);
  blob_appendf(pHdr, "%s %s%s HTTP/1.0\r\n",
               nPayload>0 ? "POST" : "GET", g.url.path,
               g.url.path[0]==0 ? "/" : "");
  if( g.url.proxyAuth ){
    blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth);
  }
  if( g.zHttpAuth && g.zHttpAuth[0] ){
    const char *zCredentials = g.zHttpAuth;
    char *zEncoded = encode64(zCredentials, -1);
    blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
    fossil_free(zEncoded);
  }
  blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname);
  blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
  if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
  if( pLogin ){
    blob_appendf(pHdr, "X-Fossil-Xfer-Login: %b\r\n", pLogin);
  }
  if( nPayload ){
    if( zAltMimetype ){
      blob_appendf(pHdr, "Content-Type: %s\r\n", zAltMimetype);
    }else if( g.fHttpTrace ){
      blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");







|
>


<


>




















|







129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  blob_reset(&sig);
  blob_reset(&nonce);
}

/*
** Construct an appropriate HTTP request header.  Write the header
** into pHdr.  This routine initializes the pHdr blob.  pPayload is
** the complete payload (including the login card if pLogin is NULL or
** empty) already compressed.
*/
static void http_build_header(

  Blob *pPayload,              /* the payload that will be sent */
  Blob *pHdr,                  /* construct the header here */
  Blob *pLogin,                /* Login card header value or NULL */
  const char *zAltMimetype     /* Alternative mimetype */
){
  int nPayload = pPayload ? blob_size(pPayload) : 0;

  blob_zero(pHdr);
  blob_appendf(pHdr, "%s %s%s HTTP/1.0\r\n",
               nPayload>0 ? "POST" : "GET", g.url.path,
               g.url.path[0]==0 ? "/" : "");
  if( g.url.proxyAuth ){
    blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth);
  }
  if( g.zHttpAuth && g.zHttpAuth[0] ){
    const char *zCredentials = g.zHttpAuth;
    char *zEncoded = encode64(zCredentials, -1);
    blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
    fossil_free(zEncoded);
  }
  blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname);
  blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
  if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
  if( pLogin && blob_size(pLogin) ){
    blob_appendf(pHdr, "X-Fossil-Xfer-Login: %b\r\n", pLogin);
  }
  if( nPayload ){
    if( zAltMimetype ){
      blob_appendf(pHdr, "Content-Type: %s\r\n", zAltMimetype);
    }else if( g.fHttpTrace ){
      blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
466
467
468
469
470
471
472
473
474






475

476





477
478

479
480
481
482

483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

  /* Construct the login card and prepare the complete payload */
  blob_zero(&login);
  if( blob_size(pSend)==0 ){
    blob_zero(&payload);
  }else{
    if( mHttpFlags & HTTP_USE_LOGIN ) http_build_login_card(pSend, &login);
#define TEST_LOGIN_HEADER 0 /* temporary dev/test/debug crutch */
#if TEST_LOGIN_HEADER






    if( g.fHttpTrace || (mHttpFlags & HTTP_NOCOMPRESS)!=0 ){

      /*blob_append(&payload, blob_buffer(pSend), blob_size(pSend));*/





      blob_zero(&payload);
      blob_swap(pSend, &payload);

    }else{
      blob_compress(pSend, &payload);
    }
#else

    if( blob_size(&login) ){
      blob_append_char(&login, '\n');
    }
    if( g.fHttpTrace || (mHttpFlags & HTTP_NOCOMPRESS)!=0 ){
      payload = login;
      login = empty_blob/*transfer ownership*/;
      blob_append(&payload, blob_buffer(pSend), blob_size(pSend));
    }else{
      blob_compress2(&login, pSend, &payload);
      blob_reset(&login);
    }
#endif

  }

  /* Construct the HTTP request header */
#if !TEST_LOGIN_HEADER
  http_build_header(0, &payload, &hdr, zAltMimetype);
#else
  http_build_header(blob_size(&login) ? &login : 0,
                    &payload, &hdr, zAltMimetype);
  blob_reset(&login);
#endif

  /* When tracing, write the transmitted HTTP message both to standard
  ** output and into a file.  The file can then be used to drive the
  ** server-side like this:
  **
  **      ./fossil test-http <http-request-1.txt
  */







<
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
<
>



<
<
<
<
|
<
<







470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514




515


516
517
518
519
520
521
522

  /* Construct the login card and prepare the complete payload */
  blob_zero(&login);
  if( blob_size(pSend)==0 ){
    blob_zero(&payload);
  }else{
    if( mHttpFlags & HTTP_USE_LOGIN ) http_build_login_card(pSend, &login);

#if 0
    fprintf(stderr, "# g.syncInfo.bLoginCardHeader=%d login card=%s\n",
            g.syncInfo.bLoginCardHeader,
            blob_size(&login) ? blob_str(&login) : "<empty>");
#endif
    if( g.syncInfo.bLoginCardHeader ) {
      /* Send the login card as an HTTP header. */
      if( g.fHttpTrace || (mHttpFlags & HTTP_NOCOMPRESS)!=0 ){
#if 1
        /*blob_append(&payload, blob_buffer(pSend), blob_size(pSend));*/
        blob_init(&payload, blob_buffer(pSend), blob_size(pSend));
#else
        /* This could save memory but looks like it would break in a
        ** couple of cases in the loop below where pSend is referenced
        ** for HTTP 401 and redirects. */
        blob_zero(&payload);
        blob_swap(pSend, &payload);
#endif
      }else{
        blob_compress(pSend, &payload);
      }
    }else{
      /* Prepend the login card (if set) to the payload */
      if( blob_size(&login) ){
        blob_append_char(&login, '\n');
      }
      if( g.fHttpTrace || (mHttpFlags & HTTP_NOCOMPRESS)!=0 ){
        payload = login;
        login = empty_blob/*transfer ownership*/;
        blob_append(&payload, blob_buffer(pSend), blob_size(pSend));
      }else{
        blob_compress2(&login, pSend, &payload);
        blob_reset(&login);
      }

    }
  }

  /* Construct the HTTP request header */




  http_build_header(&payload, &hdr, &login, zAltMimetype);



  /* When tracing, write the transmitted HTTP message both to standard
  ** output and into a file.  The file can then be used to drive the
  ** server-side like this:
  **
  **      ./fossil test-http <http-request-1.txt
  */