Browse Source

Encrypt Gazelle DB connections with client cert

biotorrents 5 years ago
parent
commit
fd1641228e

+ 33
- 32
classes/cookie.class.php View File

1
 <?php
1
 <?php
2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
-/**
5
- * Cookie
6
- *
7
- * This class handles cookies.
8
- * $Cookie->get() is user-provided and untrustworthy.
9
- */
10
-
11
 class COOKIE
4
 class COOKIE
12
 {
5
 {
6
+    # If true, blocks JS cookie API access by default (can be overridden case by case)
7
+    const LIMIT_ACCESS = true;
8
+
13
     # In some cases you may desire to prefix your cookies
9
     # In some cases you may desire to prefix your cookies
14
     const PREFIX = '';
10
     const PREFIX = '';
15
 
11
 
12
+
13
+    /**
14
+     * get()
15
+     * Untrustworthy user input
16
+     */
16
     public function get($Key)
17
     public function get($Key)
17
     {
18
     {
18
-        return (!isset($_COOKIE[SELF::PREFIX.$Key]))
19
-            ? false
20
-            : $_COOKIE[SELF::PREFIX.$Key];
19
+        if (!isset($_COOKIE[SELF::PREFIX.$Key])) {
20
+            return false;
21
+        }
22
+        return $_COOKIE[SELF::PREFIX.$Key];
21
     }
23
     }
22
 
24
 
23
-    // Pass the 4th optional param as false to allow JS access to the cookie
24
-    public function set($Key, $Value, $Seconds = 86400)
25
-    {
26
-        $ENV = ENV::go();
27
 
25
 
26
+    /**
27
+     * set()
28
+     * LimitAccess = false allows JS cookie access
29
+     */
30
+    public function set($Key, $Value, $Seconds = 86400, $LimitAccess = SELF::LIMIT_ACCESS)
31
+    {
28
         setcookie(
32
         setcookie(
29
             SELF::PREFIX.$Key,
33
             SELF::PREFIX.$Key,
30
             $Value,
34
             $Value,
31
-            [
32
-                'expires' => time() + $Seconds,
33
-                'path' => '/',
34
-                'domain' => $ENV->SITE_DOMAIN,
35
-                'secure' => true,
36
-                'httponly' => true,
37
-                'samesite' => 'Strict',
38
-            ]
35
+            time() + $Seconds,
36
+            '/',
37
+            SITE_DOMAIN,
38
+            $_SERVER['SERVER_PORT'] === '443',
39
+            $LimitAccess,
40
+            false
39
         );
41
         );
40
     }
42
     }
41
 
43
 
44
+
45
+    /**
46
+     * del()
47
+     */
42
     public function del($Key)
48
     public function del($Key)
43
     {
49
     {
44
         # 3600s vs. 1s for potential clock desyncs
50
         # 3600s vs. 1s for potential clock desyncs
45
-        setcookie(
46
-            SELF::PREFIX.$Key,
47
-            '',
48
-            [
49
-                'expires' => time() - 24 * 3600,
50
-                'secure' => true,
51
-                'httponly' => true,
52
-                'samesite' => 'Strict',
53
-            ]
54
-        );
51
+        setcookie(SELF::PREFIX.$Key, '', time() - 24 * 3600);
55
     }
52
     }
56
 
53
 
54
+
55
+    /**
56
+     * flush()
57
+     */
57
     public function flush()
58
     public function flush()
58
     {
59
     {
59
         $Cookies = array_keys($_COOKIE);
60
         $Cookies = array_keys($_COOKIE);

+ 67
- 76
classes/mysql.class.php View File

115
     error('Mysqli Extension not loaded.');
115
     error('Mysqli Extension not loaded.');
116
 }
116
 }
117
 
117
 
118
+
118
 /**
119
 /**
119
  * db_string
120
  * db_string
120
  * Handles escaping
121
  * Handles escaping
143
     return $String;
144
     return $String;
144
 }
145
 }
145
 
146
 
147
+
146
 /**
148
 /**
147
  * db_array
149
  * db_array
148
  */
150
  */
160
     return $Array;
162
     return $Array;
161
 }
163
 }
162
 
164
 
165
+
163
 // todo: Revisit access levels once Drone is replaced by ZeRobot
166
 // todo: Revisit access levels once Drone is replaced by ZeRobot
164
 class DB_MYSQL
167
 class DB_MYSQL
