Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add the ability to rotate the captcha-secret, setting up a new secret that is common to all members of a login-group. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
acfaf4e48e776d84222cdad6cda8dbb4 |
| User & Date: | drh 2024-08-23 14:43:53.675 |
Context
|
2024-08-23
| ||
| 15:42 | Improved instructions for setting a common captcha-secret across a login-group on the /setup_login_group page. check-in: 404f15501b user: drh tags: trunk | |
| 14:43 | Add the ability to rotate the captcha-secret, setting up a new secret that is common to all members of a login-group. check-in: acfaf4e48e user: drh tags: trunk | |
| 13:55 | Allow for multiple captcha-secret values. The primary is still 'captcha-secret'. Backups are in 'captcha-secret-N' where N is a small integer. The backups are only valid for 6 hours. This allows the captcha-secret to be changed without disrupting anonymous logins and/or captcha dialogs that are in progress when the secret changes. check-in: 8659d84aff user: drh tags: trunk | |
Changes
Changes to src/captcha.c.
| ︙ | ︙ | |||
506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
*/
unsigned int captcha_seed(void){
unsigned int x;
sqlite3_randomness(sizeof(x), &x);
x &= 0x7fffffff;
return x;
}
/*
** Return the value of the N-th more recent captcha-secret. The
** most recent captch-secret is 0. Others are prior captcha-secrets
** that have expired, but are retained for a limited period of time
** so that pending anonymous login cookies and/or captcha dialogs
** don't malfunction when the captcha-secret changes.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
*/
unsigned int captcha_seed(void){
unsigned int x;
sqlite3_randomness(sizeof(x), &x);
x &= 0x7fffffff;
return x;
}
/* The SQL that will rotate the the captcha-secret. */
static const char captchaSecretRotationSql[] =
@ SAVEPOINT rotate;
@ DELETE FROM config
@ WHERE name GLOB 'captcha-secret-*'
@ AND mtime<unixepoch('now','-6 hours');
@ UPDATE config
@ SET name=format('captcha-secret-%%d',substr(name,16)+1)
@ WHERE name GLOB 'captcha-secret-*';
@ UPDATE config
@ SET name='captcha-secret-1', mtime=unixepoch()
@ WHERE name='captcha-secret';
@ REPLACE INTO config(name,value,mtime)
@ VALUES('captcha-secret',%Q,unixepoch());
@ RELEASE rotate;
;
/*
** Create a new random captcha-secret. Rotate the old one into
** the captcha-secret-N backups. Purge captch-secret-N backups
** older than 6 hours.
**
** Do this on the current database and in all other databases of
** the same login group.
*/
void captcha_secret_rotate(void){
char *zNew = db_text(0, "SELECT lower(hex(randomblob(20)))");
char *zSql = mprintf(captchaSecretRotationSql/*works-like:"%Q"*/, zNew);
char *zErrs = 0;
fossil_free(zNew);
db_unprotect(PROTECT_CONFIG);
db_begin_transaction();
sqlite3_exec(g.db, zSql, 0, 0, &zErrs);
db_protect_pop();
if( zErrs && zErrs[0] ){
db_rollback_transaction();
fossil_fatal("Unable to rotate captcha-secret\n%s\nERROR: %s\n",
zSql, zErrs);
}
db_end_transaction(0);
login_group_sql(zSql, "", "", &zErrs);
if( zErrs ){
sqlite3_free(zErrs); /* Silently ignore errors on other repos */
}
fossil_free(zSql);
}
/*
** Return the value of the N-th more recent captcha-secret. The
** most recent captch-secret is 0. Others are prior captcha-secrets
** that have expired, but are retained for a limited period of time
** so that pending anonymous login cookies and/or captcha dialogs
** don't malfunction when the captcha-secret changes.
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
file_canonical_name(g.zRepositoryName, &fullName, 0);
zSelfRepo = fossil_strdup(blob_str(&fullName));
blob_reset(&fullName);
if( P("join")!=0 ){
login_group_join(zRepo, 1, zLogin, zPw, zNewName, &zErrMsg);
}else if( P("leave") ){
login_group_leave(&zErrMsg);
}
style_set_current_feature("setup");
style_header("Login Group Configuration");
if( zErrMsg ){
@ <p class="generalError">%s(zErrMsg)</p>
}
zGroup = login_group_name();
| > > | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
file_canonical_name(g.zRepositoryName, &fullName, 0);
zSelfRepo = fossil_strdup(blob_str(&fullName));
blob_reset(&fullName);
if( P("join")!=0 ){
login_group_join(zRepo, 1, zLogin, zPw, zNewName, &zErrMsg);
}else if( P("leave") ){
login_group_leave(&zErrMsg);
}else if( P("rotate") ){
captcha_secret_rotate();
}
style_set_current_feature("setup");
style_header("Login Group Configuration");
if( zErrMsg ){
@ <p class="generalError">%s(zErrMsg)</p>
}
zGroup = login_group_name();
|
| ︙ | ︙ | |||
847 848 849 850 851 852 853 |
@ <td>%h(zTitle)<td width="10"><td>%h(zRepo)</tr>
}
db_finalize(&q);
@ </table>
@
@ <p><form action="%R/setup_login_group" method="post"><div>
login_insert_csrf_secret();
| | > > > | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 |
@ <td>%h(zTitle)<td width="10"><td>%h(zRepo)</tr>
}
db_finalize(&q);
@ </table>
@
@ <p><form action="%R/setup_login_group" method="post"><div>
login_insert_csrf_secret();
@ <p>To leave this login group press:
@ <input type="submit" value="Leave Login Group" name="leave">
@ <p>To rotate the captcha-secret on all members of the login-group
@ so that they can all share anonymous logins, press:
@ <input type="submit" name="rotate" value="Rotate the captcha-secret">
@ </form></p>
}
@ <hr><h2>Implementation Details</h2>
@ <p>The following are fields from the CONFIG table related to login-groups.
@ </p>
@ <table border='1' cellspacing="0" cellpadding="4"\
@ class='sortable' data-column-types='ttt' data-init-sort='1'>
|
| ︙ | ︙ |