Certlogin entfernt
Bernd Wurst

Bernd Wurst commited on 2026-09-23 20:22:11
Zeige 10 geänderte Dateien mit 2 Einfügungen und 460 Löschungen.

... ...
@@ -1,3 +0,0 @@
1
-# allow client certs
2
-SSLVerifyClient optional_no_ca
3
-SSLoptions +StdEnvVars +ExportCertData
... ...
@@ -1,140 +0,0 @@
1
-<?php
2
-
3
-/*
4
-This file belongs to the Webinterface of schokokeks.org Hosting
5
-
6
-Written by schokokeks.org Hosting, namely
7
-  Bernd Wurst <bernd@schokokeks.org>
8
-  Hanno Böck <hanno@schokokeks.org>
9
-
10
-This code is published under a 0BSD license.
11
-
12
-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.
13
-*/
14
-
15
-// Setze das Arbeitsverzeichnis auf das Stammverzeichnis, damit die Voraussetzungen gleich sind wie bei allen anderen Requests
16
-chdir('..');
17
-
18
-require_once('config.php');
19
-global $prefix;
20
-$prefix = '../';
21
-
22
-// Das Parent-Verzeichnis in den Include-Pfad, da wir uns jetzt in einem anderen Verzeichnis befinden.
23
-ini_set('include_path', ini_get('include_path') . ':../');
24
-
25
-require_once('session/start.php');
26
-require_once('inc/base.php');
27
-require_once('inc/debug.php');
28
-require_once('inc/error.php');
29
-require_once('inc/theme.php');
30
-require_once('modules/index/include/x509.php');
31
-
32
-
33
-DEBUG('$_SERVER:');
34
-DEBUG($_SERVER);
35
-
36
-$redirect = "";
37
-if (!isset($_SERVER['SSL_CLIENT_CERT']) && isset($_SERVER['REDIRECT_SSL_CLIENT_CERT'])) {
38
-    $redirect = "REDIRECT_";
39
-}
40
-
41
-if ($_SESSION['role'] != ROLE_ANONYMOUS && isset($_REQUEST['record']) && isset($_REQUEST['backto']) && check_path($_REQUEST['backto'])) {
42
-    DEBUG('recording client-cert');
43
-    if (isset($_SERVER[$redirect . 'SSL_CLIENT_CERT']) && isset($_SERVER[$redirect . 'SSL_CLIENT_S_DN'])
44
-      && isset($_SERVER[$redirect . 'SSL_CLIENT_I_DN']) && isset($_SERVER[$redirect . 'SSL_CLIENT_M_SERIAL'])
45
-      && isset($_SERVER[$redirect . 'SSL_CLIENT_V_START']) && isset($_SERVER[$redirect . 'SSL_CLIENT_V_END'])
46
-    ) {
47
-        $_SESSION['clientcert_cert'] = $_SERVER[$redirect . 'SSL_CLIENT_CERT'];
48
-        $_SESSION['clientcert_dn'] = $_SERVER[$redirect . 'SSL_CLIENT_S_DN'];
49
-        $_SESSION['clientcert_issuer'] = $_SERVER[$redirect . 'SSL_CLIENT_I_DN'];
50
-        $_SESSION['clientcert_serial'] = $_SERVER[$redirect . 'SSL_CLIENT_M_SERIAL'];
51
-        $vstart = new DateTime($_SERVER[$redirect . 'SSL_CLIENT_V_START']);
52
-        $_SESSION['clientcert_valid_from'] = date_format($vstart, 'Y-m-d');
53
-        $vend = new DateTime($_SERVER[$redirect . 'SSL_CLIENT_V_END']);
54
-        $_SESSION['clientcert_valid_until'] = date_format($vend, 'Y-m-d');
55
-        header('Location: ' . $prefix . $_REQUEST['backto'] . encode_querystring(''));
56
-        die();
57
-    } else {
58
-        warning('Ihr Browser hat kein Client-Zertifikat gesendet');
59
-        header('Location: ' . $prefix . $_REQUEST['backto'] . encode_querystring(''));
60
-        die();
61
-    }
62
-} elseif (isset($_REQUEST['type']) && isset($_REQUEST['username'])) {
63
-    if (!isset($_SERVER[$redirect . 'SSL_CLIENT_CERT'])) {
64
-        system_failure('Ihr Browser hat kein Client-Zertifikat gesendet');
65
-    }
66
-
67
-    $ret = get_logins_by_cert($_SERVER[$redirect . 'SSL_CLIENT_CERT']);
68
-    DEBUG($ret);
69
-    foreach ($ret as $account) {
70
-        DEBUG('/' . $account['type'] . '/' . $_REQUEST['type'] . '/    /' . $account['username'] . '/' . $_REQUEST['username'] . '/    =>');
71
-        if (($account['type'] == urldecode($_REQUEST['type'])) && ($account['username'] == urldecode($_REQUEST['username']))) {
72
-            $uid = $account['username'];
73
-            $role = find_role($uid, '', true);
74
-            setup_session($role, $uid);
75
-            $destination = 'go/index/index';
76
-            if (check_path($account['startpage'])) {
77
-                $destination = $account['startpage'];
78
-            }
79
-            if (isset($_REQUEST['destination']) && check_path($_REQUEST['destination'])) {
80
-                $destination = $_REQUEST['destination'];
81
-            }
82
-            header('Location: ../' . ltrim($destination, '/'));
83
-            die();
84
-        }
85
-    }
86
-    system_failure('Der angegebene Account kann mit diesem Client-Zertifikat nicht eingeloggt werden.');
87
-} elseif ($_SESSION['role'] != ROLE_ANONYMOUS && isset($_REQUEST['destination']) && $_REQUEST['destination'] != '') {
88
-    # User hat sich grade eingeloggt
89
-    header('Location: ../' . ltrim($destination, '/'));
90
-} else {
91
-    if (isset($_SERVER[$redirect . 'SSL_CLIENT_CERT'])
92
-      && isset($_SERVER[$redirect . 'SSL_CLIENT_S_DN']) && $_SERVER[$redirect . 'SSL_CLIENT_S_DN'] != ''
93
-      && isset($_SERVER[$redirect . 'SSL_CLIENT_I_DN']) && $_SERVER[$redirect . 'SSL_CLIENT_I_DN'] != ''
94
-      && isset($_SERVER[$redirect . 'SSL_CLIENT_M_SERIAL']) && $_SERVER[$redirect . 'SSL_CLIENT_M_SERIAL'] != '') {
95
-        $ret = get_logins_by_cert($_SERVER[$redirect . 'SSL_CLIENT_CERT']);
96
-        if ($ret === null) {
97
-            login_screen('Ihr Browser hat ein Client-Zertifikat gesendet, dieses ist aber noch nicht für den Zugang hinterlegt. Melden Sie sich bitte per Benutzername und Passwort an.');
98
-        }
99
-        if (count($ret) == 1) {
100
-            $uid = $ret[0]['username'];
101
-            $role = find_role($uid, '', true);
102
-            setup_session($role, $uid);
103
-            DEBUG("Set Cookie!");
104
-            setcookie('CLIENTCERT_AUTOLOGIN', '1', ['expires' => strtotime("+ 1 year"), 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax']);
105
-            $destination = 'go/index/index';
106
-            if (check_path($ret[0]['startpage'])) {
107
-                $destination = $ret[0]['startpage'];
108
-            }
109
-            if (isset($_REQUEST['destination']) && check_path($_REQUEST['destination'])) {
110
-                $destination = $_REQUEST['destination'];
111
-            }
112
-            header('Location: ../' . ltrim($destination, '/'));
113
-            die();
114
-        }
115
-        output('<p>Ihr Browser hat ein gültiges SSL-Client-Zertifikat gesendet, mit dem Sie sich auf dieser Seite einloggen können. Allerdings haben Sie dieses Client-Zertifikat für mehrere Zugänge hinterlegt. Wählen Sie bitte den Zugang aus, mit dem Sie sich anmelden möchten.</p>
116
-      <ul>');
117
-        foreach ($ret as $account) {
118
-            $type = 'System-Account';
119
-            if ($account['type'] == 'email') {
120
-                $type = 'E-Mail-Konto';
121
-            } elseif ($account['type'] == 'subuser') {
122
-                $type = 'Unter-Nutzer';
123
-            } elseif ($account['type'] == 'customer') {
124
-                $type = 'Kundenaccount';
125
-            }
126
-            $destination = 'go/index/index';
127
-            if ($account['startpage'] && check_path($account['startpage'])) {
128
-                $destination = $account['startpage'];
129
-            }
130
-            output('<li>' . internal_link('', $type . ': <strong>' . $account['username'] . '</strong>', 'type=' . $account['type'] . '&username=' . urlencode($account['username']) . '&destination=' . urlencode($destination)) . '</li>');
131
-        }
132
-        output('</ul>');
133
-    } else {
134
-        warning('Ihr Browser hat kein Client-Zertifikat gesendet. Eventuell müssen Sie in den Einstellungen des Browsers diese Funktion einschalten.');
135
-        redirect('/');
136
-        die();
137
-    }
138
-}
139
-
140
-show_page('certlogin');
... ...
@@ -142,11 +142,6 @@ function login_screen($why = null)
142 142
         $title = '';
143 143
         system_failure("Zu viele fehlgeschlagenen Login-Versuche! Bitte warten Sie einige Minuten bis zum nächsten Versuch!");
144 144
     }
145
-    if (!$why) {
146
-        if (isset($_COOKIE['CLIENTCERT_AUTOLOGIN']) && $_COOKIE['CLIENTCERT_AUTOLOGIN'] == '1') {
147
-            redirect("/certlogin/index.php?destination=" . urlencode($_SERVER['REQUEST_URI']));
148
-        }
149
-    }
150 145
     require_once('inc/theme.php');
151 146
     if ($why) {
152 147
         warning($why);
... ...
@@ -1,77 +0,0 @@
1
-<?php
2
-
3
-/*
4
-This file belongs to the Webinterface of schokokeks.org Hosting
5
-
6
-Written by schokokeks.org Hosting, namely
7
-  Bernd Wurst <bernd@schokokeks.org>
8
-  Hanno Böck <hanno@schokokeks.org>
9
-
10
-This code is published under a 0BSD license.
11
-
12
-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.
13
-*/
14
-
15
-require_once('inc/base.php');
16
-require_once('x509.php');
17
-
18
-require_role([ROLE_SYSTEMUSER, ROLE_SUBUSER, ROLE_VMAIL_ACCOUNT]);
19
-
20
-title('Anmeldung über Client-Zertifikat');
21
-output('<p>Sie können Sie an diesem Webinterface wahlweise auch über ein SSL-Client-Zertifikat anmelden. Dazu muss das gewünschte Zertifikat <em>vorher</em> in Ihrem Browser installiert werden und kann dann hier hinzugefügt werden.</p>
22
-<p>Wenn Sie ein Zertifikat mit der entsprechenden Funktion unten auf dieser Seite hinzufügen, wird Sie Ihr Browser fragen, welches Zertifikat verwendet werden soll. Sollte Ihr Browser nicht fragen, ist entweder kein Zertifikat im Browser installiert oder Sie haben Ihren Browser auf <em>Niemals fragen</em> (o.Ä.) eingestellt.</p>
23
-');
24
-
25
-
26
-
27
-if (isset($_GET['clear'])) {
28
-    unset($_SESSION['clientcert_cert']);
29
-    unset($_SESSION['clientcert_dn']);
30
-    unset($_SESSION['clientcert_issuer']);
31
-    unset($_SESSION['clientcert_serial']);
32
-}
33
-
34
-$username = null;
35
-if ($_SESSION['role'] & ROLE_SYSTEMUSER) {
36
-    $username = $_SESSION['userinfo']['username'];
37
-    if (isset($_SESSION['subuser'])) {
38
-        $username = $_SESSION['subuser'];
39
-    }
40
-} elseif ($_SESSION['role'] & ROLE_VMAIL_ACCOUNT) {
41
-    $username = $_SESSION['mailaccount'];
42
-}
43
-
44
-if (isset($_SESSION['clientcert_cert'])) {
45
-    // FIXME: Es gibt keine Duplikaterkennung.
46
-    global $menu;
47
-    output('<div style="margin: 1em; padding: 1em; border: 2px solid green;">');
48
-    output('<p>Es wurde folgendes Client-Zertifikat von Ihrem Browser gesendet:</p>
49
-<div style="margin-left: 2em;"><strong>DN:</strong> ' . filter_output_html($_SESSION['clientcert_dn']) . '<br />
50
-<strong>Aussteller-DN:</strong> ' . filter_output_html($_SESSION['clientcert_issuer']) . '<br />
51
-<strong>Seriennummer:</strong> ' . filter_output_html($_SESSION['clientcert_serial']) . '<br />
52
-<strong>Gültigkeit:</strong> ' . filter_output_html($_SESSION['clientcert_valid_from']) . ' bis ' . filter_output_html($_SESSION['clientcert_valid_until']) . '</div>
53
-<p>Soll dieses Zertifikat für den Zugang für <strong>' . $username . '</strong> verwendet werden?</p>');
54
-    output(html_form('clientcert_add', 'certsave.php', 'action=new', '<p><input type="submit" name="submit" value="Ja, dieses Zertifikat einrichten" /> &#160; ' . internal_link('cert', 'Nein', 'clear') . '</p>'));
55
-    output('</div>');
56
-}
57
-
58
-
59
-DEBUG($username);
60
-$certs = get_certs_by_username($username);
61
-if ($certs != null) {
62
-    output('<p>Sie haben bereits Zertifikate für den Zugang eingerichtet.</p>
63
-  <ul>');
64
-    foreach ($certs as $cert) {
65
-        output('<li>' . filter_output_html($cert['dn'] . ' / Seriennummer ' . $cert['serial'] . ' / ' . 'Gültig von ' . $cert['valid_from'] . ' bis ' . $cert['valid_until']) . '<br />');
66
-        output('<em>ausgestellt von </em>' . filter_output_html($cert['issuer']));
67
-        output('<br />' . internal_link('certsave', 'Dieses Zertifikat löschen', 'action=delete&id=' . $cert['id']));
68
-        output('</li>');
69
-    }
70
-    output('</ul>');
71
-} else {
72
-    output('<p><em>Bisher sind keine Zertifikate für Ihren Zugang eingerichtet</em></p>');
73
-}
74
-
75
-$backurl = 'go/index/cert';
76
-
77
-addnew('../../certlogin/index.php', 'Neues Client-Zertifikat hinzufügen', 'record&backto=' . $backurl);
... ...
@@ -1,20 +0,0 @@
1
-<?php
2
-
3
-/*
4
-This file belongs to the Webinterface of schokokeks.org Hosting
5
-
6
-Written by schokokeks.org Hosting, namely
7
-  Bernd Wurst <bernd@schokokeks.org>
8
-  Hanno Böck <hanno@schokokeks.org>
9
-
10
-This code is published under a 0BSD license.
11
-
12
-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.
13
-*/
14
-
15
-title('Login über SSL-Client-Zertifikat');
16
-output('<p>Sie können Sich an diesem Interface auch per SSL-Client-Zertifikat anmelden. Dazu müssen Sie dieses Zertifikat vorab hinterlegt haben.</p>
17
-
18
-<p>Um den Login über ein Client-Zertifikat zu nutzen, nutzen Sie bitte diesen Link:</p>
19
-<p><strong>' . internal_link('../../certlogin/', 'Login über SSL-Client-Zertifikat') . '</strong></p>
20
-');
... ...
@@ -1,76 +0,0 @@
1
-<?php
2
-
3
-/*
4
-This file belongs to the Webinterface of schokokeks.org Hosting
5
-
6
-Written by schokokeks.org Hosting, namely
7
-  Bernd Wurst <bernd@schokokeks.org>
8
-  Hanno Böck <hanno@schokokeks.org>
9
-
10
-This code is published under a 0BSD license.
11
-
12
-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.
13
-*/
14
-
15
-require_once('session/start.php');
16
-require_once('x509.php');
17
-
18
-require_role([ROLE_SYSTEMUSER, ROLE_SUBUSER, ROLE_VMAIL_ACCOUNT]);
19
-
20
-
21
-if ($_GET['action'] == 'new') {
22
-    check_form_token('clientcert_add');
23
-    if (!isset($_SESSION['clientcert_cert'])) {
24
-        system_failure('Kein Zertifikat');
25
-    }
26
-
27
-    add_clientcert(
28
-        $_SESSION['clientcert_cert'],
29
-        $_SESSION['clientcert_dn'],
30
-        $_SESSION['clientcert_issuer'],
31
-        $_SESSION['clientcert_serial'],
32
-        $_SESSION['clientcert_valid_from'],
33
-        $_SESSION['clientcert_valid_until']
34
-    );
35
-
36
-    // Räume session auf
37
-    unset($_SESSION['clientcert_cert']);
38
-    unset($_SESSION['clientcert_dn']);
39
-    unset($_SESSION['clientcert_issuer']);
40
-    unset($_SESSION['clientcert_serial']);
41
-    unset($_SESSION['clientcert_valid_from']);
42
-    unset($_SESSION['clientcert_valid_until']);
43
-    header('Location: cert');
44
-} elseif ($_GET['action'] == 'delete') {
45
-    $cert = get_cert_by_id($_GET['id']);
46
-    if (!$cert) {
47
-        system_failure('no ID');
48
-    }
49
-    $username = null;
50
-    if ($_SESSION['role'] & ROLE_SYSTEMUSER) {
51
-        $username = $_SESSION['userinfo']['username'];
52
-        if (isset($_SESSION['subuser'])) {
53
-            $username = $_SESSION['subuser'];
54
-        }
55
-    } elseif ($_SESSION['role'] & ROLE_VMAIL_ACCOUNT) {
56
-        $username = $_SESSION['mailaccount'];
57
-    }
58
-    if (!($cert['username'] == $username)) {
59
-        system_failure('Das Zertifikat ist nicht für Ihren Zugang eingerichtet');
60
-    }
61
-    $sure = user_is_sure();
62
-    if ($sure === null) {
63
-        are_you_sure("action=delete&id={$cert['id']}", filter_output_html("Möchten Sie das Zertifikat »{$cert['dn']}« (Seriennummer {$cert['serial']}, Gültig von {$cert['valid_from']} bis {$cert['valid_until']}) wirklich löschen?"));
64
-    } elseif ($sure === true) {
65
-        delete_clientcert($cert['id']);
66
-        if (!$debugmode) {
67
-            header("Location: cert");
68
-        }
69
-    } elseif ($sure === false) {
70
-        if (!$debugmode) {
71
-            header("Location: cert");
72
-        }
73
-    }
74
-} else {
75
-    system_failure('Kein Kommando');
76
-}
... ...
@@ -1,131 +0,0 @@
1
-<?php
2
-
3
-/*
4
-This file belongs to the Webinterface of schokokeks.org Hosting
5
-
6
-Written by schokokeks.org Hosting, namely
7
-  Bernd Wurst <bernd@schokokeks.org>
8
-  Hanno Böck <hanno@schokokeks.org>
9
-
10
-This code is published under a 0BSD license.
11
-
12
-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.
13
-*/
14
-
15
-require_once('inc/security.php');
16
-
17
-function get_logins_by_cert($cert)
18
-{
19
-    $result = db_query("SELECT type,username,startpage FROM system.clientcert WHERE cert=? ORDER BY type,username", [$cert]);
20
-    if ($result->rowCount() < 1) {
21
-        DEBUG("No certlogin found for this cert!");
22
-        return null;
23
-    } else {
24
-        $ret = [];
25
-        while ($row = $result->fetch()) {
26
-            $ret[] = $row;
27
-        }
28
-        DEBUG("Logins for this cert:");
29
-        DEBUG($ret);
30
-        return $ret;
31
-    }
32
-}
33
-
34
-function get_cert_by_id($id)
35
-{
36
-    $id = (int) $id;
37
-    if ($id == 0) {
38
-        system_failure('no ID');
39
-    }
40
-    $result = db_query("SELECT id,dn,issuer,serial,valid_from,valid_until,cert,username,startpage FROM system.clientcert WHERE `id`=?", [$id]);
41
-    if ($result->rowCount() < 1) {
42
-        return null;
43
-    }
44
-    $ret = $result->fetch();
45
-    DEBUG($ret);
46
-    return $ret;
47
-}
48
-
49
-
50
-function get_certs_by_username($username)
51
-{
52
-    if ($username == '') {
53
-        system_failure('empty username');
54
-    }
55
-    $result = db_query("SELECT id,dn,issuer,serial,valid_from,valid_until,cert,startpage FROM system.clientcert WHERE `username`=?", [$username]);
56
-    if ($result->rowCount() < 1) {
57
-        return null;
58
-    }
59
-    while ($row = $result->fetch()) {
60
-        $ret[] = $row;
61
-    }
62
-    return $ret;
63
-}
64
-
65
-
66
-function add_clientcert($certdata, $dn, $issuer, $serial, $vstart, $vend, $startpage = null)
67
-{
68
-    $type = null;
69
-    $username = null;
70
-    if ($_SESSION['role'] & ROLE_SYSTEMUSER) {
71
-        $type = 'user';
72
-        $username = $_SESSION['userinfo']['username'];
73
-        if (isset($_SESSION['subuser'])) {
74
-            $username = $_SESSION['subuser'];
75
-            $type = 'subuser';
76
-        }
77
-    } elseif ($_SESSION['role'] & ROLE_VMAIL_ACCOUNT) {
78
-        $type = 'email';
79
-        $username = $_SESSION['mailaccount'];
80
-    }
81
-    if (!$type || !$username) {
82
-        system_failure('cannot get type or username of login');
83
-    }
84
-    if ($startpage && !check_path($startpage)) {
85
-        system_failure('Startseite kaputt');
86
-    }
87
-
88
-    if ($certdata == '') {
89
-        system_failure('Kein Zertifikat');
90
-    }
91
-
92
-    $args = [":dn" => $dn,
93
-        ":issuer" => $issuer,
94
-        ":serial" => $serial,
95
-        ":vstart" => $vstart,
96
-        ":vend" => $vend,
97
-        ":certdata" => $certdata,
98
-        ":type" => $type,
99
-        ":username" => $username,
100
-        ":startpage" => $startpage, ];
101
-    DEBUG($args);
102
-
103
-    db_query("INSERT INTO system.clientcert (`dn`, `issuer`, `serial`, `valid_from`, `valid_until`, `cert`, `type`, `username`, `startpage`) 
104
-VALUES (:dn, :issuer, :serial, :vstart, :vend, :certdata, :type, :username, :startpage)", $args);
105
-}
106
-
107
-
108
-function delete_clientcert($id)
109
-{
110
-    $id = (int) $id;
111
-    $type = null;
112
-    $username = null;
113
-    if ($_SESSION['role'] & ROLE_SYSTEMUSER) {
114
-        $type = 'user';
115
-        $username = $_SESSION['userinfo']['username'];
116
-        if (isset($_SESSION['subuser'])) {
117
-            $username = $_SESSION['subuser'];
118
-            $type = 'subuser';
119
-        }
120
-    } elseif ($_SESSION['role'] & ROLE_VMAIL_ACCOUNT) {
121
-        $type = 'email';
122
-        $username = $_SESSION['mailaccount'];
123
-    }
124
-    if (!$type || !$username) {
125
-        system_failure('cannot get type or username of login');
126
-    }
127
-    db_query(
128
-        "DELETE FROM system.clientcert WHERE id=:id AND type=:type AND username=:username",
129
-        [":id" => $id, ":type" => $type, ":username" => $username]
130
-    );
131
-}
... ...
@@ -17,9 +17,6 @@ $role = $_SESSION['role'];
17 17
 if ($role == ROLE_ANONYMOUS) {
18 18
     $menu["index_login"] = ["label" => "Login", "file" => "index", "weight" => 0];
19 19
 } else {
20
-    if ($role & (ROLE_SYSTEMUSER | ROLE_SUBUSER | ROLE_VMAIL_ACCOUNT)) {
21
-        $menu["index_cert"] = ["label" => "Client-Zertifikat", "file" => "cert", "weight" => 10, "submenu" => "index_index"];
22
-    }
23 20
     if ($role & (ROLE_SYSTEMUSER | ROLE_CUSTOMER)) {
24 21
         $menu["index_chpass"] = ["label" => "Passwort ändern", "file" => "chpass", "weight" => 98];
25 22
     }
... ...
@@ -8,10 +8,8 @@ async function check_passkey() {
8 8
         PublicKeyCredential.isConditionalMediationAvailable) {
9 9
         const newButton = document.createElement('button');
10 10
         newButton.textContent = 'Mit Passkey/FIDO2-Gerät anmelden!';
11
-        const newPara = document.createElement('p');
11
+        newPara = document.getElementById("passkeybutton");
12 12
         newPara.appendChild(newButton)
13
-        certlogin = document.getElementById("certlogin")
14
-        certlogin.parentNode.insertBefore(newPara, certlogin)
15 13
         newButton.addEventListener('click', passkey_login);
16 14
     }
17 15
 }
... ...
@@ -71,8 +71,7 @@ if ($messages) {
71 71
 <p>Sie können sich hier mit Ihrem System-Benutzernamen, Ihrer E-Mail-Adresse oder Ihrer Kundennummer (jeweils mit zugehörigem Passwort) anmelden. Je nach gewählten Daten erhalten Sie unterschiedliche Zugriffsrechte.</p>
72 72
 <?php /* <p>Sollten Sie Ihr Benutzer-Passwort nicht mehr kennen, wenden Sie sich bitte an den Support. Passwörter für E-Mail-Konten kann der Eigentümer des Benutzeraccounts neu setzen.</p> */ ?>
73 73
 
74
-<p id="certlogin"><em><a href="../../certlogin/?destination=go/<?php echo $go; ?>"  >Mit einem Client-Zertifikat anmelden</a></em> (<a href="../../go/index/certinfo"  >Wie geht das?</a>)</p>
75
-
74
+<p id="passkeybutton"></p>
76 75
 
77 76
 <?php if ($footnotes) {
78 77
     echo '<div class="footnotes">';
79 78