165
 {
168
 {
182
     protected $Port = 0;
185
     protected $Port = 0;
183
     protected $Socket = '';
186
     protected $Socket = '';
184
 
187
 
188
+    protected $Key = '';
189
+    protected $Cert = '';
190
+    protected $CA = '';
191
+
192
+
185
     /**
193
     /**
186
      * __construct
194
      * __construct
187
      */
195
      */
188
-    public function __construct($Database = null, $User = null, $Pass = null, $Server = null, $Port = null, $Socket = null)
189
-    {
196
+    public function __construct(
197
+        $Database = null,
198
+        $User = null,
199
+        $Pass = null,
200
+        $Server = null,
201
+        $Port = null,
202
+        $Socket = null,
203
+        $Key = null,
204
+        $Cert = null,
205
+        $CA = null
206
+    ) {
190
         $ENV = ENV::go();
207
         $ENV = ENV::go();
208
+
191
         $this->Database = $ENV->getPriv('SQLDB');
209
         $this->Database = $ENV->getPriv('SQLDB');
192
         $this->User = $ENV->getPriv('SQLLOGIN');
210
         $this->User = $ENV->getPriv('SQLLOGIN');
193
         $this->Pass = $ENV->getPriv('SQLPASS');
211
         $this->Pass = $ENV->getPriv('SQLPASS');
194
         $this->Server = $ENV->getPriv('SQLHOST');
212
         $this->Server = $ENV->getPriv('SQLHOST');
195
         $this->Port = $ENV->getPriv('SQLPORT');
213
         $this->Port = $ENV->getPriv('SQLPORT');
196
         $this->Socket = $ENV->getPriv('SQLSOCK');
214
         $this->Socket = $ENV->getPriv('SQLSOCK');
215
+
216
+        $this->Key = $ENV->getPriv('SQL_KEY');
217
+        $this->Cert = $ENV->getPriv('SQL_CERT');
218
+        $this->CA = $ENV->getPriv('SQL_CA');
197
     }
219
     }
198
 
220
 
221
+
199
     /**
222
     /**
200
      * halt
223
      * halt
201
      */
224
      */
220
         }
243
         }
221
     }
244
     }
222
 
245
 
246
+
223
     /**
247
     /**
224
      * connect
248
      * connect
225
      */
249
      */
226
     public function connect()
250
     public function connect()
227
     {
251
     {
228
         if (!$this->LinkID) {
252
         if (!$this->LinkID) {
229
-            $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php
253
+            $this->LinkID = mysqli_init();
254
+
255
+            mysqli_ssl_set(
256
+                $this->LinkID,
257
+                $this->Key,
258
+                $this->Cert,
259
+                $this->Ca,
260
+                null,
261
+                null
262
+            );
263
+
264
+            mysqli_real_connect(
265
+                $this->LinkID,
266
+                $this->Server,
267
+                $this->User,
268
+                $this->Pass,
269
+                $this->Database,
270
+                $this->Port,
271
+                $this->Socket,
272
+                MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT
273
+            );
274
+
230
             if (!$this->LinkID) {
275
             if (!$this->LinkID) {
231
                 $this->Errno = mysqli_connect_errno();
276
                 $this->Errno = mysqli_connect_errno();
232
                 $this->Error = mysqli_connect_error();
277
                 $this->Error = mysqli_connect_error();
235
         }
280
         }
236
         mysqli_set_charset($this->LinkID, "utf8mb4");
281
         mysqli_set_charset($this->LinkID, "utf8mb4");
237
     }
282
     }
238
-     
283
+
284
+
239
     /**
285
     /**
240
      * prepare_query
286
      * prepare_query
241
      */
287
      */
258
         return $this->StatementID;
304
         return $this->StatementID;
259
     }
305
     }
260
 
306
 
307
+
261
     /**
308
     /**
262
      * exec_prepared_query
309
      * exec_prepared_query
263
      */
310
      */
271
         $this->Time += $QueryRunTime;
318
         $this->Time += $QueryRunTime;
272
     }
319
     }
273
 
320
 
321
+
274
     /**
322
     /**
275
      * Runs a raw query assuming pre-sanitized input. However, attempting to self sanitize (such
323
      * Runs a raw query assuming pre-sanitized input. However, attempting to self sanitize (such
276
      * as via db_string) is still not as safe for using prepared statements so for queries
324
      * as via db_string) is still not as safe for using prepared statements so for queries
360
         return $this->QueryID;
408
         return $this->QueryID;
361
     }
409
     }
362
 
410
 
411
+
363
     /**
412
     /**
364
      * inserted_id
413
      * inserted_id
365
      */
