Browse Source

Add PGP keys to user profiles

spaghetti 8 years ago
parent
commit
43b5ec894d
2 changed files with 94 additions and 111 deletions
  1. 25
    14
      sections/user/edit.php
  2. 69
    97
      sections/user/take_edit.php

+ 25
- 14
sections/user/edit.php View File

@@ -9,6 +9,7 @@ $DB->query("
9 9
   SELECT
10 10
     m.Username,
11 11
     m.TwoFactor,
12
+    m.PublicKey,
12 13
     m.Email,
13 14
     m.IRCKey,
14 15
     m.Paranoia,
@@ -24,7 +25,7 @@ $DB->query("
24 25
     JOIN users_info AS i ON i.UserID = m.ID
25 26
     LEFT JOIN permissions AS p ON p.ID = m.PermissionID
26 27
   WHERE m.ID = '".db_string($UserID)."'");
27
-list($Username, $TwoFactor, $Email, $IRCKey, $Paranoia, $Info, $Avatar, $StyleID, $StyleURL, $SiteOptions, $UnseededAlerts, $Class, $InfoTitle) = $DB->next_record(MYSQLI_NUM, array(4, 9));
28
+list($Username, $TwoFactor, $PublicKey, $Email, $IRCKey, $Paranoia, $Info, $Avatar, $StyleID, $StyleURL, $SiteOptions, $UnseededAlerts, $Class, $InfoTitle) = $DB->next_record(MYSQLI_NUM, array(5, 10));
28 29
 
29 30
 $TwoFA = new TwoFactorAuth();
30 31
 
@@ -56,7 +57,7 @@ function checked($Checked) {
56 57
 }
57 58
 
58 59
 if ($SiteOptions) {
59
-  $SiteOptions = json_decode($SiteOptions, true);
60
+  $SiteOptions = json_decode($SiteOptions, true) ?? [];
60 61
 } else {
61 62
   $SiteOptions = [];
62 63
 }
@@ -162,13 +163,13 @@ echo $Val->GenerateJS('userform');
162 163
         <td class="label tooltip" title="Select changes that you want made to your chosen stylesheet"><strong>Stylesheet additions</strong></td>
163 164
         <td> <?
164 165
           foreach($Stylesheets as $Style) {
165
-            $StyleAdditions = explode('|',$Style['Additions']);
166
+            $StyleAdditions = explode('|', $Style['Additions']);
166 167
             ?> <ul class="nobullet style_addition<?=$Style['ID']==$Stylesheets[$LoggedUser['StyleID']]['ID']?'':' hidden'?>" id="style_addition_<?=$Style['Name']?>"> <?
167 168
             foreach($StyleAdditions as $i => $Addition) {
168 169
               if ($Addition) { ?>
169 170
                 <li>
170 171
                 <input type="checkbox" name="style_additions[]" value="<?=$Addition?>" id="addition_<?=$Addition?>"<?=(in_array($Addition, $SiteOptions['StyleAdditions']??[])?' checked="checked"':'')?>>
171
-                  <label for="addition_<?=$Addition?>"><?=explode('|',$Style['ProperAdditions'])[$i]?></label>
172
+                  <label for="addition_<?=$Addition?>"><?=explode('|', $Style['ProperAdditions'])[$i]?></label>
172 173
                 </li>
173 174
            <? }
174 175
             }
@@ -738,6 +739,15 @@ list($ArtistsAdded) = $DB->next_record();
738 739
           <strong>Access Settings</strong>
739 740
         </td>
740 741
       </tr>
742
+      <tr id="acc_currentpassword_tr">
743
+        <td class="label"><strong>Current Password</strong></td>
744
+        <td>
745
+          <div class="field_div">
746
+            <input type="password" size="40" name="cur_pass" id="cur_pass" maxlength="307200" value="" />
747
+          </div>
748
+          <strong class="important_text">When changing any of the settings in this section, you must enter your current password in this field before saving your changes</strong>
749
+        </td>
750
+      </tr>
741 751
       <tr id="acc_resetpk_tr">
742 752
         <td class="label tooltip_interactive" title="For information about the function of your passkey, please &lt;a href=&quot;<?=site_url()?>wiki.php?action=article&amp;amp;name=Passkey&quot;&gt;read this wiki article&lt;/a&gt;." data-title-plain="For information about the function of your passkey, please read the &quot;Passkey&quot; wiki article."><strong>Reset passkey</strong></td>
743 753
         <td>
@@ -754,7 +764,7 @@ list($ArtistsAdded) = $DB->next_record();
754 764
           <div class="field_div">
755 765
             <input type="text" size="50" name="irckey" id="irckey" value="<?=display_str($IRCKey)?>" />
756 766
           </div>
757
-          <p class="min_padding">If set, this key will be used instead of your site password when authenticating with <?=BOT_NICK?> on the <a href="wiki.php?action=article&amp;name=IRC">site's IRC network</a>. <span style="white-space: nowrap;">Please note:</span></p>
767
+          <p class="min_padding">This key will be used when authenticating with <?=BOT_NICK?> on the <a href="wiki.php?action=article&amp;name=IRC">site's IRC network</a>. <span style="white-space: nowrap;">Please note:</span></p>
758 768
           <ul>
759 769
             <li>This value is stored in plaintext and should not be your password.</li>
760 770
             <li>IRC keys must be between 6 and 32 characters.</li>
@@ -767,7 +777,14 @@ list($ArtistsAdded) = $DB->next_record();
767 777
           <div class="field_div">
768 778
             <input type="email" size="50" name="email" id="email" value="<?=display_str($Email)?>" />
769 779
           </div>
770
-          <p class="min_padding">When changing your email address, you must enter your current password in the "Current password" field before saving your changes.</p>
780
+        </td>
781
+      </tr>
782
+      <tr id="acc_publickey_tr">
783
+        <td class="label tooltip" title="This is your PGP public key. The matching private key can be used to prove ownership of your account should you lose access to your password or 2FA key. Only add a PGP key if you have taken proper precautions like creating a revocation certificate"><strong>PGP Public Key</strong></td>
784
+        <td>
785
+          <div class="field_div">
786
+            <textarea name="publickey" id="publickey" cols="64" rows="8"><?=display_str($PublicKey)?></textarea>
787
+          </div>
771 788
         </td>
772 789
       </tr>
773 790
       <tr id="acc_2fa_tr">
@@ -778,28 +795,22 @@ list($ArtistsAdded) = $DB->next_record();
778 795
             <? if (!empty($TwoFactor)) { ?>
779 796
             <p class="min_padding">2FA is enabled for this account with the following secret:</p>
780 797
             <? } ?>
781
-            <img src="<?=$TwoFA->getQRCodeImageAsDataUri(SITE_NAME, $TwoFASecret)?>">
798
+            <img src="<?=$TwoFA->getQRCodeImageAsDataUri(SITE_NAME, $TwoFASecret)?>"><br>
782 799
             <input type="text" size="20" name="twofasecret" id="twofasecret" value="<?=$TwoFASecret?>" readonly><br>
783 800
             <? if (empty($TwoFactor)) { ?>
784 801
             <input type="text" size="20" maxlength="6" name="twofa" id="twofa" placeholder="Verification Code">
785 802
             <p class="min_padding">To enable 2FA, scan the above QR code (or add the secret below it) to your 2FA client of choice, and enter a verification code it generates. Note that the verification code must not have expired when you save your profile.</p>
786
-            <p class="min_padding">When setting up 2FA, you must enter your current password in the "Current password" field before saving your changes.</p>
787 803
             <p class="min_padding"><strong class="important_text">WARNING</strong>: Losing your 2FA key can make your account unrecoverable. Only enable it if you're sure you can handle it.
788 804
             <? } else { ?>
789 805
             <label><input type="checkbox" name="disable2fa" id="disable2fa" />
790 806
             Disable 2FA</label>
791
-            <p class="min_padding">When disabling 2FA, you must enter your current password in the "Current Password" field before saving your changes</p>
792 807
             <? } ?>
793 808
           </div>
794 809
         </td>
795 810
       </tr>
796 811
       <tr id="acc_password_tr">
797
-        <td class="label"><strong>Change password</strong></td>
812
+        <td class="label"><strong>Password</strong></td>
798 813
         <td>
799
-          <div class="field_div">
800
-            <label>Current password:<br>
801
-            <input type="password" size="40" name="cur_pass" id="cur_pass" maxlength="307200" value="" /></label>
802
-          </div>
803 814
           <div class="field_div">
804 815
             <label>New password:<br />
805 816
             <input type="password" size="40" name="new_pass_1" id="new_pass_1" maxlength="307200" value="" /> <strong id="pass_strength"></strong></label>

+ 69
- 97
sections/user/take_edit.php View File

@@ -37,16 +37,13 @@ if (check_perms('site_advanced_search')) {
37 37
   $Val->SetFields('searchtype', 1, "number", "You forgot to select your default search preference.", ['minlength' => 0, 'maxlength' => 1]);
38 38
 }
39 39
 
40
-$Err = $Val->ValidateForm($_POST);
41
-
42
-if (!apcu_exists('DBKEY')) {
43
-  $Err = "Cannot edit profile until database fully decrypted.";
40
+$ValErr = $Val->ValidateForm($_POST);
41
+if ($ValErr) {
42
+  error($ValErr);
44 43
 }
45 44
 
46
-if ($Err) {
47
-  error($Err);
48
-  header("Location: user.php?action=edit&userid=$UserID");
49
-  die();
45
+if (!apcu_exists('DBKEY')) {
46
+  error("Cannot edit profile until database fully decrypted");
50 47
 }
51 48
 
52 49
 // Begin building $Paranoia
@@ -136,121 +133,96 @@ if (isset($_POST['p_donor_stats'])) {
136 133
 
137 134
 // End building $Paranoia
138 135
 
139
-
140
-// Email change
141 136
 $DB->query("
142
-  SELECT Email
137
+  SELECT Email, PassHash, TwoFactor, PublicKey, IRCKey
143 138
   FROM users_main
144 139
   WHERE ID = $UserID");
145
-list($CurEmail) = $DB->next_record();
140
+list($CurEmail, $CurPassHash, $CurTwoFA, $CurPublicKey, $CurIRCKey) = $DB->next_record();
141
+
142
+function require_password($Setting = false) {
143
+  global $CurPassHash;
144
+  if (empty($_POST['cur_pass'])) {
145
+    error('A setting you changed requires you to enter your current password'.($Setting ? ' (Setting: '.$Setting.')' : ''));
146
+  }
147
+  if (!Users::check_password($_POST['cur_pass'], $CurPassHash)) {
148
+    error('The password you entered was incorrect'.($Setting ? ' (Required by setting: '.$Setting.')' : ''));
149
+  }
150
+}
151
+
152
+// Email change
146 153
 $CurEmail = DBCrypt::decrypt($CurEmail);
147 154
 if ($CurEmail != $_POST['email']) {
148
-  if (!check_perms('users_edit_profiles')) { // Non-admins have to authenticate to change email
149
-    $DB->query("
150
-      SELECT PassHash
151
-      FROM users_main
152
-      WHERE ID = '".db_string($UserID)."'");
153
-    list($PassHash)=$DB->next_record();
154
-    if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
155
-      $Err = 'You did not enter the correct password.';
156
-    }
155
+
156
+  // Non-admins have to authenticate to change email
157
+  if (!check_perms('users_edit_profiles')) {
158
+    require_password("Change Email");
157 159
   }
158
-  if (!$Err) {
159
-    $NewEmail = db_string($_POST['email']);
160 160
 
161
+  $NewEmail = db_string($_POST['email']);
161 162
 
162
-    //This piece of code will update the time of their last email change to the current time *not* the current change.
163
-    $ChangerIP = db_string($LoggedUser['IP']);
164
-    $DB->query("
165
-      UPDATE users_history_emails
166
-      SET Time = '".sqltime()."'
167
-      WHERE UserID = '$UserID'
168
-        AND Time IS NULL");
169
-    $DB->query("
170
-      INSERT INTO users_history_emails
171
-        (UserID, Email, Time, IP)
172
-      VALUES
173
-        ('$UserID', '".DBCrypt::encrypt($NewEmail)."', NULL, '".DBCrypt::encrypt($_SERVER['REMOTE_ADDR'])."')");
163
+  // Update the time of their last email change to the current time *not* the current change.
164
+  $ChangerIP = db_string($LoggedUser['IP']);
165
+  $DB->query("
166
+    UPDATE users_history_emails
167
+    SET Time = '".sqltime()."'
168
+    WHERE UserID = '$UserID'
169
+      AND Time IS NULL");
170
+  $DB->query("
171
+    INSERT INTO users_history_emails
172
+      (UserID, Email, Time, IP)
173
+    VALUES
174
+      ('$UserID', '".DBCrypt::encrypt($NewEmail)."', NULL, '".DBCrypt::encrypt($_SERVER['REMOTE_ADDR'])."')");
174 175
 
175
-  } else {
176
-    error($Err);
177
-    header("Location: user.php?action=edit&userid=$UserID");
178
-    die();
179
-  }
180 176
 }
181
-//End email change
182 177
 
183
-//2FA activation
184
-if (!empty($_POST['twofa'])) {
178
+// PGP Key
179
+if ($CurPublicKey != $_POST['publickey']) {
180
+  require_password("Change Public Key");
185 181
   $DB->query("
186
-    SELECT TwoFactor, PassHash
187
-    FROM users_main
182
+    UPDATE users_main
183
+    SET PublicKey = '".db_string($_POST['publickey'])."'
188 184
     WHERE ID = $UserID");
189
-  list($TwoFactor, $PassHash) = $DB->next_record();
190
-  if (empty($TwoFactor)) {
191
-    if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
192
-      error('You did not enter the correct password.');
193
-      header("Location: user.php?action=edit&userid=$UserID");
194
-      die();
195
-    }
196
-    require_once SERVER_ROOT.'/classes/twofa.class.php';
197
-    $TwoFA = new TwoFactorAuth(SITE_NAME);
198
-    if ($TwoFA->verifyCode($_POST['twofasecret'], $_POST['twofa'])) {
199
-      $DB->query("
200
-        UPDATE users_main
201
-        SET TwoFactor='".db_string($_POST['twofasecret'])."'
202
-        WHERE ID = $UserID");
203
-    } else {
204
-      error('Invalid 2FA verification code.');
205
-      header("Location: user.php?action=edit&userid=$UserID");
206
-      die();
207
-    }
185
+}
186
+
187
+// 2FA activation
188
+if (!empty($_POST['twofa']) && empty($CurTwoFA)) {
189
+  require_password("Enable 2-Factor");
190
+  require_once SERVER_ROOT.'/classes/twofa.class.php';
191
+  $TwoFA = new TwoFactorAuth(SITE_NAME);
192
+  if ($TwoFA->verifyCode($_POST['twofasecret'], $_POST['twofa'])) {
193
+    $DB->query("
194
+      UPDATE users_main
195
+      SET TwoFactor='".db_string($_POST['twofasecret'])."'
196
+      WHERE ID = $UserID");
197
+  } else {
198
+    error('Invalid 2FA verification code.');
208 199
   }
209 200
 }
210 201
 
211
-//2FA deactivation
202
+// 2FA deactivation
212 203
 if (isset($_POST['disable2fa'])) {
213
-  $DB->query("
214
-    SELECT PassHash
215
-    FROM users_main
216
-    WHERE ID = $UserID");
217
-  list($PassHash) = $DB->next_record();
218
-  if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
219
-      error('You did not enter the correct password.');
220
-      header("Location: user.php?action=edit&userid=$UserID");
221
-      die();
222
-  }
204
+  require_password("Disable 2-Factor");
223 205
   $DB->query("
224 206
     UPDATE users_main
225
-    SET TwoFactor=NULL
207
+    SET TwoFactor = NULL
226 208
     WHERE ID = $UserID");
227 209
 }
228
-//End 2FA
229 210
 
230
-if (!$Err && ($_POST['cur_pass'] || $_POST['new_pass_1'] || $_POST['new_pass_2'])) {
231
-  $DB->query("
232
-    SELECT PassHash
233
-    FROM users_main
234
-    WHERE ID = '".db_string($UserID)."'");
235
-  list($PassHash) = $DB->next_record();
236
-
237
-  if (Users::check_password($_POST['cur_pass'], $PassHash)) {
238
-    if ($_POST['new_pass_1'] && $_POST['new_pass_2']) {
239
-      $ResetPassword = true;
240
-    }
241
-  } else {
242
-    $Err = 'You did not enter the correct password.';
243
-  }
211
+if (!empty($_POST['new_pass_1']) && !empty($_POST['new_pass_2'])) {
212
+  require_password("Change Password");
213
+  $ResetPassword = true;
244 214
 }
245 215
 
246
-if ($LoggedUser['DisableAvatar'] && $_POST['avatar'] != $U['Avatar']) {
247
-  $Err = 'Your avatar privileges have been revoked.';
216
+if ($CurIRCKey != $_POST['irckey']) {
217
+  require_password("Change IRC Key");
248 218
 }
249 219
 
250
-if ($Err) {
251
-  error($Err);
252
-  header("Location: user.php?action=edit&userid=$UserID");
253
-  die();
220
+if (isset($_POST['resetpasskey'])) {
221
+  require_password("Reset Passkey");
222
+}
223
+
224
+if ($LoggedUser['DisableAvatar'] && $_POST['avatar'] != $U['Avatar']) {
225
+  error('Your avatar privileges have been revoked.');
254 226
 }
255 227
 
256 228
 if (!empty($LoggedUser['DefaultSearch'])) {

Loading…
Cancel
Save