diff --git a/addKey.php b/addKey.php index 24c0bcd..7e68090 100644 --- a/addKey.php +++ b/addKey.php @@ -16,7 +16,8 @@ if($settings == "valid") if(!@mysqli_select_db($dbconn,$mysql_db)) $err = error("Datenbank nicht gefunden!! ($mysql_db)"); } -if($_SESSION["login"] == "valid" && isset($_GET["id"])){ +// Wie sites/userkeys.php: nur Superadmins dürfen Passkeys vergeben +if($_SESSION["login"] == "valid" && isset($_GET["id"]) && ((int)substr($_SESSION["rights"], RIGHTS_SUPERADMIN, 1) & RIGHTS_CHANGE)){ if(!mysqli_query($dbconn,"DELETE FROM addKey WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE);")){ echo mysqli_error($dbconn); } @@ -25,8 +26,8 @@ if($_SESSION["login"] == "valid" && isset($_GET["id"])){ if(!mysqli_query($dbconn,"INSERT INTO addKey SET accesskey=".$accessKey.", datetime=NOW();")){ echo mysqli_error($dbconn); } - header('Location: https://wm.el-wa.org/kunden?action=userkeys&id='.$_GET["id"].'&addKey='.$accessKey); - echo 'https://wm.el-wa.org/kunden?action=userkeys&id='.$_GET["id"].'&addKey='.$accessKey; + header('Location: https://wm.el-wa.org/kunden?action=userkeys&id='.(int)$_GET["id"].'&addKey='.$accessKey); + echo 'https://wm.el-wa.org/kunden?action=userkeys&id='.(int)$_GET["id"].'&addKey='.$accessKey; }else{ echo "Keine Berechtigung."; } diff --git a/authServer.php b/authServer.php index 7bf3b01..377eeaa 100644 --- a/authServer.php +++ b/authServer.php @@ -107,6 +107,24 @@ try { // request for create arguments // ------------------------------------ + // Passkeys anlegen darf nur ein angemeldeter Superadmin, der vorher in + // sites/userkeys.php eine gültige Einmal-Freigabe (addKey) eingelöst hat. + // Die Freigabe liegt in der Session und legt fest, für welchen Benutzer + // der Schlüssel gilt - die id aus der URL zählt nicht. + $passkeyFreigabe = null; + if (isset($_SESSION["passkey_freigabe"]) && $_SESSION["passkey_freigabe"]["bis"] >= time() + && ($_SESSION["login"] ?? "") == "valid" + && ((int)substr($_SESSION["rights"] ?? "", RIGHTS_SUPERADMIN, 1) & RIGHTS_CHANGE)) { + $passkeyFreigabe = $_SESSION["passkey_freigabe"]; + } + if (($fn === 'getCreateArgs' || $fn === 'processCreate') && $passkeyFreigabe === null) { + throw new Exception('Keine Berechtigung, Passkeys anzulegen.'); + } + if ($fn === 'queryFidoMetaDataService' + && !(($_SESSION["login"] ?? "") == "valid" && ((int)substr($_SESSION["rights"] ?? "", RIGHTS_SUPERADMIN, 1) & RIGHTS_CHANGE))) { + throw new Exception('Keine Berechtigung.'); + } + if ($fn === 'getCreateArgs') { $createArgs = $WebAuthn->getCreateArgs(\hex2bin($userId), $userName, $userDisplayName, 60*4, $requireResidentKey, $userVerification, $crossPlatformAttachment); @@ -181,10 +199,12 @@ try { if (!isset($_SESSION['registrations']) || !array_key_exists('registrations', $_SESSION) || !is_array($_SESSION['registrations'])) { $_SESSION['registrations'] = []; }*/ - if(!mysqli_query($dbconn,"INSERT INTO passkeys SET credentialId = '".base64_encode($data->credentialId)."', credentialPublicKey = '".base64_encode($data->credentialPublicKey)."', signatureCounter = '".base64_encode($data->signatureCounter)."', name = '".mysqli_real_escape_string($mysql,filter_input(INPUT_GET, 'name'))."', userId = '".mysqli_real_escape_string($mysql,filter_input(INPUT_GET, 'id'))."';")){ + if(!mysqli_query($dbconn,"INSERT INTO passkeys SET credentialId = '".base64_encode($data->credentialId)."', credentialPublicKey = '".base64_encode($data->credentialPublicKey)."', signatureCounter = '".base64_encode($data->signatureCounter)."', name = '".mysqli_real_escape_string($mysql,filter_input(INPUT_GET, 'name'))."', userId = '".(int)$passkeyFreigabe["user"]."';")){ $msg = "Error:
".mysqli_error($dbconn)."
"; } else{ + // Freigabe gilt für genau einen Schlüssel + unset($_SESSION["passkey_freigabe"]); if ($data->rootValid === false) { $msg = 'registration ok, but certificate does not match any of the selected root ca. NO PROBLEM FOR THIS APP'; } @@ -253,10 +273,16 @@ try { $authKey = strval(random_int(0,99999999)); $result = mysqli_query($dbconn,"UPDATE passkeys SET authKey=".$authKey.", lastAuth=NOW() WHERE credentialId = '".base64_encode($id)."';"); - $qry= mysqli_query($dbconn, "SELECT * FROM user WHERE id = '".mysqli_real_escape_string($dbconn,$userId)."'"); - if(mysqli_num_rows($qry) == 1) + // Gesperrte Benutzer bleiben gesperrt, auch mit gültigem Passkey + $qry= mysqli_query($dbconn, "SELECT * FROM user WHERE id = '".mysqli_real_escape_string($dbconn,$userId)."' AND blocked = 0"); + if(!$qry || mysqli_num_rows($qry) != 1) + { + throw new Exception('Benutzer nicht gefunden oder gesperrt.'); + } + else { $udata = mysqli_fetch_assoc($qry); + session_regenerate_id(true); $_SESSION["login"] = "valid"; $_SESSION["logedout"] = $udata["logedout"]; $_SESSION["user"] = $udata["id"]; diff --git a/sites/start.php b/sites/start.php index afd3d03..eb43930 100644 --- a/sites/start.php +++ b/sites/start.php @@ -20,6 +20,8 @@ if(isset($_GET["formsent"]) && $_SESSION["login"] != "valid" && isLocal()) if(mysqli_num_rows($qry) == 1) { $udata = mysqli_fetch_assoc($qry); + // neue Session-ID nach dem Login, sonst ist Session-Fixation möglich + session_regenerate_id(true); $_SESSION["login"] = "valid"; $_SESSION["logedout"] = $udata["logedout"]; $_SESSION["user"] = $udata["id"]; diff --git a/sites/userkeys.php b/sites/userkeys.php index 64f3e94..fe0a60f 100644 --- a/sites/userkeys.php +++ b/sites/userkeys.php @@ -2,7 +2,12 @@ if(isset($_GET["id"]) && isset($_GET["addKey"])){ - if (checkAdduser($_GET["addUser"])) { + if (checkAdduser()) { + // Freigabe einlösen: gilt 5 Minuten, nur für diesen Benutzer und nur + // in dieser Session (geprüft in authServer.php). Der addKey ist damit + // verbraucht. + $_SESSION["passkey_freigabe"] = array("user" => (int)$_GET["id"], "bis" => time() + 300); + mysqli_query($mysql, "DELETE FROM addKey WHERE accesskey = '".mysqli_real_escape_string($mysql, $_GET["addKey"])."'"); echo << @@ -73,11 +78,11 @@ if(isset($_GET["id"]) && isset($_GET["addKey"])){ $smarty->assign("heading","Passkeys für externen Zugang verwalten"); $smarty->display("heading.tpl"); -$qry = mysqli_query($_SESSION["dbconn"],"SELECT id, vname, nname FROM user WHERE blocked = 0 AND user.id = ".mysqli_real_escape_string($_SESSION["dbconn"],$_GET["id"])) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"])); +$qry = mysqli_query($_SESSION["dbconn"],"SELECT id, vname, nname FROM user WHERE blocked = 0 AND user.id = ".(int)$_GET["id"]) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"])); $row=mysqli_fetch_array($qry); $smarty->assign("user",$row); -$qry = mysqli_query($_SESSION["dbconn"],"SELECT passkeys.id , passkeys.name FROM user JOIN passkeys ON user.id = passkeys.userId WHERE blocked = 0 AND user.id = ".mysqli_real_escape_string($_SESSION["dbconn"],$_GET["id"])) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"])); +$qry = mysqli_query($_SESSION["dbconn"],"SELECT passkeys.id , passkeys.name FROM user JOIN passkeys ON user.id = passkeys.userId WHERE blocked = 0 AND user.id = ".(int)$_GET["id"]) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"])); $keys = array(); while($row=mysqli_fetch_array($qry)){ $keys[] = $row;