414
      */
370
         }
419
         }
371
     }
420
     }
372
 
421
 
422
+
373
     /**
423
     /**
374
      * next_record
424
      * next_record
375
      */
425
      */
388
         }
438
         }
389
     }
439
     }
390
 
440
 
441
+
391
     /**
442
     /**
392
      * close
443
      * close
393
      */
444
      */
401
         }
452
         }
402
     }
453
     }
403
 
454
 
455
+
404
     /*
456
     /*
405
      * Returns an integer with the number of rows found
457
      * Returns an integer with the number of rows found
406
      * Returns a string if the number of rows found exceeds MAXINT
458
      * Returns a string if the number of rows found exceeds MAXINT
412
         }
464
         }
413
     }
465
     }
414
 
466
 
467
+
415
     /*
468
     /*
416
      * Returns true if the query exists and there were records found
469
      * Returns true if the query exists and there were records found
417
      * Returns false if the query does not exist or if there were 0 records returned
470
      * Returns false if the query does not exist or if there were 0 records returned
421
         return ($this->QueryID && $this->record_count() !== 0);
474
         return ($this->QueryID && $this->record_count() !== 0);
422
     }
475
     }
423
 
476
 
477
+
424
     /**
478
     /**
425
      * affected_rows
479
      * affected_rows
426
      */
480
      */
431
         }
485
         }
432
     }
486
     }
433
 
487
 
488
+
434
     /**
489
     /**
435
      * info
490
      * info
436
      */
491
      */
439
         return mysqli_get_host_info($this->LinkID);
494
         return mysqli_get_host_info($this->LinkID);
440
     }
495
     }
441
 
496
 
497
+
442
     // Creates an array from a result set
498
     // Creates an array from a result set
443
     // If $Key is set, use the $Key column in the result set as the array key
499
     // If $Key is set, use the $Key column in the result set as the array key
444
     // Otherwise, use an integer
500
     // Otherwise, use an integer
461
         return $Return;
517
         return $Return;
462
     }
518
     }
463
 
519
 
520
+
464
     //  Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
521
     //  Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
465
     public function to_pair($KeyField, $ValField, $Escape = true)
522
     public function to_pair($KeyField, $ValField, $Escape = true)
466
     {
523
     {
480
         return $Return;
537
         return $Return;
481
     }
538
     }
482
 
539
 
540
+
483
     //  Loops through the result set, collecting the $Key column into an array
541
     //  Loops through the result set, collecting the $Key column into an array
484
     public function collect($Key, $Escape = true)
542
     public function collect($Key, $Escape = true)
485
     {
543
     {
497
      * Useful extras from OPS
555
      * Useful extras from OPS
498
      */
556
      */
499
 
557
 
558
+
500
     /**
559
     /**
501
      * Runs a prepared_query using placeholders and returns the matched row.
560
      * Runs a prepared_query using placeholders and returns the matched row.
502
      * Stashes the current query id so that this can be used within a block
561
      * Stashes the current query id so that this can be used within a block
515
         return $result;
574
         return $result;
516
     }
575
     }
517
 
576
 
577
+
518
     /**
578
     /**
519
      * Runs a prepared_query using placeholders and returns the first element
579
      * Runs a prepared_query using placeholders and returns the first element
520
      * of the first row.
580
      * of the first row.
545
         $this->Row = 0;
605
         $this->Row = 0;
546
     }
606
     }
547
 
607
 
608
+
548
     /**
609
     /**
549
      * get_query_id
610
      * get_query_id
550
      */
611
      */
553
         return $this->QueryID;
614
         return $this->QueryID;
554
     }
615
     }
555
 
616
 
617
+
556
     /**
618
     /**
557
      * beginning
619
      * beginning
558
      */
620
      */
562
         $this->Row = 0;
624
         $this->Row = 0;
563
     }
625
     }
564
 
626
 
