diff --git a/pool/email.php b/pool/email.php
index db4f5540..1e1d36f2 100644
--- a/pool/email.php
+++ b/pool/email.php
@@ -186,7 +186,7 @@ function twofaSetup($to, $whoip, $emailinfo)
return false;
$message = "2FA is ready to be tested.$eol";
- $message = "It will be enabled once you test it.$eol$eol";
+ $message .= "It will be enabled once you test it.$eol$eol";
$message .= $ret;
return sendnoheader($to, "2FA is Ready to be Enabled", $message, $emailinfo);
@@ -211,6 +211,46 @@ function twofaEnabled($to, $whoip, $emailinfo)
return sendnoheader($to, "2FA is Enabled", $message, $emailinfo);
}
#
+function twofaCancel($to, $whoip, $emailinfo)
+{
+ global $eol;
+
+ if (!isset($emailinfo['KWebURL']))
+ return false;
+
+ $web = $emailinfo['KWebURL'];
+
+ $ret = emailEnd('2fa change', $whoip, $emailinfo);
+ if ($ret === false)
+ return false;
+
+ $message = "2FA setup was cancelled on your account.$eol";
+ $message .= "You can set it up later if you want.$eol$eol";
+ $message .= $ret;
+
+ return sendnoheader($to, "2FA was Cancelled", $message, $emailinfo);
+}
+#
+function twofaRemove($to, $whoip, $emailinfo)
+{
+ global $eol;
+
+ if (!isset($emailinfo['KWebURL']))
+ return false;
+
+ $web = $emailinfo['KWebURL'];
+
+ $ret = emailEnd('2fa change', $whoip, $emailinfo);
+ if ($ret === false)
+ return false;
+
+ $message = "2FA was removed from your account.$eol";
+ $message .= "You can set it up again later if you want.$eol$eol";
+ $message .= $ret;
+
+ return sendnoheader($to, "2FA was Removed", $message, $emailinfo);
+}
+#
# getOpts required for email
# If they aren't all setup in the DB then email functions will return false
function emailOptList()
diff --git a/pool/page_2fa.php b/pool/page_2fa.php
index 4ec7330a..37e1ff2d 100644
--- a/pool/page_2fa.php
+++ b/pool/page_2fa.php
@@ -23,7 +23,6 @@ function set_2fa($data, $user, $tfa, $ans, $err)
$pg .= '
';
@@ -147,34 +160,52 @@ function set_2fa($data, $user, $tfa, $ans, $err)
#
function do2fa($data, $user)
{
+ $mailmode = '';
$err = '';
$setup = getparam('Setup', false);
- $testemail = false;
if ($setup === 'Setup')
{
// rand() included as part of the entropy
$ans = get2fa($user, 'setup', rand(1073741824,2147483647), 0);
- $testemail = true;
+ $mailmode = 'Setup';
}
else
{
- $value = getparam('Value', false);
- $test = getparam('Test', false);
- if ($test === 'Test' and $value !== null)
+ $can = getparam('Cancel', false);
+ if ($can === 'Cancel')
{
- $ans = get2fa($user, 'test', 0, $value);
- $testemail = true;
+ $ans = get2fa($user, 'untest', 0, 0);
+ $mailmode = 'Cancel';
}
else
{
- $nw = getparam('New', false);
- if ($nw === 'New' and $value !== null)
+ $value = getparam('Value', false);
+ $test = getparam('Test', false);
+ if ($test === 'Test' and $value !== null)
{
- $ans = get2fa($user, 'new', rand(1073741824,2147483647), $value);
- $testemail = true;
+ $ans = get2fa($user, 'test', 0, $value);
+ $mailmode = 'Test';
}
else
- $ans = get2fa($user, '', 0, 0);
+ {
+ $nw = getparam('New', false);
+ if ($nw === 'New' and $value !== null)
+ {
+ $ans = get2fa($user, 'new', rand(1073741824,2147483647), $value);
+ $mailmode = 'New';
+ }
+ else
+ {
+ $rem = getparam('Remove', false);
+ if ($rem === 'Remove' and $value !== null)
+ {
+ $ans = get2fa($user, 'remove', 0, $value);
+ $mailmode = 'Remove';
+ }
+ else
+ $ans = get2fa($user, '', 0, 0);
+ }
+ }
}
}
if ($ans['STATUS'] != 'ok')
@@ -184,7 +215,7 @@ function do2fa($data, $user)
if (isset($ans['2fa_error']))
$err = $ans['2fa_error'];
- if ($testemail and $err == '')
+ if ($mailmode != '' and $err == '')
{
$ans2 = userSettings($user);
if ($ans2['STATUS'] != 'ok')
@@ -199,12 +230,16 @@ function do2fa($data, $user)
$err = 'An error occurred, check your details below';
else
{
- if ($setup === 'Setup')
+ if ($mailmode === 'Setup')
twofaSetup($email, zeip(), $emailinfo);
- else if ($test === 'Test')
+ else if ($mailmode === 'Test')
twofaEnabled($email, zeip(), $emailinfo);
- else if ($nw === 'New')
+ else if ($mailmode === 'New')
twofaSetup($email, zeip(), $emailinfo);
+ else if ($mailmode === 'Cancel')
+ twofaCancel($email, zeip(), $emailinfo);
+ else if ($mailmode === 'Remove')
+ twofaRemove($email, zeip(), $emailinfo);
}
}
}
diff --git a/src/ckdb.h b/src/ckdb.h
index 7a5448be..fcb313c3 100644
--- a/src/ckdb.h
+++ b/src/ckdb.h
@@ -55,7 +55,7 @@
#define DB_VLOCK "1"
#define DB_VERSION "1.0.2"
-#define CKDB_VERSION DB_VERSION"-1.233"
+#define CKDB_VERSION DB_VERSION"-1.240"
#define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@@ -2633,6 +2633,7 @@ extern bool check_2fa(USERS *users, int32_t value);
extern bool tst_2fa(K_ITEM *old_u_item, int32_t value, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root);
extern K_ITEM *remove_2fa(K_ITEM *old_u_item, int32_t value, char *by,
- char *code, char *inet, tv_t *cd, K_TREE *trf_root);
+ char *code, char *inet, tv_t *cd, K_TREE *trf_root,
+ bool check);
#endif
diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c
index a94abd60..7ad2e25b 100644
--- a/src/ckdb_cmd.c
+++ b/src/ckdb_cmd.c
@@ -301,9 +301,24 @@ static char *cmd_2fa(__maybe_unused PGconn *conn, char *cmd, char *id,
else {
key = false;
sfa_status = "ok";
+ sfa_error = "2FA Enabled";
}
// Report sfa_error to web
ok = true;
+ } else if (strcmp(action, "untest") == 0) {
+ // Can't untest if it's not ready to test
+ if ((users->databits & (USER_TOTPAUTH | USER_TEST2FA))
+ != (USER_TOTPAUTH | USER_TEST2FA))
+ goto dame;
+ // since it's currently test, the value isn't required
+ u_new = remove_2fa(u_item, 0, by, code, inet, now,
+ trf_root, false);
+ if (u_new) {
+ ok = true;
+ sfa_status = EMPTY;
+ key = false;
+ sfa_error = "2FA Cancelled";
+ }
} else if (strcmp(action, "new") == 0) {
// Can't new if 2FA isn't already present -> setup
if ((users->databits & USER_TOTPAUTH) == 0)
@@ -329,18 +344,22 @@ static char *cmd_2fa(__maybe_unused PGconn *conn, char *cmd, char *id,
// Can't remove if 2FA isn't already present
if (!(users->databits & (USER_TOTPAUTH | USER_TEST2FA)))
goto dame;
+ // remove requires value
value = (int32_t)atoi(transfer_data(i_value));
if (!check_2fa(users, value)) {
sfa_error = "Invalid code";
// Report sfa_error to web
ok = true;
} else {
+ /* already tested 2fa so don't retest, also,
+ * a retest will fail using the same value */
u_new = remove_2fa(u_item, value, by, code,
- inet, now, trf_root);
+ inet, now, trf_root, false);
if (u_new) {
ok = true;
sfa_status = EMPTY;
key = false;
+ sfa_error = "2FA Removed";
}
}
}
diff --git a/src/ckdb_crypt.c b/src/ckdb_crypt.c
index d285e9ac..7ad0109f 100644
--- a/src/ckdb_crypt.c
+++ b/src/ckdb_crypt.c
@@ -237,14 +237,17 @@ bool tst_2fa(K_ITEM *old_u_item, int32_t value, char *by, char *code,
}
K_ITEM *remove_2fa(K_ITEM *old_u_item, int32_t value, char *by, char *code,
- char *inet, tv_t *cd, K_TREE *trf_root)
+ char *inet, tv_t *cd, K_TREE *trf_root, bool check)
{
K_ITEM *u_item = NULL;
USERS *old_users, *users;
- bool ok, did = false;
+ bool ok = true, did = false;
DATA_USERS(old_users, old_u_item);
- ok = check_2fa(old_users, value);
+ /* N.B. check_2fa will fail if it is called a second time
+ * with the same value */
+ if (check)
+ ok = check_2fa(old_users, value);
if (ok) {
K_WLOCK(users_free);
u_item = k_unlink_head(users_free);
|