Fossil SCM

Add the fossil_random_password() utility function and use it to generate a stronger initial admin-user password in the "fossil new" command.

drh 2019-08-23 12:42 trunk
Commit 23a9f9bac2aaddb55e5d72689fcf4bb079306ac7411db269c1c44c8240455865
2 files changed +2 -2 +53
+2 -2
--- src/db.c
+++ src/db.c
@@ -2046,12 +2046,12 @@
20462046
}
20472047
db_multi_exec(
20482048
"INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser
20492049
);
20502050
db_multi_exec(
2051
- "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))"
2052
- " WHERE login=%Q", zUser
2051
+ "UPDATE user SET cap='s', pw=%Q"
2052
+ " WHERE login=%Q", fossil_random_password(10), zUser
20532053
);
20542054
if( !setupUserOnly ){
20552055
db_multi_exec(
20562056
"INSERT OR IGNORE INTO user(login,pw,cap,info)"
20572057
" VALUES('anonymous',hex(randomblob(8)),'hmnc','Anon');"
20582058
--- src/db.c
+++ src/db.c
@@ -2046,12 +2046,12 @@
2046 }
2047 db_multi_exec(
2048 "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser
2049 );
2050 db_multi_exec(
2051 "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))"
2052 " WHERE login=%Q", zUser
2053 );
2054 if( !setupUserOnly ){
2055 db_multi_exec(
2056 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2057 " VALUES('anonymous',hex(randomblob(8)),'hmnc','Anon');"
2058
--- src/db.c
+++ src/db.c
@@ -2046,12 +2046,12 @@
2046 }
2047 db_multi_exec(
2048 "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser
2049 );
2050 db_multi_exec(
2051 "UPDATE user SET cap='s', pw=%Q"
2052 " WHERE login=%Q", fossil_random_password(10), zUser
2053 );
2054 if( !setupUserOnly ){
2055 db_multi_exec(
2056 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2057 " VALUES('anonymous',hex(randomblob(8)),'hmnc','Anon');"
2058
+53
--- src/util.c
+++ src/util.c
@@ -525,5 +525,58 @@
525525
fossil_panic("pledge(\"%s\",NULL) fails with errno=%d",
526526
promises, (int)errno);
527527
}
528528
}
529529
#endif /* defined(HAVE_PLEDGE) */
530
+
531
+/*
532
+** Construct a random password and return it as a string. N is the
533
+** recommended number of characters for the password.
534
+**
535
+** Space to hold the returned string is obtained from fossil_malloc()
536
+** and should be freed by the caller.
537
+*/
538
+char *fossil_random_password(int N){
539
+ char zSrc[60];
540
+ int nSrc;
541
+ int i;
542
+ char z[60];
543
+
544
+ /* Source characters for the password. Omit characters like "0", "O",
545
+ ** "1" and "I" that might be easily confused */
546
+ static const char zAlphabet[] =
547
+ /* 0 1 2 3 4 5 */
548
+ /* 123456789 123456789 123456789 123456789 123456789 123456 */
549
+ "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
550
+
551
+ if( N<8 ) N = 8;
552
+ else if( N>sizeof(zAlphabet)-2 ) N = sizeof(zAlphabet)-2;
553
+ nSrc = sizeof(zAlphabet) - 1;
554
+ memcpy(zSrc, zAlphabet, nSrc);
555
+
556
+ for(i=0; i<N; i++){
557
+ unsigned r;
558
+ sqlite3_randomness(sizeof(r), &r);
559
+ r %= nSrc;
560
+ z[i] = zSrc[r];
561
+ zSrc[r] = zSrc[--nSrc];
562
+ }
563
+ z[i] = 0;
564
+ return fossil_strdup(z);
565
+}
566
+
567
+/*
568
+** COMMAND: test-random-password
569
+**
570
+** Usage: %fossil test-random-password ?N?
571
+**
572
+** Generate a random password string of approximately N characters in length.
573
+** If N is omitted, use 10. Values of N less than 8 are changed to 8
574
+** and greater than 55 and changed to 55.
575
+*/
576
+void test_random_password(void){
577
+ int N = 10;
578
+ if( g.argc>=3 ){
579
+ N = atoi(g.argv[2]);
580
+ }
581
+ fossil_print("%s\n", fossil_random_password(N));
582
+}
530583
--- src/util.c
+++ src/util.c
@@ -525,5 +525,58 @@
525 fossil_panic("pledge(\"%s\",NULL) fails with errno=%d",
526 promises, (int)errno);
527 }
528 }
529 #endif /* defined(HAVE_PLEDGE) */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
--- src/util.c
+++ src/util.c
@@ -525,5 +525,58 @@
525 fossil_panic("pledge(\"%s\",NULL) fails with errno=%d",
526 promises, (int)errno);
527 }
528 }
529 #endif /* defined(HAVE_PLEDGE) */
530
531 /*
532 ** Construct a random password and return it as a string. N is the
533 ** recommended number of characters for the password.
534 **
535 ** Space to hold the returned string is obtained from fossil_malloc()
536 ** and should be freed by the caller.
537 */
538 char *fossil_random_password(int N){
539 char zSrc[60];
540 int nSrc;
541 int i;
542 char z[60];
543
544 /* Source characters for the password. Omit characters like "0", "O",
545 ** "1" and "I" that might be easily confused */
546 static const char zAlphabet[] =
547 /* 0 1 2 3 4 5 */
548 /* 123456789 123456789 123456789 123456789 123456789 123456 */
549 "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
550
551 if( N<8 ) N = 8;
552 else if( N>sizeof(zAlphabet)-2 ) N = sizeof(zAlphabet)-2;
553 nSrc = sizeof(zAlphabet) - 1;
554 memcpy(zSrc, zAlphabet, nSrc);
555
556 for(i=0; i<N; i++){
557 unsigned r;
558 sqlite3_randomness(sizeof(r), &r);
559 r %= nSrc;
560 z[i] = zSrc[r];
561 zSrc[r] = zSrc[--nSrc];
562 }
563 z[i] = 0;
564 return fossil_strdup(z);
565 }
566
567 /*
568 ** COMMAND: test-random-password
569 **
570 ** Usage: %fossil test-random-password ?N?
571 **
572 ** Generate a random password string of approximately N characters in length.
573 ** If N is omitted, use 10. Values of N less than 8 are changed to 8
574 ** and greater than 55 and changed to 55.
575 */
576 void test_random_password(void){
577 int N = 10;
578 if( g.argc>=3 ){
579 N = atoi(g.argv[2]);
580 }
581 fossil_print("%s\n", fossil_random_password(N));
582 }
583

Keyboard Shortcuts

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