627
+
565
     /**
628
     /**
566
      * This function determines whether the last query caused warning messages
629
      * This function determines whether the last query caused warning messages
567
      * and stores them in $this->Queries
630
      * and stores them in $this->Queries
581
         }
644
         }
582
         $this->Queries[count($this->Queries) - 1][2] = $Warnings;
645
         $this->Queries[count($this->Queries) - 1][2] = $Warnings;
583
     }
646
     }
584
-
585
-
586
-    /**
587
-     * todo: Work this into Bio Gazelle
588
-     * @see https://github.com/OPSnet/Gazelle/blob/master/app/DB.php
589
-     */
590
-
591
-    /**
592
-     * Soft delete a row from a table <t> by inserting it into deleted_<t> and then delete from <t>
593
-     * @param string $schema the schema name
594
-     * @param string $table the table name
595
-     * @param array $condition Must be an array of arrays, e.g. [[column_name, column_value]] or [[col1, val1], [col2, val2]]
596
-     *                         Will be used to identify the row (or rows) to delete
597
-     * @param boolean $delete whether to delete the matched rows
598
-     * @return array 2 elements, true/false and message if false
599
-     * /
600
-    public function softDelete($schema, $table, array $condition, $delete = true)
601
-    {
602
-        $sql = 'SELECT column_name, column_type FROM information_schema.columns WHERE table_schema = ? AND table_name = ? ORDER BY 1';
603
-        $this->db->prepared_query($sql, $schema, $table);
604
-        $t1 = $this->db->to_array();
605
-        $n1 = count($t1);
606
-
607
-        $softDeleteTable = 'deleted_' . $table;
608
-        $this->db->prepared_query($sql, $schema, $softDeleteTable);
609
-        $t2 = $this->db->to_array();
610
-        $n2 = count($t2);
611
-
612
-        if (!$n1) {
613
-            return [false, "No such table $table"];
614
-        } elseif (!$n2) {
615
-            return [false, "No such table $softDeleteTable"];
616
-        } elseif ($n1 != $n2) {
617
-            // tables do not have the same number of columns
618
-            return [false, "$table and $softDeleteTable column count mismatch ($n1 != $n2)"];
619
-        }
620
-
621
-        $column = [];
622
-        for ($i = 0; $i < $n1; ++$i) {
623
-            // a column does not have the same name or datatype
624
-            if (strtolower($t1[$i][0]) != strtolower($t2[$i][0]) || $t1[$i][1] != $t2[$i][1]) {
625
-                return [false, "{$table}: column {$t1[$i][0]} name or datatype mismatch {$t1[$i][0]}:{$t2[$i][0]} {$t1[$i][1]}:{$t2[$i][1]}"];
626
-            }
627
-            $column[] = $t1[$i][0];
628
-        }
629
-        $columnList = implode(', ', $column);
630
-        $conditionList = implode(' AND ', array_map(function ($c) {
631
-            return "{$c[0]} = ?";
632
-        }, $condition));
633
-        $argList = array_map(function ($c) {
634
-            return $c[1];
635
-        }, $condition);
636
-
637
-        $sql = "INSERT INTO $softDeleteTable
638
-                  ($columnList)
639
-            SELECT $columnList
640
-            FROM $table
641
-            WHERE $conditionList";
642
-        $this->db->prepared_query($sql, ...$argList);
643
-        if ($this->db->affected_rows() == 0) {
644
-            return [false, "condition selected 0 rows"];
645
-        }
646
-
647
-        if (!$delete) {
648
-            return [true, "rows affected: " . $this->db->affected_rows()];
649
-        }
650
-
651
-        $sql = "DELETE FROM $table WHERE $conditionList";
652
-        $this->db->prepared_query($sql, ...$argList);
653
-        return [true, "rows deleted: " . $this->db->affected_rows()];
654
-    }
655
-    */
656
 }
647
 }

+ 1
- 1
design/privateheader.php View File

