85414232f168f7d5b9000c4c54252308cda2c27f
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

1) <?php
2) /*
3) This file belongs to the Webinterface of schokokeks.org Hosting
4) 
5) Written by schokokeks.org Hosting, namely
6)   Bernd Wurst <bernd@schokokeks.org>
7)   Hanno Böck <hanno@schokokeks.org>
8) 
9) This code is published under a 0BSD license.
10) 
11) Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code.
12) */
13) 
14) require_once('passkey.php');
15) require_once('inc/base.php');
16) 
17) require_once('vendor/autoload.php');
18) 
19) $req = filter_input(INPUT_POST, 'req');
20) 
21) // Relying Party == Hostname
22) $rpId = $_SERVER['HTTP_HOST'];
23) 
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

24) $WebAuthn = new lbuchs\WebAuthn\WebAuthn(config('company_name') . ' Webinterface', $rpId, ["none"]);
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

25) 
26) if ($req == 'getCreateArgs') {
27)     require_role(ROLE_SYSTEMUSER);
28)     $userId = dechex($_SESSION['userinfo']['uid']); // Hex-formatted internal ID not displayed to the user
29)     if (strlen($userId) % 2 == 1) {
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

30)         $userId = "0" . $userId;
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

31)     }
32)     $userName = $_SESSION['userinfo']['username'];
33)     $_SESSION['passkey_handle'] = filter_input(INPUT_POST, "handle");
34)     $userDisplayName = $_SESSION['userinfo']['name'];
35)     if ($_SESSION['passkey_handle']) {
36)         $userDisplayName = $userDisplayName . " ({$_SESSION['passkey_handle']})";
37)     }
38) 
39)     $requireResidentKey = 'required';
40)     $userVerification = 'preferred';
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

41) 
42)     $timeout = 3 * 60;
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

43) 
44)     $createArgs = $WebAuthn->getCreateArgs(\hex2bin($userId), $userName, $userDisplayName, $timeout, $requireResidentKey, $userVerification);
45) 
46)     // save challange to session. you have to deliver it to processGet later.
47)     $_SESSION['challenge'] = ($WebAuthn->getChallenge())->getBinaryString();
48) 
49)     header('Content-Type: application/json');
50)     print(json_encode($createArgs));
51) } elseif ($req == 'processCreate') {
52)     require_role(ROLE_SYSTEMUSER);
53)     $client = $_POST['client'];
54)     $attest = $_POST['attest'];
55) 
56)     try {
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

57)         $data = $WebAuthn->processCreate(
58)             base64_decode($_POST["client"]),
59)             base64_decode($_POST["attest"]),
60)             $_SESSION["challenge"],
61)             true,
62)             true,
63)             false,
64)             false
65)         );
66)     } catch (Exception $ex) {
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

67)         logger(LOG_ERR, "modules/loginsecurity/passkey_ajax", "loginsecurity", "processCreate failed with {$ex}");
68)         print("Error");
69)         die();
70)     }
71) 
72)     save_passkey($data, $_SESSION['passkey_handle']);
73)     unset($_SESSION['passkey_handle']);
74)     print("OK");
75)     success_msg("Der Passkey wurde gespeichert!");
76)     die();
77) } elseif ($req == 'getGetArgs') {
78)     $args = $WebAuthn->getGetArgs([], 30);
79)     $_SESSION["challenge"] = ($WebAuthn->getChallenge())->getBinaryString();
80)     header('Content-Type: application/json');
81)     print(json_encode($args));
82)     die();
83) } elseif ($req == 'processGet') {
84)     $id = base64_decode($_POST["id"]);
85)     $savedData = get_passkey($id);
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

86)     if (!$savedData) {
87)         print("Invalid credentials");
Bernd Wurst merge passkeys feature

Bernd Wurst authored 1 year ago

88)         die();
89)     }
90)     try {
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

91)         $WebAuthn->processGet(
92)             base64_decode($_POST["client"]),
93)             base64_decode($_POST["auth"]),
94)             base64_decode($_POST["sig"]),
95)             $savedData['credentialPublicKey'],
96)             $_SESSION["challenge"]
97)         );
98)         // DO WHATEVER IS REQUIRED AFTER VALIDATION
99)         echo "OK";
100)         $login = ($_POST['login'] == "true");
101)         if ($login) {
102)             $uid = $savedData['uid'];
103)             require_once("session/start.php");
104)             $role = find_role($uid, '', true);
Bernd Wurst Speichere Login-Methode in...

Bernd Wurst authored 1 year ago

105)             setup_session($role, $uid, 'passkey');
Bernd Wurst Warnung auf der Startseite,...

Bernd Wurst authored 1 year ago

106)             unset($_SESSION['challenge']);
Hanno Böck Fix codingstyle

Hanno Böck authored 1 year ago

107)             die();
108)         } else {
109)             success_msg("Die Identifikation mit dem Passkey »{$savedData['handle']}« hat funktioniert!");
110)         }
111)     } catch (Exception $ex) {