Fossil SCM

Obscure the text of the remote-url password so that it is not easily visible using the sqlite3 CLI.

drh 2010-10-08 10:59 trunk
Commit cfbbad3d480b0e2a656b1bff6f119e9e6a98bad4
+1 -1
--- src/configure.c
+++ src/configure.c
@@ -454,11 +454,11 @@
454454
}else{
455455
zServer = db_get("last-sync-url", 0);
456456
if( zServer==0 ){
457457
fossil_fatal("no server specified");
458458
}
459
- zPw = db_get("last-sync-pw", 0);
459
+ zPw = unobscure(db_get("last-sync-pw", 0));
460460
}
461461
url_parse(zServer);
462462
if( g.urlPasswd==0 && zPw ) g.urlPasswd = mprintf("%s", zPw);
463463
user_select();
464464
url_enable_proxy("via proxy: ");
465465
--- src/configure.c
+++ src/configure.c
@@ -454,11 +454,11 @@
454 }else{
455 zServer = db_get("last-sync-url", 0);
456 if( zServer==0 ){
457 fossil_fatal("no server specified");
458 }
459 zPw = db_get("last-sync-pw", 0);
460 }
461 url_parse(zServer);
462 if( g.urlPasswd==0 && zPw ) g.urlPasswd = mprintf("%s", zPw);
463 user_select();
464 url_enable_proxy("via proxy: ");
465
--- src/configure.c
+++ src/configure.c
@@ -454,11 +454,11 @@
454 }else{
455 zServer = db_get("last-sync-url", 0);
456 if( zServer==0 ){
457 fossil_fatal("no server specified");
458 }
459 zPw = unobscure(db_get("last-sync-pw", 0));
460 }
461 url_parse(zServer);
462 if( g.urlPasswd==0 && zPw ) g.urlPasswd = mprintf("%s", zPw);
463 user_select();
464 url_enable_proxy("via proxy: ");
465
+82
--- src/encode.c
+++ src/encode.c
@@ -506,5 +506,87 @@
506506
while( *z && n-- ){
507507
*z = zEncode[zDecode[(*z)&0x7f]&0x1f];
508508
z++;
509509
}
510510
}
511
+
512
+/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
513
+static const unsigned char aObscurer[16] = {
514
+ 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
515
+ 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
516
+};
517
+
518
+
519
+/*
520
+** Obscure plain text so that it is not easily readable.
521
+**
522
+** This is used for storing sensitive information (such as passwords) in a
523
+** way that prevents their exposure through idle browsing. This is not
524
+** encryption. Anybody who really wants the password can still get it.
525
+**
526
+** The text is XOR-ed with a repeating pattern then converted to hex.
527
+** Space to hold the returned string is obtained from malloc and should
528
+** be freed by the caller.
529
+*/
530
+char *obscure(const char *zIn){
531
+ int n, i;
532
+ unsigned char salt;
533
+ char *zOut;
534
+
535
+ n = strlen(zIn);
536
+ zOut = malloc( n*2+3 );
537
+ if( zOut==0 ) fossil_panic("out of memory");
538
+ sqlite3_randomness(1, &salt);
539
+ zOut[n+1] = (char)salt;
540
+ for(i=0; i<n; i++) zOut[i+n+2] = zIn[i]^aObscurer[i&0x0f]^salt;
541
+ encode16((unsigned char*)&zOut[n+1], (unsigned char*)zOut, n+1);
542
+ return zOut;
543
+}
544
+
545
+/*
546
+** Undo the obscuring of text performed by obscure(). Or, if the input is
547
+** not hexadecimal (meaning the input is not the output of obscure()) then
548
+** do the equivalent of strdup().
549
+**
550
+** The result is memory obtained from malloc that should be freed by the caller.
551
+*/
552
+char *unobscure(const char *zIn){
553
+ int n, i;
554
+ unsigned char salt;
555
+ char *zOut;
556
+
557
+ n = strlen(zIn);
558
+ zOut = malloc( n + 1 );
559
+ if( zOut==0 ) fossil_panic("out of memory");
560
+ if( n<2
561
+ || decode16((unsigned char*)zIn, &salt, 2)
562
+ || decode16((unsigned char*)&zIn[2], (unsigned char*)zOut, n-2)
563
+ ){
564
+ memcpy(zOut, zIn, n+1);
565
+ }else{
566
+ n = n/2 - 1;
567
+ for(i=0; i<n; i++) zOut[i] = zOut[i]^aObscurer[i&0x0f]^salt;
568
+ zOut[n] = 0;
569
+ }
570
+ return zOut;
571
+}
572
+
573
+/*
574
+** Command to test obscure() and unobscure(). These commands are also useful
575
+** utilities for decoding passwords found in the database.
576
+**
577
+** COMMAND: test-obscure
578
+*/
579
+void test_obscure_cmd(void){
580
+ int i;
581
+ char *z, *z2;
582
+ for(i=2; i<g.argc; i++){
583
+ z = obscure(g.argv[i]);
584
+ z2 = unobscure(z);
585
+ printf("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2);
586
+ free(z);
587
+ free(z2);
588
+ z = unobscure(g.argv[i]);
589
+ printf("UNOBSCURE: %s -> %s\n", g.argv[i], z);
590
+ free(z);
591
+ }
592
+}
511593
--- src/encode.c
+++ src/encode.c
@@ -506,5 +506,87 @@
506 while( *z && n-- ){
507 *z = zEncode[zDecode[(*z)&0x7f]&0x1f];
508 z++;
509 }
510 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
--- src/encode.c
+++ src/encode.c
@@ -506,5 +506,87 @@
506 while( *z && n-- ){
507 *z = zEncode[zDecode[(*z)&0x7f]&0x1f];
508 z++;
509 }
510 }
511
512 /* Randomness used for XOR-ing by the obscure() and unobscure() routines */
513 static const unsigned char aObscurer[16] = {
514 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
515 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
516 };
517
518
519 /*
520 ** Obscure plain text so that it is not easily readable.
521 **
522 ** This is used for storing sensitive information (such as passwords) in a
523 ** way that prevents their exposure through idle browsing. This is not
524 ** encryption. Anybody who really wants the password can still get it.
525 **
526 ** The text is XOR-ed with a repeating pattern then converted to hex.
527 ** Space to hold the returned string is obtained from malloc and should
528 ** be freed by the caller.
529 */
530 char *obscure(const char *zIn){
531 int n, i;
532 unsigned char salt;
533 char *zOut;
534
535 n = strlen(zIn);
536 zOut = malloc( n*2+3 );
537 if( zOut==0 ) fossil_panic("out of memory");
538 sqlite3_randomness(1, &salt);
539 zOut[n+1] = (char)salt;
540 for(i=0; i<n; i++) zOut[i+n+2] = zIn[i]^aObscurer[i&0x0f]^salt;
541 encode16((unsigned char*)&zOut[n+1], (unsigned char*)zOut, n+1);
542 return zOut;
543 }
544
545 /*
546 ** Undo the obscuring of text performed by obscure(). Or, if the input is
547 ** not hexadecimal (meaning the input is not the output of obscure()) then
548 ** do the equivalent of strdup().
549 **
550 ** The result is memory obtained from malloc that should be freed by the caller.
551 */
552 char *unobscure(const char *zIn){
553 int n, i;
554 unsigned char salt;
555 char *zOut;
556
557 n = strlen(zIn);
558 zOut = malloc( n + 1 );
559 if( zOut==0 ) fossil_panic("out of memory");
560 if( n<2
561 || decode16((unsigned char*)zIn, &salt, 2)
562 || decode16((unsigned char*)&zIn[2], (unsigned char*)zOut, n-2)
563 ){
564 memcpy(zOut, zIn, n+1);
565 }else{
566 n = n/2 - 1;
567 for(i=0; i<n; i++) zOut[i] = zOut[i]^aObscurer[i&0x0f]^salt;
568 zOut[n] = 0;
569 }
570 return zOut;
571 }
572
573 /*
574 ** Command to test obscure() and unobscure(). These commands are also useful
575 ** utilities for decoding passwords found in the database.
576 **
577 ** COMMAND: test-obscure
578 */
579 void test_obscure_cmd(void){
580 int i;
581 char *z, *z2;
582 for(i=2; i<g.argc; i++){
583 z = obscure(g.argv[i]);
584 z2 = unobscure(z);
585 printf("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2);
586 free(z);
587 free(z2);
588 z = unobscure(g.argv[i]);
589 printf("UNOBSCURE: %s -> %s\n", g.argv[i], z);
590 free(z);
591 }
592 }
593
+1 -1
--- src/http.c
+++ src/http.c
@@ -60,11 +60,11 @@
6060
zPw = 0;
6161
}else{
6262
/* Password failure while doing a sync from the command-line interface */
6363
url_prompt_for_password();
6464
zPw = g.urlPasswd;
65
- if( !g.dontKeepUrl ) db_set("last-sync-pw", zPw, 0);
65
+ if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0);
6666
}
6767
6868
/* The login card wants the SHA1 hash of the password, so convert the
6969
** password to its SHA1 hash it it isn't already a SHA1 hash.
7070
**
7171
--- src/http.c
+++ src/http.c
@@ -60,11 +60,11 @@
60 zPw = 0;
61 }else{
62 /* Password failure while doing a sync from the command-line interface */
63 url_prompt_for_password();
64 zPw = g.urlPasswd;
65 if( !g.dontKeepUrl ) db_set("last-sync-pw", zPw, 0);
66 }
67
68 /* The login card wants the SHA1 hash of the password, so convert the
69 ** password to its SHA1 hash it it isn't already a SHA1 hash.
70 **
71
--- src/http.c
+++ src/http.c
@@ -60,11 +60,11 @@
60 zPw = 0;
61 }else{
62 /* Password failure while doing a sync from the command-line interface */
63 url_prompt_for_password();
64 zPw = g.urlPasswd;
65 if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0);
66 }
67
68 /* The login card wants the SHA1 hash of the password, so convert the
69 ** password to its SHA1 hash it it isn't already a SHA1 hash.
70 **
71
+4 -4
--- src/sync.c
+++ src/sync.c
@@ -56,11 +56,11 @@
5656
}
5757
zUrl = db_get("last-sync-url", 0);
5858
if( zUrl==0 ){
5959
return; /* No default server */
6060
}
61
- zPw = db_get("last-sync-pw", 0);
61
+ zPw = unobscure(db_get("last-sync-pw", 0));
6262
url_parse(zUrl);
6363
if( g.urlUser!=0 && g.urlPasswd==0 ){
6464
g.urlPasswd = mprintf("%s", zPw);
6565
}
6666
if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
@@ -93,11 +93,11 @@
9393
url_proxy_options();
9494
db_find_and_open_repository(1);
9595
db_open_config(0);
9696
if( g.argc==2 ){
9797
zUrl = db_get("last-sync-url", 0);
98
- zPw = db_get("last-sync-pw", 0);
98
+ zPw = unobscure(db_get("last-sync-pw", 0));
9999
if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
100100
}else if( g.argc==3 ){
101101
zUrl = g.argv[2];
102102
}
103103
if( zUrl==0 ){
@@ -105,11 +105,11 @@
105105
usage("URL");
106106
}
107107
url_parse(zUrl);
108108
if( !g.dontKeepUrl ){
109109
db_set("last-sync-url", g.urlCanonical, 0);
110
- if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0);
110
+ if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
111111
}
112112
if( g.urlUser!=0 && g.urlPasswd==0 ){
113113
if( zPw==0 ){
114114
url_prompt_for_password();
115115
}else{
@@ -232,11 +232,11 @@
232232
if( g.urlUser && g.urlPasswd==0 ){
233233
url_prompt_for_password();
234234
}
235235
db_set("last-sync-url", g.urlCanonical, 0);
236236
if( g.urlPasswd ){
237
- db_set("last-sync-pw", g.urlPasswd, 0);
237
+ db_set("last-sync-pw", obscure(g.urlPasswd), 0);
238238
}else{
239239
db_unset("last-sync-pw", 0);
240240
}
241241
}
242242
}
243243
--- src/sync.c
+++ src/sync.c
@@ -56,11 +56,11 @@
56 }
57 zUrl = db_get("last-sync-url", 0);
58 if( zUrl==0 ){
59 return; /* No default server */
60 }
61 zPw = db_get("last-sync-pw", 0);
62 url_parse(zUrl);
63 if( g.urlUser!=0 && g.urlPasswd==0 ){
64 g.urlPasswd = mprintf("%s", zPw);
65 }
66 if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
@@ -93,11 +93,11 @@
93 url_proxy_options();
94 db_find_and_open_repository(1);
95 db_open_config(0);
96 if( g.argc==2 ){
97 zUrl = db_get("last-sync-url", 0);
98 zPw = db_get("last-sync-pw", 0);
99 if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
100 }else if( g.argc==3 ){
101 zUrl = g.argv[2];
102 }
103 if( zUrl==0 ){
@@ -105,11 +105,11 @@
105 usage("URL");
106 }
107 url_parse(zUrl);
108 if( !g.dontKeepUrl ){
109 db_set("last-sync-url", g.urlCanonical, 0);
110 if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0);
111 }
112 if( g.urlUser!=0 && g.urlPasswd==0 ){
113 if( zPw==0 ){
114 url_prompt_for_password();
115 }else{
@@ -232,11 +232,11 @@
232 if( g.urlUser && g.urlPasswd==0 ){
233 url_prompt_for_password();
234 }
235 db_set("last-sync-url", g.urlCanonical, 0);
236 if( g.urlPasswd ){
237 db_set("last-sync-pw", g.urlPasswd, 0);
238 }else{
239 db_unset("last-sync-pw", 0);
240 }
241 }
242 }
243
--- src/sync.c
+++ src/sync.c
@@ -56,11 +56,11 @@
56 }
57 zUrl = db_get("last-sync-url", 0);
58 if( zUrl==0 ){
59 return; /* No default server */
60 }
61 zPw = unobscure(db_get("last-sync-pw", 0));
62 url_parse(zUrl);
63 if( g.urlUser!=0 && g.urlPasswd==0 ){
64 g.urlPasswd = mprintf("%s", zPw);
65 }
66 if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
@@ -93,11 +93,11 @@
93 url_proxy_options();
94 db_find_and_open_repository(1);
95 db_open_config(0);
96 if( g.argc==2 ){
97 zUrl = db_get("last-sync-url", 0);
98 zPw = unobscure(db_get("last-sync-pw", 0));
99 if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
100 }else if( g.argc==3 ){
101 zUrl = g.argv[2];
102 }
103 if( zUrl==0 ){
@@ -105,11 +105,11 @@
105 usage("URL");
106 }
107 url_parse(zUrl);
108 if( !g.dontKeepUrl ){
109 db_set("last-sync-url", g.urlCanonical, 0);
110 if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
111 }
112 if( g.urlUser!=0 && g.urlPasswd==0 ){
113 if( zPw==0 ){
114 url_prompt_for_password();
115 }else{
@@ -232,11 +232,11 @@
232 if( g.urlUser && g.urlPasswd==0 ){
233 url_prompt_for_password();
234 }
235 db_set("last-sync-url", g.urlCanonical, 0);
236 if( g.urlPasswd ){
237 db_set("last-sync-pw", obscure(g.urlPasswd), 0);
238 }else{
239 db_unset("last-sync-pw", 0);
240 }
241 }
242 }
243

Keyboard Shortcuts

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