49
     array_merge(
49
     array_merge(
50
         [
50
         [
51
           'vendor/jquery-ui.min',
51
           'vendor/jquery-ui.min',
52
-          'assets/fonts/fa/css/all.min',
52
+          #'assets/fonts/fa/css/all.min',
53
           'global'
53
           'global'
54
         ],
54
         ],
55
         explode(',', $CSSIncludes)
55
         explode(',', $CSSIncludes)

+ 8
- 1
design/publicfooter.php View File

1
+<?php
2
+declare(strict_types=1);
3
+
4
+$ENV = ENV::go();
5
+
6
+echo <<<HTML
1
 </main>
7
 </main>
2
 
8
 
3
 <footer>
9
 <footer>
9
 <script src="$ENV->STATIC_SERVER/functions/vendor/instantpage.js" type="module"></script>
15
 <script src="$ENV->STATIC_SERVER/functions/vendor/instantpage.js" type="module"></script>
10
 </body>
16
 </body>
11
 
17
 
12
-</html>
18
+</html>
19
+HTML;

+ 3
- 13
sections/donate/donate.php View File

50
     <ul>
50
     <ul>
51
       <li>
51
       <li>
52
         <strong>Server.</strong>
52
         <strong>Server.</strong>
53
-        We use one budget VPS at 2.50€ per month and may add more as needed.
53
+        We use two budget VPS at 2.50€ per month each.
54
         Please consider using our
54
         Please consider using our
55
         <a href="https://hetzner.cloud/?ref=mzIDQWTHipNB" target="_blank">affiliate link</a>.
55
         <a href="https://hetzner.cloud/?ref=mzIDQWTHipNB" target="_blank">affiliate link</a>.
56
-        You'd receive 20€ credit, effectively paying your server for 8 months.
57
-        BioTorrents would receive 10€ credit after a year, paying our server for 4 months.
58
-      </li>
59
-
60
-      <li>
61
-        <strong>Seedbox.</strong>
62
-        A dedicated seedbox from
63
-        <a href="https://pulsedmedia.com/clients/aff.php?aff=1275" target="_blank">Pulsed Media (affiliate link)</a>
64
-        is 75€ per year.
65
-        Please see the <a href="/user.php?id=28">seedbox user account stats</a>.
56
+        You'd receive 20€ credit, and BioTorrents.de would receive 10€ credit after that.
66
       </li>
57
       </li>
67
 
58
 
68
       <li>
59
       <li>
69
         <strong>Domain.</strong>
60
         <strong>Domain.</strong>
70
         The domain name is $15 per year.
61
         The domain name is $15 per year.
71
-        The SSL certificate is gratis.
62
+        The TLS certificates are gratis.
72
       </li>
63
       </li>
73
 
64
 
74
       <li>
65
       <li>
75
         <strong>Company.</strong>
66
         <strong>Company.</strong>
76
         Omics Tools LLC is <?= $ENV->SITE_NAME ?>'s parent company.
67
         Omics Tools LLC is <?= $ENV->SITE_NAME ?>'s parent company.
77
         It's $50 per year for annual reports and $125 for resident agent services.
68
         It's $50 per year for annual reports and $125 for resident agent services.
78
-        Also, DMCA agent registration is $6.
79
       </li>
69
       </li>
80
     </ul>
70
     </ul>
81
   </div>
71
   </div>

+ 7
- 6
sections/index/private.php View File

34
     $LoggedUser['LastReadNews'] = $News[0][0];
34
     $LoggedUser['LastReadNews'] = $News[0][0];
35
 }
35
 }
36
 
36
 
37
-View::show_header('News', 'bbcode,news_ajax');
37
+View::show_header('News', 'news_ajax');
38
+#View::show_header('News', 'bbcode,news_ajax');
38
 ?>
39
 ?>
39
 <div>
40
 <div>
40
   <div class="sidebar">
41
   <div class="sidebar">
41
-    <?php #include 'connect.php'; ?>
42
+    <?php #include 'connect.php';?>
42
 
43
 
43
     <?php
44
     <?php
44
     # Staff blog
45
     # Staff blog
49
       </div>
50
       </div>
50
       <?php
51
       <?php
