Fossil SCM

merged and conflict-resolved trunk [c0274f996266aef].

stephan 2011-10-04 23:40 UTC json-multitag-test merge
Commit 4fbf77d4f371c1960fb4524be3098834a421103c
+26
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311311
sz = szA<szB ? szA : szB;
312312
rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313313
if( rc==0 ){
314314
rc = szA - szB;
315315
}
316
+ return rc;
317
+}
318
+
319
+/*
320
+** Compare two blobs in constant time and return zero if they are equal.
321
+** Constant time comparison only applies for blobs of the same length.
322
+** If lengths are different, immediately returns 1.
323
+*/
324
+int blob_constant_time_cmp(Blob *pA, Blob *pB){
325
+ int szA, szB, i;
326
+ unsigned char *buf1, *buf2;
327
+ unsigned char rc = 0;
328
+
329
+ blob_is_init(pA);
330
+ blob_is_init(pB);
331
+ szA = blob_size(pA);
332
+ szB = blob_size(pB);
333
+ if( szA!=szB || szA==0 ) return 1;
334
+
335
+ buf1 = blob_buffer(pA);
336
+ buf2 = blob_buffer(pB);
337
+
338
+ for( i=0; i<szA; i++ ){
339
+ rc = rc | (buf1[i] ^ buf2[i]);
340
+ }
341
+
316342
return rc;
317343
}
318344
319345
/*
320346
** Compare a blob to a string. Return TRUE if they are equal.
321347
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311 sz = szA<szB ? szA : szB;
312 rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313 if( rc==0 ){
314 rc = szA - szB;
315 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316 return rc;
317 }
318
319 /*
320 ** Compare a blob to a string. Return TRUE if they are equal.
321
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311 sz = szA<szB ? szA : szB;
312 rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313 if( rc==0 ){
314 rc = szA - szB;
315 }
316 return rc;
317 }
318
319 /*
320 ** Compare two blobs in constant time and return zero if they are equal.
321 ** Constant time comparison only applies for blobs of the same length.
322 ** If lengths are different, immediately returns 1.
323 */
324 int blob_constant_time_cmp(Blob *pA, Blob *pB){
325 int szA, szB, i;
326 unsigned char *buf1, *buf2;
327 unsigned char rc = 0;
328
329 blob_is_init(pA);
330 blob_is_init(pB);
331 szA = blob_size(pA);
332 szB = blob_size(pB);
333 if( szA!=szB || szA==0 ) return 1;
334
335 buf1 = blob_buffer(pA);
336 buf2 = blob_buffer(pB);
337
338 for( i=0; i<szA; i++ ){
339 rc = rc | (buf1[i] ^ buf2[i]);
340 }
341
342 return rc;
343 }
344
345 /*
346 ** Compare a blob to a string. Return TRUE if they are equal.
347
+26
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311311
sz = szA<szB ? szA : szB;
312312
rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313313
if( rc==0 ){
314314
rc = szA - szB;
315315
}
316
+ return rc;
317
+}
318
+
319
+/*
320
+** Compare two blobs in constant time and return zero if they are equal.
321
+** Constant time comparison only applies for blobs of the same length.
322
+** If lengths are different, immediately returns 1.
323
+*/
324
+int blob_constant_time_cmp(Blob *pA, Blob *pB){
325
+ int szA, szB, i;
326
+ unsigned char *buf1, *buf2;
327
+ unsigned char rc = 0;
328
+
329
+ blob_is_init(pA);
330
+ blob_is_init(pB);
331
+ szA = blob_size(pA);
332
+ szB = blob_size(pB);
333
+ if( szA!=szB || szA==0 ) return 1;
334
+
335
+ buf1 = blob_buffer(pA);
336
+ buf2 = blob_buffer(pB);
337
+
338
+ for( i=0; i<szA; i++ ){
339
+ rc = rc | (buf1[i] ^ buf2[i]);
340
+ }
341
+
316342
return rc;
317343
}
318344
319345
/*
320346
** Compare a blob to a string. Return TRUE if they are equal.
321347
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311 sz = szA<szB ? szA : szB;
312 rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313 if( rc==0 ){
314 rc = szA - szB;
315 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316 return rc;
317 }
318
319 /*
320 ** Compare a blob to a string. Return TRUE if they are equal.
321
--- src/blob.c
+++ src/blob.c
@@ -311,10 +311,36 @@
311 sz = szA<szB ? szA : szB;
312 rc = memcmp(blob_buffer(pA), blob_buffer(pB), sz);
313 if( rc==0 ){
314 rc = szA - szB;
315 }
316 return rc;
317 }
318
319 /*
320 ** Compare two blobs in constant time and return zero if they are equal.
321 ** Constant time comparison only applies for blobs of the same length.
322 ** If lengths are different, immediately returns 1.
323 */
324 int blob_constant_time_cmp(Blob *pA, Blob *pB){
325 int szA, szB, i;
326 unsigned char *buf1, *buf2;
327 unsigned char rc = 0;
328
329 blob_is_init(pA);
330 blob_is_init(pB);
331 szA = blob_size(pA);
332 szB = blob_size(pB);
333 if( szA!=szB || szA==0 ) return 1;
334
335 buf1 = blob_buffer(pA);
336 buf2 = blob_buffer(pB);
337
338 for( i=0; i<szA; i++ ){
339 rc = rc | (buf1[i] ^ buf2[i]);
340 }
341
342 return rc;
343 }
344
345 /*
346 ** Compare a blob to a string. Return TRUE if they are equal.
347
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325325
*/
326326
/*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327327
time_t expires = time(0) + 604800;
328328
fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329329
}else{
330
- fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n");
330
+ fprintf(g.httpOut, "Cache-control: no-cache\r\n");
331331
}
332332
333333
/* Content intended for logged in users should only be cached in
334334
** the browser, not some shared location.
335335
*/
336336
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325 */
326 /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327 time_t expires = time(0) + 604800;
328 fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329 }else{
330 fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n");
331 }
332
333 /* Content intended for logged in users should only be cached in
334 ** the browser, not some shared location.
335 */
336
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325 */
326 /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327 time_t expires = time(0) + 604800;
328 fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329 }else{
330 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
331 }
332
333 /* Content intended for logged in users should only be cached in
334 ** the browser, not some shared location.
335 */
336
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325325
*/
326326
/*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327327
time_t expires = time(0) + 604800;
328328
fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329329
}else{
330
- fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n");
330
+ fprintf(g.httpOut, "Cache-control: no-cache\r\n");
331331
}
332332
333333
/* Content intended for logged in users should only be cached in
334334
** the browser, not some shared location.
335335
*/
336336
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325 */
326 /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327 time_t expires = time(0) + 604800;
328 fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329 }else{
330 fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n");
331 }
332
333 /* Content intended for logged in users should only be cached in
334 ** the browser, not some shared location.
335 */
336
--- src/cgi.c
+++ src/cgi.c
@@ -325,11 +325,11 @@
325 */
326 /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
327 time_t expires = time(0) + 604800;
328 fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
329 }else{
330 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
331 }
332
333 /* Content intended for logged in users should only be cached in
334 ** the browser, not some shared location.
335 */
336
+43 -9
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380380
}
381381
if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382382
/* The user requests a password change */
383383
zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384384
if( db_int(1, "SELECT 0 FROM user"
385
- " WHERE uid=%d AND (pw=%Q OR pw=%Q)",
386
- g.userUid, zPasswd, zSha1Pw) ){
385
+ " WHERE uid=%d"
386
+ " AND (constant_time_cmp(pw,%Q)=0"
387
+ " OR constant_time_cmp(pw,%Q)=0)",
388
+ g.userUid, zSha1Pw, zPasswd) ){
387389
sleep(1);
388390
zErrMsg =
389391
@ <p><span class="loginError">
390392
@ You entered an incorrect old password while attempting to change
391393
@ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
556558
@ </table>
557559
@ </form>
558560
}
559561
style_footer();
560562
}
563
+
564
+/*
565
+** SQL function for constant time comparison of two values.
566
+** Sets result to 0 if two values are equal.
567
+*/
568
+static void constant_time_cmp_function(
569
+ sqlite3_context *context,
570
+ int argc,
571
+ sqlite3_value **argv
572
+){
573
+ const unsigned char *buf1, *buf2;
574
+ int len, i;
575
+ unsigned char rc = 0;
576
+
577
+ assert( argc==2 );
578
+ len = sqlite3_value_bytes(argv[0]);
579
+ if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
580
+ rc = 1;
581
+ }else{
582
+ buf1 = sqlite3_value_text(argv[0]);
583
+ buf2 = sqlite3_value_text(argv[1]);
584
+ for( i=0; i<len; i++ ){
585
+ rc = rc | (buf1[i] ^ buf2[i]);
586
+ }
587
+ }
588
+ sqlite3_result_int(context, rc);
589
+}
561590
562591
/*
563592
** Attempt to find login credentials for user zLogin on a peer repository
564593
** with project code zCode. Transfer those credentials to the local
565594
** repository.
@@ -586,20 +615,22 @@
586615
if( zOtherRepo==0 ) return 0; /* No such peer repository */
587616
588617
rc = sqlite3_open(zOtherRepo, &pOther);
589618
if( rc==SQLITE_OK ){
590619
sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
620
+ sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0,
621
+ constant_time_cmp_function, 0, 0);
591622
sqlite3_busy_timeout(pOther, 5000);
592623
zSQL = mprintf(
593624
"SELECT cexpire FROM user"
594
- " WHERE cookie=%Q"
625
+ " WHERE login=%Q"
595626
" AND ipaddr=%Q"
596
- " AND login=%Q"
597627
" AND length(cap)>0"
598628
" AND length(pw)>0"
599
- " AND cexpire>julianday('now')",
600
- zHash, zRemoteAddr, zLogin
629
+ " AND cexpire>julianday('now')"
630
+ " AND constant_time_cmp(cookie,%Q)=0",
631
+ zLogin, zRemoteAddr, zHash
601632
);
602633
pStmt = 0;
603634
rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
604635
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
605636
db_multi_exec(
@@ -636,16 +667,16 @@
636667
if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
637668
if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
638669
uid = db_int(0,
639670
"SELECT uid FROM user"
640671
" WHERE login=%Q"
641
- " AND cookie=%Q"
642672
" AND ipaddr=%Q"
643673
" AND cexpire>julianday('now')"
644674
" AND length(cap)>0"
645
- " AND length(pw)>0",
646
- zLogin, zCookie, zRemoteAddr
675
+ " AND length(pw)>0"
676
+ " AND constant_time_cmp(cookie,%Q)=0",
677
+ zLogin, zRemoteAddr, zCookie
647678
);
648679
return uid;
649680
}
650681
651682
/*
@@ -661,10 +692,13 @@
661692
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
662693
const char *zCap = 0; /* Capability string */
663694
664695
/* Only run this check once. */
665696
if( g.userUid!=0 ) return;
697
+
698
+ sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
699
+ constant_time_cmp_function, 0, 0);
666700
667701
/* If the HTTP connection is coming over 127.0.0.1 and if
668702
** local login is disabled and if we are using HTTP and not HTTPS,
669703
** then there is no need to check user credentials.
670704
**
671705
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380 }
381 if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382 /* The user requests a password change */
383 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384 if( db_int(1, "SELECT 0 FROM user"
385 " WHERE uid=%d AND (pw=%Q OR pw=%Q)",
386 g.userUid, zPasswd, zSha1Pw) ){
 
 
387 sleep(1);
388 zErrMsg =
389 @ <p><span class="loginError">
390 @ You entered an incorrect old password while attempting to change
391 @ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
556 @ </table>
557 @ </form>
558 }
559 style_footer();
560 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
562 /*
563 ** Attempt to find login credentials for user zLogin on a peer repository
564 ** with project code zCode. Transfer those credentials to the local
565 ** repository.
@@ -586,20 +615,22 @@
586 if( zOtherRepo==0 ) return 0; /* No such peer repository */
587
588 rc = sqlite3_open(zOtherRepo, &pOther);
589 if( rc==SQLITE_OK ){
590 sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
 
 
591 sqlite3_busy_timeout(pOther, 5000);
592 zSQL = mprintf(
593 "SELECT cexpire FROM user"
594 " WHERE cookie=%Q"
595 " AND ipaddr=%Q"
596 " AND login=%Q"
597 " AND length(cap)>0"
598 " AND length(pw)>0"
599 " AND cexpire>julianday('now')",
600 zHash, zRemoteAddr, zLogin
 
601 );
602 pStmt = 0;
603 rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
604 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
605 db_multi_exec(
@@ -636,16 +667,16 @@
636 if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
637 if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
638 uid = db_int(0,
639 "SELECT uid FROM user"
640 " WHERE login=%Q"
641 " AND cookie=%Q"
642 " AND ipaddr=%Q"
643 " AND cexpire>julianday('now')"
644 " AND length(cap)>0"
645 " AND length(pw)>0",
646 zLogin, zCookie, zRemoteAddr
 
647 );
648 return uid;
649 }
650
651 /*
@@ -661,10 +692,13 @@
661 char *zRemoteAddr; /* Abbreviated IP address of the requestor */
662 const char *zCap = 0; /* Capability string */
663
664 /* Only run this check once. */
665 if( g.userUid!=0 ) return;
 
 
 
666
667 /* If the HTTP connection is coming over 127.0.0.1 and if
668 ** local login is disabled and if we are using HTTP and not HTTPS,
669 ** then there is no need to check user credentials.
670 **
671
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380 }
381 if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382 /* The user requests a password change */
383 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384 if( db_int(1, "SELECT 0 FROM user"
385 " WHERE uid=%d"
386 " AND (constant_time_cmp(pw,%Q)=0"
387 " OR constant_time_cmp(pw,%Q)=0)",
388 g.userUid, zSha1Pw, zPasswd) ){
389 sleep(1);
390 zErrMsg =
391 @ <p><span class="loginError">
392 @ You entered an incorrect old password while attempting to change
393 @ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
558 @ </table>
559 @ </form>
560 }
561 style_footer();
562 }
563
564 /*
565 ** SQL function for constant time comparison of two values.
566 ** Sets result to 0 if two values are equal.
567 */
568 static void constant_time_cmp_function(
569 sqlite3_context *context,
570 int argc,
571 sqlite3_value **argv
572 ){
573 const unsigned char *buf1, *buf2;
574 int len, i;
575 unsigned char rc = 0;
576
577 assert( argc==2 );
578 len = sqlite3_value_bytes(argv[0]);
579 if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
580 rc = 1;
581 }else{
582 buf1 = sqlite3_value_text(argv[0]);
583 buf2 = sqlite3_value_text(argv[1]);
584 for( i=0; i<len; i++ ){
585 rc = rc | (buf1[i] ^ buf2[i]);
586 }
587 }
588 sqlite3_result_int(context, rc);
589 }
590
591 /*
592 ** Attempt to find login credentials for user zLogin on a peer repository
593 ** with project code zCode. Transfer those credentials to the local
594 ** repository.
@@ -586,20 +615,22 @@
615 if( zOtherRepo==0 ) return 0; /* No such peer repository */
616
617 rc = sqlite3_open(zOtherRepo, &pOther);
618 if( rc==SQLITE_OK ){
619 sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
620 sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0,
621 constant_time_cmp_function, 0, 0);
622 sqlite3_busy_timeout(pOther, 5000);
623 zSQL = mprintf(
624 "SELECT cexpire FROM user"
625 " WHERE login=%Q"
626 " AND ipaddr=%Q"
 
627 " AND length(cap)>0"
628 " AND length(pw)>0"
629 " AND cexpire>julianday('now')"
630 " AND constant_time_cmp(cookie,%Q)=0",
631 zLogin, zRemoteAddr, zHash
632 );
633 pStmt = 0;
634 rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
635 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
636 db_multi_exec(
@@ -636,16 +667,16 @@
667 if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
668 if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
669 uid = db_int(0,
670 "SELECT uid FROM user"
671 " WHERE login=%Q"
 
672 " AND ipaddr=%Q"
673 " AND cexpire>julianday('now')"
674 " AND length(cap)>0"
675 " AND length(pw)>0"
676 " AND constant_time_cmp(cookie,%Q)=0",
677 zLogin, zRemoteAddr, zCookie
678 );
679 return uid;
680 }
681
682 /*
@@ -661,10 +692,13 @@
692 char *zRemoteAddr; /* Abbreviated IP address of the requestor */
693 const char *zCap = 0; /* Capability string */
694
695 /* Only run this check once. */
696 if( g.userUid!=0 ) return;
697
698 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
699 constant_time_cmp_function, 0, 0);
700
701 /* If the HTTP connection is coming over 127.0.0.1 and if
702 ** local login is disabled and if we are using HTTP and not HTTPS,
703 ** then there is no need to check user credentials.
704 **
705
+43 -9
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380380
}
381381
if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382382
/* The user requests a password change */
383383
zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384384
if( db_int(1, "SELECT 0 FROM user"
385
- " WHERE uid=%d AND (pw=%Q OR pw=%Q)",
386
- g.userUid, zPasswd, zSha1Pw) ){
385
+ " WHERE uid=%d"
386
+ " AND (constant_time_cmp(pw,%Q)=0"
387
+ " OR constant_time_cmp(pw,%Q)=0)",
388
+ g.userUid, zSha1Pw, zPasswd) ){
387389
sleep(1);
388390
zErrMsg =
389391
@ <p><span class="loginError">
390392
@ You entered an incorrect old password while attempting to change
391393
@ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
556558
@ </table>
557559
@ </form>
558560
}
559561
style_footer();
560562
}
563
+
564
+/*
565
+** SQL function for constant time comparison of two values.
566
+** Sets result to 0 if two values are equal.
567
+*/
568
+static void constant_time_cmp_function(
569
+ sqlite3_context *context,
570
+ int argc,
571
+ sqlite3_value **argv
572
+){
573
+ const unsigned char *buf1, *buf2;
574
+ int len, i;
575
+ unsigned char rc = 0;
576
+
577
+ assert( argc==2 );
578
+ len = sqlite3_value_bytes(argv[0]);
579
+ if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
580
+ rc = 1;
581
+ }else{
582
+ buf1 = sqlite3_value_text(argv[0]);
583
+ buf2 = sqlite3_value_text(argv[1]);
584
+ for( i=0; i<len; i++ ){
585
+ rc = rc | (buf1[i] ^ buf2[i]);
586
+ }
587
+ }
588
+ sqlite3_result_int(context, rc);
589
+}
561590
562591
/*
563592
** Attempt to find login credentials for user zLogin on a peer repository
564593
** with project code zCode. Transfer those credentials to the local
565594
** repository.
@@ -586,20 +615,22 @@
586615
if( zOtherRepo==0 ) return 0; /* No such peer repository */
587616
588617
rc = sqlite3_open(zOtherRepo, &pOther);
589618
if( rc==SQLITE_OK ){
590619
sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
620
+ sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0,
621
+ constant_time_cmp_function, 0, 0);
591622
sqlite3_busy_timeout(pOther, 5000);
592623
zSQL = mprintf(
593624
"SELECT cexpire FROM user"
594
- " WHERE cookie=%Q"
625
+ " WHERE login=%Q"
595626
" AND ipaddr=%Q"
596
- " AND login=%Q"
597627
" AND length(cap)>0"
598628
" AND length(pw)>0"
599
- " AND cexpire>julianday('now')",
600
- zHash, zRemoteAddr, zLogin
629
+ " AND cexpire>julianday('now')"
630
+ " AND constant_time_cmp(cookie,%Q)=0",
631
+ zLogin, zRemoteAddr, zHash
601632
);
602633
pStmt = 0;
603634
rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
604635
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
605636
db_multi_exec(
@@ -636,16 +667,16 @@
636667
if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
637668
if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
638669
uid = db_int(0,
639670
"SELECT uid FROM user"
640671
" WHERE login=%Q"
641
- " AND cookie=%Q"
642672
" AND ipaddr=%Q"
643673
" AND cexpire>julianday('now')"
644674
" AND length(cap)>0"
645
- " AND length(pw)>0",
646
- zLogin, zCookie, zRemoteAddr
675
+ " AND length(pw)>0"
676
+ " AND constant_time_cmp(cookie,%Q)=0",
677
+ zLogin, zRemoteAddr, zCookie
647678
);
648679
return uid;
649680
}
650681
651682
/*
@@ -661,10 +692,13 @@
661692
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
662693
const char *zCap = 0; /* Capability string */
663694
664695
/* Only run this check once. */
665696
if( g.userUid!=0 ) return;
697
+
698
+ sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
699
+ constant_time_cmp_function, 0, 0);
666700
667701
/* If the HTTP connection is coming over 127.0.0.1 and if
668702
** local login is disabled and if we are using HTTP and not HTTPS,
669703
** then there is no need to check user credentials.
670704
**
671705
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380 }
381 if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382 /* The user requests a password change */
383 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384 if( db_int(1, "SELECT 0 FROM user"
385 " WHERE uid=%d AND (pw=%Q OR pw=%Q)",
386 g.userUid, zPasswd, zSha1Pw) ){
 
 
387 sleep(1);
388 zErrMsg =
389 @ <p><span class="loginError">
390 @ You entered an incorrect old password while attempting to change
391 @ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
556 @ </table>
557 @ </form>
558 }
559 style_footer();
560 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
562 /*
563 ** Attempt to find login credentials for user zLogin on a peer repository
564 ** with project code zCode. Transfer those credentials to the local
565 ** repository.
@@ -586,20 +615,22 @@
586 if( zOtherRepo==0 ) return 0; /* No such peer repository */
587
588 rc = sqlite3_open(zOtherRepo, &pOther);
589 if( rc==SQLITE_OK ){
590 sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
 
 
591 sqlite3_busy_timeout(pOther, 5000);
592 zSQL = mprintf(
593 "SELECT cexpire FROM user"
594 " WHERE cookie=%Q"
595 " AND ipaddr=%Q"
596 " AND login=%Q"
597 " AND length(cap)>0"
598 " AND length(pw)>0"
599 " AND cexpire>julianday('now')",
600 zHash, zRemoteAddr, zLogin
 
601 );
602 pStmt = 0;
603 rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
604 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
605 db_multi_exec(
@@ -636,16 +667,16 @@
636 if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
637 if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
638 uid = db_int(0,
639 "SELECT uid FROM user"
640 " WHERE login=%Q"
641 " AND cookie=%Q"
642 " AND ipaddr=%Q"
643 " AND cexpire>julianday('now')"
644 " AND length(cap)>0"
645 " AND length(pw)>0",
646 zLogin, zCookie, zRemoteAddr
 
647 );
648 return uid;
649 }
650
651 /*
@@ -661,10 +692,13 @@
661 char *zRemoteAddr; /* Abbreviated IP address of the requestor */
662 const char *zCap = 0; /* Capability string */
663
664 /* Only run this check once. */
665 if( g.userUid!=0 ) return;
 
 
 
666
667 /* If the HTTP connection is coming over 127.0.0.1 and if
668 ** local login is disabled and if we are using HTTP and not HTTPS,
669 ** then there is no need to check user credentials.
670 **
671
--- src/login.c
+++ src/login.c
@@ -380,12 +380,14 @@
380 }
381 if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
382 /* The user requests a password change */
383 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
384 if( db_int(1, "SELECT 0 FROM user"
385 " WHERE uid=%d"
386 " AND (constant_time_cmp(pw,%Q)=0"
387 " OR constant_time_cmp(pw,%Q)=0)",
388 g.userUid, zSha1Pw, zPasswd) ){
389 sleep(1);
390 zErrMsg =
391 @ <p><span class="loginError">
392 @ You entered an incorrect old password while attempting to change
393 @ your password. Your password is unchanged.
@@ -556,10 +558,37 @@
558 @ </table>
559 @ </form>
560 }
561 style_footer();
562 }
563
564 /*
565 ** SQL function for constant time comparison of two values.
566 ** Sets result to 0 if two values are equal.
567 */
568 static void constant_time_cmp_function(
569 sqlite3_context *context,
570 int argc,
571 sqlite3_value **argv
572 ){
573 const unsigned char *buf1, *buf2;
574 int len, i;
575 unsigned char rc = 0;
576
577 assert( argc==2 );
578 len = sqlite3_value_bytes(argv[0]);
579 if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
580 rc = 1;
581 }else{
582 buf1 = sqlite3_value_text(argv[0]);
583 buf2 = sqlite3_value_text(argv[1]);
584 for( i=0; i<len; i++ ){
585 rc = rc | (buf1[i] ^ buf2[i]);
586 }
587 }
588 sqlite3_result_int(context, rc);
589 }
590
591 /*
592 ** Attempt to find login credentials for user zLogin on a peer repository
593 ** with project code zCode. Transfer those credentials to the local
594 ** repository.
@@ -586,20 +615,22 @@
615 if( zOtherRepo==0 ) return 0; /* No such peer repository */
616
617 rc = sqlite3_open(zOtherRepo, &pOther);
618 if( rc==SQLITE_OK ){
619 sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
620 sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0,
621 constant_time_cmp_function, 0, 0);
622 sqlite3_busy_timeout(pOther, 5000);
623 zSQL = mprintf(
624 "SELECT cexpire FROM user"
625 " WHERE login=%Q"
626 " AND ipaddr=%Q"
 
627 " AND length(cap)>0"
628 " AND length(pw)>0"
629 " AND cexpire>julianday('now')"
630 " AND constant_time_cmp(cookie,%Q)=0",
631 zLogin, zRemoteAddr, zHash
632 );
633 pStmt = 0;
634 rc = sqlite3_prepare_v2(pOther, zSQL, -1, &pStmt, 0);
635 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
636 db_multi_exec(
@@ -636,16 +667,16 @@
667 if( fossil_strcmp(zLogin, "developer")==0 ) return 0;
668 if( fossil_strcmp(zLogin, "reader")==0 ) return 0;
669 uid = db_int(0,
670 "SELECT uid FROM user"
671 " WHERE login=%Q"
 
672 " AND ipaddr=%Q"
673 " AND cexpire>julianday('now')"
674 " AND length(cap)>0"
675 " AND length(pw)>0"
676 " AND constant_time_cmp(cookie,%Q)=0",
677 zLogin, zRemoteAddr, zCookie
678 );
679 return uid;
680 }
681
682 /*
@@ -661,10 +692,13 @@
692 char *zRemoteAddr; /* Abbreviated IP address of the requestor */
693 const char *zCap = 0; /* Capability string */
694
695 /* Only run this check once. */
696 if( g.userUid!=0 ) return;
697
698 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
699 constant_time_cmp_function, 0, 0);
700
701 /* If the HTTP connection is coming over 127.0.0.1 and if
702 ** local login is disabled and if we are using HTTP and not HTTPS,
703 ** then there is no need to check user credentials.
704 **
705
+60
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298298
memset(&g.json, 0, sizeof(g.json));
299299
if(g.db){
300300
db_close(0);
301301
}
302302
}
303
+
304
+/*
305
+** Search g.argv for arguments "--args FILENAME". If found, then
306
+** (1) remove the two arguments from g.argv
307
+** (2) Read the file FILENAME
308
+** (3) Use the contents of FILE to replace the two removed arguments:
309
+** (a) Ignore blank lines in the file
310
+** (b) Each non-empty line of the file is an argument, except
311
+** (c) If the line begins with "-" and contains a space, it is broken
312
+** into two arguments at the space.
313
+*/
314
+static void expand_args_option(void){
315
+ Blob file = empty_blob; /* Content of the file */
316
+ Blob line = empty_blob; /* One line of the file */
317
+ unsigned int nLine; /* Number of lines in the file*/
318
+ unsigned int i, j, k; /* Loop counters */
319
+ int n; /* Number of bytes in one line */
320
+ char *z; /* General use string pointer */
321
+ char **newArgv; /* New expanded g.argv under construction */
322
+
323
+ for(i=1; i<g.argc-1; i++){
324
+ z = g.argv[i];
325
+ if( z[0]!='-' ) continue;
326
+ z++;
327
+ if( z[0]=='-' ) z++;
328
+ if( z[0]==0 ) return; /* Stop searching at "--" */
329
+ if( fossil_strcmp(z, "args")==0 ) break;
330
+ }
331
+ if( i>=g.argc-1 ) return;
332
+
333
+ blob_read_from_file(&file, g.argv[i+1]);
334
+ z = blob_str(&file);
335
+ for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
336
+ newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
337
+ for(j=0; j<i; j++) newArgv[j] = g.argv[j];
338
+
339
+ blob_rewind(&file);
340
+ while( (n = blob_line(&file, &line))>0 ){
341
+ if( n<=1 ) continue;
342
+ z = blob_buffer(&line);
343
+ z[n-1] = 0;
344
+ newArgv[j++] = z;
345
+ if( z[0]=='-' ){
346
+ for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
347
+ if( z[k] ){
348
+ z[k] = 0;
349
+ k++;
350
+ if( z[k] ) newArgv[j++] = &z[k];
351
+ }
352
+ }
353
+ }
354
+ i += 2;
355
+ while( i<g.argc ) newArgv[j++] = g.argv[i++];
356
+ newArgv[j] = 0;
357
+ g.argc = j;
358
+ g.argv = newArgv;
359
+}
303360
304361
/*
305362
** This procedure runs first.
306363
*/
307364
int main(int argc, char **argv){
@@ -324,10 +381,13 @@
324381
g.json.errorDetailParanoia = 0;
325382
#endif
326383
g.json.outOpt = cson_output_opt_empty;
327384
g.json.outOpt.addNewline = 1;
328385
g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
386
+ expand_args_option();
387
+ argc = g.argc;
388
+ argv = g.argv;
329389
for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
330390
if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
331391
zCmdName = "cgi";
332392
g.isHTTP = 1;
333393
}else if( argc<2 ){
334394
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298 memset(&g.json, 0, sizeof(g.json));
299 if(g.db){
300 db_close(0);
301 }
302 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
304 /*
305 ** This procedure runs first.
306 */
307 int main(int argc, char **argv){
@@ -324,10 +381,13 @@
324 g.json.errorDetailParanoia = 0;
325 #endif
326 g.json.outOpt = cson_output_opt_empty;
327 g.json.outOpt.addNewline = 1;
328 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
 
 
 
329 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
330 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
331 zCmdName = "cgi";
332 g.isHTTP = 1;
333 }else if( argc<2 ){
334
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298 memset(&g.json, 0, sizeof(g.json));
299 if(g.db){
300 db_close(0);
301 }
302 }
303
304 /*
305 ** Search g.argv for arguments "--args FILENAME". If found, then
306 ** (1) remove the two arguments from g.argv
307 ** (2) Read the file FILENAME
308 ** (3) Use the contents of FILE to replace the two removed arguments:
309 ** (a) Ignore blank lines in the file
310 ** (b) Each non-empty line of the file is an argument, except
311 ** (c) If the line begins with "-" and contains a space, it is broken
312 ** into two arguments at the space.
313 */
314 static void expand_args_option(void){
315 Blob file = empty_blob; /* Content of the file */
316 Blob line = empty_blob; /* One line of the file */
317 unsigned int nLine; /* Number of lines in the file*/
318 unsigned int i, j, k; /* Loop counters */
319 int n; /* Number of bytes in one line */
320 char *z; /* General use string pointer */
321 char **newArgv; /* New expanded g.argv under construction */
322
323 for(i=1; i<g.argc-1; i++){
324 z = g.argv[i];
325 if( z[0]!='-' ) continue;
326 z++;
327 if( z[0]=='-' ) z++;
328 if( z[0]==0 ) return; /* Stop searching at "--" */
329 if( fossil_strcmp(z, "args")==0 ) break;
330 }
331 if( i>=g.argc-1 ) return;
332
333 blob_read_from_file(&file, g.argv[i+1]);
334 z = blob_str(&file);
335 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
336 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
337 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
338
339 blob_rewind(&file);
340 while( (n = blob_line(&file, &line))>0 ){
341 if( n<=1 ) continue;
342 z = blob_buffer(&line);
343 z[n-1] = 0;
344 newArgv[j++] = z;
345 if( z[0]=='-' ){
346 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
347 if( z[k] ){
348 z[k] = 0;
349 k++;
350 if( z[k] ) newArgv[j++] = &z[k];
351 }
352 }
353 }
354 i += 2;
355 while( i<g.argc ) newArgv[j++] = g.argv[i++];
356 newArgv[j] = 0;
357 g.argc = j;
358 g.argv = newArgv;
359 }
360
361 /*
362 ** This procedure runs first.
363 */
364 int main(int argc, char **argv){
@@ -324,10 +381,13 @@
381 g.json.errorDetailParanoia = 0;
382 #endif
383 g.json.outOpt = cson_output_opt_empty;
384 g.json.outOpt.addNewline = 1;
385 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
386 expand_args_option();
387 argc = g.argc;
388 argv = g.argv;
389 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
390 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
391 zCmdName = "cgi";
392 g.isHTTP = 1;
393 }else if( argc<2 ){
394
+60
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298298
memset(&g.json, 0, sizeof(g.json));
299299
if(g.db){
300300
db_close(0);
301301
}
302302
}
303
+
304
+/*
305
+** Search g.argv for arguments "--args FILENAME". If found, then
306
+** (1) remove the two arguments from g.argv
307
+** (2) Read the file FILENAME
308
+** (3) Use the contents of FILE to replace the two removed arguments:
309
+** (a) Ignore blank lines in the file
310
+** (b) Each non-empty line of the file is an argument, except
311
+** (c) If the line begins with "-" and contains a space, it is broken
312
+** into two arguments at the space.
313
+*/
314
+static void expand_args_option(void){
315
+ Blob file = empty_blob; /* Content of the file */
316
+ Blob line = empty_blob; /* One line of the file */
317
+ unsigned int nLine; /* Number of lines in the file*/
318
+ unsigned int i, j, k; /* Loop counters */
319
+ int n; /* Number of bytes in one line */
320
+ char *z; /* General use string pointer */
321
+ char **newArgv; /* New expanded g.argv under construction */
322
+
323
+ for(i=1; i<g.argc-1; i++){
324
+ z = g.argv[i];
325
+ if( z[0]!='-' ) continue;
326
+ z++;
327
+ if( z[0]=='-' ) z++;
328
+ if( z[0]==0 ) return; /* Stop searching at "--" */
329
+ if( fossil_strcmp(z, "args")==0 ) break;
330
+ }
331
+ if( i>=g.argc-1 ) return;
332
+
333
+ blob_read_from_file(&file, g.argv[i+1]);
334
+ z = blob_str(&file);
335
+ for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
336
+ newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
337
+ for(j=0; j<i; j++) newArgv[j] = g.argv[j];
338
+
339
+ blob_rewind(&file);
340
+ while( (n = blob_line(&file, &line))>0 ){
341
+ if( n<=1 ) continue;
342
+ z = blob_buffer(&line);
343
+ z[n-1] = 0;
344
+ newArgv[j++] = z;
345
+ if( z[0]=='-' ){
346
+ for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
347
+ if( z[k] ){
348
+ z[k] = 0;
349
+ k++;
350
+ if( z[k] ) newArgv[j++] = &z[k];
351
+ }
352
+ }
353
+ }
354
+ i += 2;
355
+ while( i<g.argc ) newArgv[j++] = g.argv[i++];
356
+ newArgv[j] = 0;
357
+ g.argc = j;
358
+ g.argv = newArgv;
359
+}
303360
304361
/*
305362
** This procedure runs first.
306363
*/
307364
int main(int argc, char **argv){
@@ -324,10 +381,13 @@
324381
g.json.errorDetailParanoia = 0;
325382
#endif
326383
g.json.outOpt = cson_output_opt_empty;
327384
g.json.outOpt.addNewline = 1;
328385
g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
386
+ expand_args_option();
387
+ argc = g.argc;
388
+ argv = g.argv;
329389
for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
330390
if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
331391
zCmdName = "cgi";
332392
g.isHTTP = 1;
333393
}else if( argc<2 ){
334394
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298 memset(&g.json, 0, sizeof(g.json));
299 if(g.db){
300 db_close(0);
301 }
302 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
304 /*
305 ** This procedure runs first.
306 */
307 int main(int argc, char **argv){
@@ -324,10 +381,13 @@
324 g.json.errorDetailParanoia = 0;
325 #endif
326 g.json.outOpt = cson_output_opt_empty;
327 g.json.outOpt.addNewline = 1;
328 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
 
 
 
329 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
330 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
331 zCmdName = "cgi";
332 g.isHTTP = 1;
333 }else if( argc<2 ){
334
--- src/main.c
+++ src/main.c
@@ -298,10 +298,67 @@
298 memset(&g.json, 0, sizeof(g.json));
299 if(g.db){
300 db_close(0);
301 }
302 }
303
304 /*
305 ** Search g.argv for arguments "--args FILENAME". If found, then
306 ** (1) remove the two arguments from g.argv
307 ** (2) Read the file FILENAME
308 ** (3) Use the contents of FILE to replace the two removed arguments:
309 ** (a) Ignore blank lines in the file
310 ** (b) Each non-empty line of the file is an argument, except
311 ** (c) If the line begins with "-" and contains a space, it is broken
312 ** into two arguments at the space.
313 */
314 static void expand_args_option(void){
315 Blob file = empty_blob; /* Content of the file */
316 Blob line = empty_blob; /* One line of the file */
317 unsigned int nLine; /* Number of lines in the file*/
318 unsigned int i, j, k; /* Loop counters */
319 int n; /* Number of bytes in one line */
320 char *z; /* General use string pointer */
321 char **newArgv; /* New expanded g.argv under construction */
322
323 for(i=1; i<g.argc-1; i++){
324 z = g.argv[i];
325 if( z[0]!='-' ) continue;
326 z++;
327 if( z[0]=='-' ) z++;
328 if( z[0]==0 ) return; /* Stop searching at "--" */
329 if( fossil_strcmp(z, "args")==0 ) break;
330 }
331 if( i>=g.argc-1 ) return;
332
333 blob_read_from_file(&file, g.argv[i+1]);
334 z = blob_str(&file);
335 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
336 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
337 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
338
339 blob_rewind(&file);
340 while( (n = blob_line(&file, &line))>0 ){
341 if( n<=1 ) continue;
342 z = blob_buffer(&line);
343 z[n-1] = 0;
344 newArgv[j++] = z;
345 if( z[0]=='-' ){
346 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
347 if( z[k] ){
348 z[k] = 0;
349 k++;
350 if( z[k] ) newArgv[j++] = &z[k];
351 }
352 }
353 }
354 i += 2;
355 while( i<g.argc ) newArgv[j++] = g.argv[i++];
356 newArgv[j] = 0;
357 g.argc = j;
358 g.argv = newArgv;
359 }
360
361 /*
362 ** This procedure runs first.
363 */
364 int main(int argc, char **argv){
@@ -324,10 +381,13 @@
381 g.json.errorDetailParanoia = 0;
382 #endif
383 g.json.outOpt = cson_output_opt_empty;
384 g.json.outOpt.addNewline = 1;
385 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
386 expand_args_option();
387 argc = g.argc;
388 argv = g.argv;
389 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
390 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
391 zCmdName = "cgi";
392 g.isHTTP = 1;
393 }else if( argc<2 ){
394
+2 -2
--- src/xfer.c
+++ src/xfer.c
@@ -573,11 +573,11 @@
573573
blob_zero(&combined);
574574
blob_copy(&combined, pNonce);
575575
blob_append(&combined, blob_buffer(&pw), szPw);
576576
sha1sum_blob(&combined, &hash);
577577
assert( blob_size(&hash)==40 );
578
- rc = blob_compare(&hash, pSig);
578
+ rc = blob_constant_time_cmp(&hash, pSig);
579579
blob_reset(&hash);
580580
blob_reset(&combined);
581581
if( rc!=0 && szPw!=40 ){
582582
/* If this server stores cleartext passwords and the password did not
583583
** match, then perhaps the client is sending SHA1 passwords. Try
@@ -588,11 +588,11 @@
588588
blob_zero(&combined);
589589
blob_copy(&combined, pNonce);
590590
blob_append(&combined, zSecret, -1);
591591
free(zSecret);
592592
sha1sum_blob(&combined, &hash);
593
- rc = blob_compare(&hash, pSig);
593
+ rc = blob_constant_time_cmp(&hash, pSig);
594594
blob_reset(&hash);
595595
blob_reset(&combined);
596596
}
597597
if( rc==0 ){
598598
const char *zCap;
599599
--- src/xfer.c
+++ src/xfer.c
@@ -573,11 +573,11 @@
573 blob_zero(&combined);
574 blob_copy(&combined, pNonce);
575 blob_append(&combined, blob_buffer(&pw), szPw);
576 sha1sum_blob(&combined, &hash);
577 assert( blob_size(&hash)==40 );
578 rc = blob_compare(&hash, pSig);
579 blob_reset(&hash);
580 blob_reset(&combined);
581 if( rc!=0 && szPw!=40 ){
582 /* If this server stores cleartext passwords and the password did not
583 ** match, then perhaps the client is sending SHA1 passwords. Try
@@ -588,11 +588,11 @@
588 blob_zero(&combined);
589 blob_copy(&combined, pNonce);
590 blob_append(&combined, zSecret, -1);
591 free(zSecret);
592 sha1sum_blob(&combined, &hash);
593 rc = blob_compare(&hash, pSig);
594 blob_reset(&hash);
595 blob_reset(&combined);
596 }
597 if( rc==0 ){
598 const char *zCap;
599
--- src/xfer.c
+++ src/xfer.c
@@ -573,11 +573,11 @@
573 blob_zero(&combined);
574 blob_copy(&combined, pNonce);
575 blob_append(&combined, blob_buffer(&pw), szPw);
576 sha1sum_blob(&combined, &hash);
577 assert( blob_size(&hash)==40 );
578 rc = blob_constant_time_cmp(&hash, pSig);
579 blob_reset(&hash);
580 blob_reset(&combined);
581 if( rc!=0 && szPw!=40 ){
582 /* If this server stores cleartext passwords and the password did not
583 ** match, then perhaps the client is sending SHA1 passwords. Try
@@ -588,11 +588,11 @@
588 blob_zero(&combined);
589 blob_copy(&combined, pNonce);
590 blob_append(&combined, zSecret, -1);
591 free(zSecret);
592 sha1sum_blob(&combined, &hash);
593 rc = blob_constant_time_cmp(&hash, pSig);
594 blob_reset(&hash);
595 blob_reset(&combined);
596 }
597 if( rc==0 ){
598 const char *zCap;
599

Keyboard Shortcuts

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