123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- <?php
- declare(strict_types = 1);
-
- $ENV = ENV::go();
- require_once SERVER_ROOT.'/classes/twofa.class.php';
- require_once SERVER_ROOT.'/classes/u2f.class.php';
-
- $TwoFA = new TwoFactorAuth($ENV->SITE_NAME);
- $U2F = new u2f\U2F('https://'.SITE_DOMAIN);
-
- if ($Type = $_POST['type'] ?? false) {
- if ($Type === 'PGP') {
- if (!empty($_POST['publickey']) && (strpos($_POST['publickey'], 'BEGIN PGP PUBLIC KEY BLOCK') === false || strpos($_POST['publickey'], 'END PGP PUBLIC KEY BLOCK') === false)) {
- $Error = "Invalid PGP public key";
- } else {
- $DB->query("
- UPDATE users_main
- SET PublicKey = '".db_string($_POST['publickey'])."'
- WHERE ID = $UserID");
- $Message = 'Public key '.(empty($_POST['publickey']) ? 'removed' : 'updated') ;
- }
- }
-
- if ($Type === '2FA-E') {
- if ($TwoFA->verifyCode($_POST['twofasecret'], $_POST['twofa'])) {
- $DB->query("
- UPDATE users_main
- SET TwoFactor='".db_string($_POST['twofasecret'])."'
- WHERE ID = $UserID");
- $Message = "Two Factor Authentication enabled";
- } else {
- $Error = "Invalid 2FA verification code";
- }
- }
-
- if ($Type === '2FA-D') {
- $DB->query("
- UPDATE users_main
- SET TwoFactor = NULL
- WHERE ID = $UserID");
- $Message = "Two Factor Authentication disabled";
- }
-
- if ($Type === 'U2F-E') {
- try {
- $U2FReg = $U2F->doRegister(json_decode($_POST['u2f-request']), json_decode($_POST['u2f-response']));
- $DB->query("
- INSERT INTO u2f
- (UserID, KeyHandle, PublicKey, Certificate, Counter, Valid)
- Values ($UserID, '".db_string($U2FReg->keyHandle)."', '".db_string($U2FReg->publicKey)."', '".db_string($U2FReg->certificate)."', '".db_string($U2FReg->counter)."', '1')");
- $Message = "U2F token registered";
- } catch (Exception $e) {
- $Error = "Failed to register U2F token";
- }
- }
-
- if ($Type === 'U2F-D') {
- $DB->query("
- DELETE FROM u2f
- WHERE UserID = $UserID");
- $Message = 'U2F tokens deregistered';
- }
- }
-
- $U2FRegs = [];
- $DB->query("
- SELECT KeyHandle, PublicKey, Certificate, Counter
- FROM u2f
- WHERE UserID = $UserID");
-
- // Needs to be an array of objects, so we can't use to_array()
- while (list($KeyHandle, $PublicKey, $Certificate, $Counter) = $DB->next_record()) {
- $U2FRegs[] = (object)['keyHandle'=>$KeyHandle, 'publicKey'=>$PublicKey, 'certificate'=>$Certificate, 'counter'=>$Counter];
- }
-
- $DB->query("
- SELECT PublicKey, TwoFactor
- FROM users_main
- WHERE ID = $UserID");
-
- list($PublicKey, $TwoFactor) = $DB->next_record();
- list($U2FRequest, $U2FSigs) = $U2F->getRegisterData($U2FRegs);
- View::show_header("2FA Settings", 'u2f');
- ?>
-
- <h2>Additional Account Security Options</h2>
- <div>
- <?php if (isset($Message)) { ?>
- <div class="alertbar"><?=$Message?>
- </div>
- <?php }
-
- if (isset($Error)) { ?>
- <div class="alertbar error"><?=$Error?>
- </div>
- <?php } ?>
-
- <div class="box">
- <div class="head">
- <strong>PGP Public Key</strong>
- </div>
-
- <div class="pad">
- <?php if (empty($PublicKey)) {
- if (!empty($TwoFactor) || sizeof($U2FRegs) > 0) { ?>
- <strong class="important_text">
- You have a form of 2FA enabled but no PGP key associated with your account.
- If you lose access to your 2FA device, you will permanently lose access to your account.
- </strong>
- <?php } ?>
-
- <p>
- When setting up any form of second factor authentication, it is strongly recommended that you add your PGP
- public key as a form of secure recovery in the event that you lose access to your second factor device.
- </p>
-
- <p>
- After adding a PGP public key to your account, you will be able to disable your account's second factor
- protection by solving a challenge that only someone with your private key could solve.
- </p>
-
- <p>
- Additionally, being able to solve such a challenge when given manually by staff will suffice to provide proof of
- ownership of your account, provided no revocation certificate has been published for your key.
- </p>
-
- <p>
- Before adding your PGP public key, please make sure that you have taken the necessary precautions to protect it
- from loss (backup) or theft (revocation certificate).
- </p>
- <?php
- } else { ?>
- <p>
- The PGP public key associated with your account is shown below.
- </p>
-
- <p>
- This key can be used to create challenges that are only solvable by the holder of the related private key.
- Successfully solving these challenges is necessary for disabling any form of second factor authentication or
- proving ownership of this account to staff when you are unable to login.
- </p>
- <?php } ?>
-
- <form method="post">
- <input type="hidden" name="type" value="PGP">
- Public Key
- <br />
-
- <textarea name="publickey" id="publickey" spellcheck="false" cols="64"
- rows="8"><?=display_str($PublicKey)?></textarea>
- <br />
-
- <button type="submit" name="type" value="PGP">Update Public Key</button>
- </form>
- </div>
- </div>
-
- <div class="box">
- <div class="head">
- <strong>Two-Factor Authentication (2FA-TOTP)</strong>
- </div>
-
- <div class="pad">
- <?php $TwoFASecret = empty($TwoFactor) ? $TwoFA->createSecret() : $TwoFactor;
- if (empty($TwoFactor)) {
- if (sizeof($U2FRegs) === 0) { ?>
- <p>
- Two Factor Authentication is not currently enabled for this account.
- To enable it, add the secret key below to your 2FA client either manually or by scanning the QR code, then enter
- a verification code generated by your 2FA client and click the "Enable 2FA" button.
- </p>
-
- <form method="post">
- <input type="text" size="60" name="twofasecret" id="twofasecret"
- value="<?=$TwoFASecret?>" readonly><br>
- <img
- src="<?=$TwoFA->getQRCodeImageAsDataUri($ENV->SITE_NAME.':'.$LoggedUser['Username'], $TwoFASecret)?>" />
- <br />
-
- <input type="text" size="20" maxlength="6" pattern="[0-9]{0,6}" name="twofa" id="twofa"
- placeholder="Verification Code" autocomplete="off">
- <br /><br />
-
- <button type="submit" name="type" value="2FA-E">Enable 2FA</button>
- </form>
-
- <?php } else { ?>
- <p>
- Two Factor Authentication is not currently enabled for this account.
- To enable 2FA, you must first disable U2F below.
- </p>
- <?php }
- } else {?>
- <form method="post">
- <input type="hidden" name="type" value="2FA-D">
- <p>
- 2FA is enabled for this account with the following secret:
- </p>
-
- <p>
- <input type="text" size="50" name="twofasecret" id="twofasecret"
- value="<?=$TwoFASecret?>" onclick="this.select()"
- readonly />
- </p>
-
- <p>
- <img
- src="<?=$TwoFA->getQRCodeImageAsDataUri($ENV->SITE_NAME.':'.$LoggedUser['Username'], $TwoFASecret)?>" />
- </p>
-
- <p>
- To disable 2FA, click the button below.
- </p>
-
- <button type="submit" name="type" value="2FA-D">Disable 2FA</button>
- </form>
- <?php } ?>
- </div>
- </div>
-
- <div class="box">
- <div class="head">
- <strong>Universal Two Factor (FIDO U2F)</strong>
- </div>
-
- <div class="pad">
- <?php if (sizeof($U2FRegs) === 0) { ?>
- <?php if (empty($TwoFactor)) { ?>
- <form method="post" id="u2f_register_form">
- <input type="hidden" name="u2f-request"
- value='<?=json_encode($U2FRequest)?>' />
-
- <input type="hidden" name="u2f-sigs"
- value='<?=json_encode($U2FSigs)?>' />
-
- <input type="hidden" name="u2f-response" />
-
- <input type="hidden" value="U2F-E" />
- </form>
-
- <p>
- Universal Two Factor is not currently enabled for this account.
- To enable Universal Two Factor, plug in your U2F token and press the button on it.
- </p>
-
- <?php } else { ?>
- <p>
- Universal Two Factor is not currently enabled for this account.
- To enable Universal Two Factor, you must first disable normal 2FA above.
- </p>
- <?php } ?>
-
- <?php } else { ?>
- <form method="post" id="u2f_register_form">
- <input type="hidden" name="u2f-request"
- value='<?=json_encode($U2FRequest)?>' />
-
- <input type="hidden" name="u2f-sigs"
- value='<?=json_encode($U2FSigs)?>' />
-
- <input type="hidden" name="u2f-response" />
-
- <input type="hidden" value="U2F-E" />
-
- <p>
- Universal Two Factor is enabled.
- To add an additional U2F token, plug it in and press the button on it.
- To disable U2F completely and deregister all tokens, press the button below.
- </p>
- <button type="submit" name="type" value="U2F-D">Disable U2F</button>
- </form>
- <?php } ?>
- </div>
- </div>
- </div>
- <?php
- View::show_footer();
|