51
 if (($Blog = $Cache->get_value('staff_blog')) === false) {
52
 if (($Blog = $Cache->get_value('staff_blog')) === false) {
52
-        $DB->query("
53
+    $DB->query("
53
     SELECT
54
     SELECT
54
       b.ID,
55
       b.ID,
55
       um.Username,
56
       um.Username,
59
     FROM staff_blog AS b
60
     FROM staff_blog AS b
60
       LEFT JOIN users_main AS um ON b.UserID = um.ID
61
       LEFT JOIN users_main AS um ON b.UserID = um.ID
61
     ORDER BY Time DESC");
62
     ORDER BY Time DESC");
62
-        $Blog = $DB->to_array(false, MYSQLI_NUM);
63
-        $Cache->cache_value('staff_blog', $Blog, 1209600);
64
-    }
63
+    $Blog = $DB->to_array(false, MYSQLI_NUM);
64
+    $Cache->cache_value('staff_blog', $Blog, 1209600);
65
+}
65
     if (($SBlogReadTime = $Cache->get_value('staff_blog_read_'.$LoggedUser['ID'])) === false) {
66
     if (($SBlogReadTime = $Cache->get_value('staff_blog_read_'.$LoggedUser['ID'])) === false) {
66
         $DB->query("
67
         $DB->query("
67
     SELECT Time
68
     SELECT Time

+ 34
- 29
sections/login/index.php View File

10
 //-----------------------------------*/
10
 //-----------------------------------*/
11
 
11
 
12
 // Allow users to reset their password while logged in
12
 // Allow users to reset their password while logged in
13
-if (!empty($LoggedUser['ID']) && $_REQUEST['act'] != 'recover') {
13
+if (!empty($LoggedUser['ID']) && $_REQUEST['act'] !== 'recover') {
14
     header('Location: index.php');
14
     header('Location: index.php');
15
     error();
15
     error();
16
 }
16
 }
24
     error('Your IP address has been banned.');
24
     error('Your IP address has been banned.');
25
 }
25
 }
26
 
26
 
27
+# Initialize
27
 require_once SERVER_ROOT.'/classes/twofa.class.php';
28
 require_once SERVER_ROOT.'/classes/twofa.class.php';
28
 require_once SERVER_ROOT.'/classes/u2f.class.php';
29
 require_once SERVER_ROOT.'/classes/u2f.class.php';
29
 require_once SERVER_ROOT.'/classes/validate.class.php';
30
 require_once SERVER_ROOT.'/classes/validate.class.php';
33
 $U2F = new u2f\U2F('https://'.SITE_DOMAIN);
34
 $U2F = new u2f\U2F('https://'.SITE_DOMAIN);
34
 
35
 
35
 # todo: Test strict equality very gently here
36
 # todo: Test strict equality very gently here
36
-if (array_key_exists('action', $_GET) && $_GET['action'] == 'disabled') {
37
+if (array_key_exists('action', $_GET) && $_GET['action'] === 'disabled') {
37
     require('disabled.php');
38
     require('disabled.php');
38
     error();
39
     error();
39
 }
40
 }
40
 
41
 
41
-if (isset($_REQUEST['act']) && $_REQUEST['act'] == 'recover') {
42
+if (isset($_REQUEST['act']) && $_REQUEST['act'] === 'recover') {
42
     // Recover password
43
     // Recover password
43
     if (!empty($_REQUEST['key'])) {
44
     if (!empty($_REQUEST['key'])) {
44
         // User has entered a new password, use step 2
45
         // User has entered a new password, use step 2
45
         $DB->query("
46
         $DB->query("
46
         SELECT
47
         SELECT
47
-          m.ID,
48
-          m.Email,
49
-          i.ResetExpires
50
-        FROM users_main AS m
51
-          INNER JOIN users_info AS i ON i.UserID = m.ID
52
-          WHERE i.ResetKey = ?
53
-          AND i.ResetKey != ''", $_REQUEST['key']);
48
+          m.`ID`,
49
+          m.`Email`,
50
+          i.`ResetExpires`
51
+        FROM `users_main` AS m
52
+          INNER JOIN `users_info` AS i ON i.`UserID` = m.`ID`
53
+          WHERE i.`ResetKey` = ?
54
+          AND i.`ResetKey` != ''", $_REQUEST['key']);
54
         list($UserID, $Email, $Country, $Expires) = $DB->next_record();
55
         list($UserID, $Email, $Country, $Expires) = $DB->next_record();
55
 
56
 
56
         if (!apcu_exists('DBKEY')) {
57
         if (!apcu_exists('DBKEY')) {
57
-            error('Database not fully decrypted. Please wait for staff to fix this and try again later');
58
+            error('Database not fully decrypted. Please wait for staff to fix this and try again later.');
58
         }
59
         }
59
 
60
 
60
         $Email = Crypto::decrypt($Email);
61
         $Email = Crypto::decrypt($Email);
65
             $Validate->SetFields('verifypassword', '1', 'compare', 'Your passwords did not match.', array('comparefield' => 'password'));
66
             $Validate->SetFields('verifypassword', '1', 'compare', 'Your passwords did not match.', array('comparefield' => 'password'));
66
 
67
 
67
             if (!empty($_REQUEST['password'])) {
68
             if (!empty($_REQUEST['password'])) {
68
-                // If the user has entered a password.
69
-                // If the user has not entered a password, $PassWasReset is not set to 1, and the success message is not shown
69
+                // If the user entered a password.
70
+                // If not, $PassWasReset !== 1, success message hidden.
70
                 $Err = $Validate->ValidateForm($_REQUEST);
71
                 $Err = $Validate->ValidateForm($_REQUEST);
71
                 if ($Err == '') {
72
                 if ($Err == '') {
72
                     // Form validates without error, set new secret and password.
73
                     // Form validates without error, set new secret and password.
73
-                    $DB->query("
74
+                    $DB->query(
75
+                        "
74
                     UPDATE
76
                     UPDATE
75
-                      users_main AS m,
76
-                      users_info AS i
77
+                      `users_main` AS m,
78
+                      `users_info` AS i
77
                     SET
79
                     SET
78
-                      m.PassHash = ?,
79
-                      i.ResetKey = '',
80
-                      m.LastLogin = NOW(),
81
-                      i.ResetExpires = NULL
82
-                      WHERE m.ID = ?
83
-                      AND i.UserID = m.ID", Users::make_sec_hash($_REQUEST['password']), $UserID);
80
+                      m.`PassHash` = ?,
81
+                      i.`ResetKey` = '',
82
+                      m.`LastLogin` = NOW(),
83
+                      i.`ResetExpires` = NULL
84
+                      WHERE m.`ID` = ?
85
+                      AND i.`UserID` = m.`ID`",
86
+                        Users::make_sec_hash($_REQUEST['password']),
87
+                        $UserID
88
+                    );
89
+
84
                     $DB->query("
90
                     $DB->query("
85
-                    INSERT INTO users_history_passwords
86
-                      (UserID, ChangerIP, ChangeTime)
91
+                    INSERT INTO `users_history_passwords`
92
+                      (`UserID`, `ChangerIP`, `ChangeTime`)
87
                     VALUES
93
                     VALUES
88
                       (?, ?, NOW())", $UserID, Crypto::encrypt($_SERVER['REMOTE_ADDR']));
94
                       (?, ?, NOW())", $UserID, Crypto::encrypt($_SERVER['REMOTE_ADDR']));
95
+
89
                     $PassWasReset = true;
96
                     $PassWasReset = true;
90
                     $LoggedUser['ID'] = $UserID; // Set $LoggedUser['ID'] for logout_all_sessions() to work
97
                     $LoggedUser['ID'] = $UserID; // Set $LoggedUser['ID'] for logout_all_sessions() to work
91
                     logout_all_sessions();
98
                     logout_all_sessions();
193
                       AND `Active` = 1
200
                       AND `Active` = 1
194
                     ");
201
                     ");
195
                 } else {
202
                 } else {
196
-                    $Err = 'There is no user with that email address';
203
+                    $Err = 'There is no user with that email address.';
197
                 }
204
                 }
198
             }
205
             }
199
         } elseif (!empty($_SESSION['reseterr'])) {
206
         } elseif (!empty($_SESSION['reseterr'])) {
209
     }
216
     }
210
 } // End password recovery
217
 } // End password recovery
211
 
218
 
212
-elseif (isset($_REQUEST['act']) && $_REQUEST['act'] == 'newlocation') {
219
+elseif (isset($_REQUEST['act']) && $_REQUEST['act'] === 'newlocation') {
213
     if (isset($_REQUEST['key'])) {
220
     if (isset($_REQUEST['key'])) {
214
         if ($ASNCache = $Cache->get_value('new_location_'.$_REQUEST['key'])) {
221
         if ($ASNCache = $Cache->get_value('new_location_'.$_REQUEST['key'])) {
215
             $Cache->cache_value('new_location_'.$ASNCache['UserID'].'_'.$ASNCache['ASN'], true);
222
             $Cache->cache_value('new_location_'.$ASNCache['UserID'].'_'.$ASNCache['ASN'], true);
226
 // Normal login
233
 // Normal login
227
 else {
234
 else {
228
     $Validate->SetFields('username', true, 'regex', 'You did not enter a valid username', array('regex' => USERNAME_REGEX));
235
     $Validate->SetFields('username', true, 'regex', 'You did not enter a valid username', array('regex' => USERNAME_REGEX));
229
-    $Validate->SetFields('password', '1', 'string', 'You entered an invalid password', array('minlength' => '6', 'maxlength' => '307200'));
236
+    $Validate->SetFields('password', '1', 'string', 'You entered an invalid password', array('minlength' => '15', 'maxlength' => '307200'));
230
 
237
 
231
     list($Attempts, $Banned) = $Cache->get_value('login_attempts_'.db_string($_SERVER['REMOTE_ADDR']));
238
     list($Attempts, $Banned) = $Cache->get_value('login_attempts_'.db_string($_SERVER['REMOTE_ADDR']));
232
 
239
 
306
                                         $QueryParts[] = "(StartIP<=INET6_ATON('$IP') AND EndIP>=INET6_ATON('$IP'))";
313
                                         $QueryParts[] = "(StartIP<=INET6_ATON('$IP') AND EndIP>=INET6_ATON('$IP'))";
307
                                     }
314
                                     }
308
 
315
 
309
-                                    /*
310
                                     $DB->query('SELECT ASN FROM geoip_asn WHERE '.implode(' OR ', $QueryParts));
316
                                     $DB->query('SELECT ASN FROM geoip_asn WHERE '.implode(' OR ', $QueryParts));
311
                                     $PastASNs = array_column($DB->to_array(false, MYSQLI_NUM), 0);
317
                                     $PastASNs = array_column($DB->to_array(false, MYSQLI_NUM), 0);
312
                                     $DB->query("SELECT ASN FROM geoip_asn WHERE StartIP<=INET6_ATON('$_SERVER[REMOTE_ADDR]') AND EndIP>=INET6_ATON('$_SERVER[REMOTE_ADDR]')");
318
                                     $DB->query("SELECT ASN FROM geoip_asn WHERE StartIP<=INET6_ATON('$_SERVER[REMOTE_ADDR]') AND EndIP>=INET6_ATON('$_SERVER[REMOTE_ADDR]')");
313
                                     list($CurrentASN) = $DB->next_record();
319
                                     list($CurrentASN) = $DB->next_record();
314
-                                    */
315
 
320
 
316
                                     // If FEATURE_ENFORCE_LOCATIONS is enabled, require users to confirm new logins
321
                                     // If FEATURE_ENFORCE_LOCATIONS is enabled, require users to confirm new logins
317
                                     if (!in_array($CurrentASN, $PastASNs) && $ENV->FEATURE_ENFORCE_LOCATIONS) {
322
                                     if (!in_array($CurrentASN, $PastASNs) && $ENV->FEATURE_ENFORCE_LOCATIONS) {

+ 3
- 3
sections/login/login.php View File

1
 <?php
1
 <?php
2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
-View::show_header('Login');
5
-?>
4
+View::show_header('Login'); ?>
6
 
5
 
7
 <p class="center mouseless">
6
 <p class="center mouseless">
8
   A platform to share <strong>biological sequence</strong><br />
7
   A platform to share <strong>biological sequence</strong><br />
51
         <input type="password" minlength="15" name="password" id="password" class="inputtext" required="required"
50
         <input type="password" minlength="15" name="password" id="password" class="inputtext" required="required"
52
           maxlength="307200" pattern=".{15,307200}" placeholder="Password" autocomplete="current-password" />
51
           maxlength="307200" pattern=".{15,307200}" placeholder="Password" autocomplete="current-password" />
53
       </td>
52
       </td>
53
+
54
       <td>
54
       <td>
55
         <input type="text" name="twofa" id="twofa" class="inputtext" maxlength="6" pattern="[0-9]{6}"
55
         <input type="text" name="twofa" id="twofa" class="inputtext" maxlength="6" pattern="[0-9]{6}"
56
           inputmode="numeric" placeholder="2FA" size="6" title="Leave blank if you have not enabled 2FA"
56
           inputmode="numeric" placeholder="2FA" size="6" title="Leave blank if you have not enabled 2FA"
70
 } # if !$Banned
70
 } # if !$Banned
71
 else { ?>
71
 else { ?>
72
 <p class="error">
72
 <p class="error">
73
-  You are banned from logging in for a few hours.
73
+  You're banned from logging in for a few hours.
74
 </p>
74
 </p>
75
 <?php
75
 <?php
76
   }
76
   }

+ 2
- 10
sections/login/recover_step2.php View File

2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
 $ENV = ENV::go();
4
 $ENV = ENV::go();
5
-View::show_header('Recover Password');
6
-?>
5
+View::show_header('Recover Password', 'validate,password_validate');
7
 
6
 
8
-<h2>Reset your password</h2>
7
+echo '<h2>Reset your password</h2>';
9
 
8
 
10
-<script src="<?=(STATIC_SERVER)?>functions/validate.js" type="text/javascript">
11
-</script>
12
-
13
-<script src="<?=(STATIC_SERVER)?>functions/password_validate.js"
14
-  type="text/javascript"></script>
15
-
16
-<?php
17
 if (empty($PassWasReset)) {
9
 if (empty($PassWasReset)) {
18
     if (!empty($Err)) { ?>
10
     if (!empty($Err)) { ?>
19
 <strong class="important_text"><?=display_str($Err)?></strong><br /><br />
11
 <strong class="important_text"><?=display_str($Err)?></strong><br /><br />

Loading…
Cancel
Save