| | @@ -506,5 +506,87 @@ |
| 506 | 506 | while( *z && n-- ){ |
| 507 | 507 | *z = zEncode[zDecode[(*z)&0x7f]&0x1f]; |
| 508 | 508 | z++; |
| 509 | 509 | } |
| 510 | 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 | +} |
| 511 | 593 | |