]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0 server: Subscription remediation with user selected new password
authorJouni Malinen <jouni@codeaurora.org>
Mon, 8 Oct 2018 15:07:00 +0000 (18:07 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 11 Oct 2018 09:12:30 +0000 (12:12 +0300)
Add support for user remediation to request a new password from the user
for username/password credentials that have been configured not use use
machine managed password.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
hs20/server/spp_server.c
hs20/server/www/remediation-pw.php [new file with mode: 0644]
hs20/server/www/remediation.php

index d693317d4b7f64b0080a5817177f48ac780c30b8..389f6b0a7e4c22c9b6a2cb877d655d0b4581b7cf 100644 (file)
@@ -540,7 +540,8 @@ static xml_node_t * build_username_password(struct hs20_svc *ctx,
 
 
 static int add_username_password(struct hs20_svc *ctx, xml_node_t *cred,
-                                const char *user, const char *pw)
+                                const char *user, const char *pw,
+                                int machine_managed)
 {
        xml_node_t *node;
 
@@ -548,7 +549,8 @@ static int add_username_password(struct hs20_svc *ctx, xml_node_t *cred,
        if (node == NULL)
                return -1;
 
-       add_text_node(ctx, node, "MachineManaged", "TRUE");
+       add_text_node(ctx, node, "MachineManaged",
+                     machine_managed ? "TRUE" : "FALSE");
        add_text_node(ctx, node, "SoftTokenApp", "");
        add_eap_ttls(ctx, node);
 
@@ -573,7 +575,7 @@ static void add_creation_date(struct hs20_svc *ctx, xml_node_t *cred)
 
 static xml_node_t * build_credential_pw(struct hs20_svc *ctx,
                                        const char *user, const char *realm,
-                                       const char *pw)
+                                       const char *pw, int machine_managed)
 {
        xml_node_t *cred;
 
@@ -583,7 +585,7 @@ static xml_node_t * build_credential_pw(struct hs20_svc *ctx,
                return NULL;
        }
        add_creation_date(ctx, cred);
-       if (add_username_password(ctx, cred, user, pw) < 0) {
+       if (add_username_password(ctx, cred, user, pw, machine_managed) < 0) {
                xml_node_free(ctx->xml, cred);
                return NULL;
        }
@@ -600,7 +602,7 @@ static xml_node_t * build_credential(struct hs20_svc *ctx,
        if (new_password(new_pw, new_pw_len) < 0)
                return NULL;
        debug_print(ctx, 1, "Update password to '%s'", new_pw);
-       return build_credential_pw(ctx, user, realm, new_pw);
+       return build_credential_pw(ctx, user, realm, new_pw, 1);
 }
 
 
@@ -710,8 +712,23 @@ static xml_node_t * build_sub_rem_resp(struct hs20_svc *ctx,
                cred = build_credential_cert(ctx, real_user ? real_user : user,
                                             realm, cert);
        } else {
-               cred = build_credential(ctx, real_user ? real_user : user,
-                                       realm, new_pw, sizeof(new_pw));
+               char *pw;
+
+               pw = db_get_session_val(ctx, user, realm, session_id,
+                                       "password");
+               if (pw && pw[0]) {
+                       debug_print(ctx, 1, "New password from the user: '%s'",
+                                   pw);
+                       snprintf(new_pw, sizeof(new_pw), "%s", pw);
+                       free(pw);
+                       cred = build_credential_pw(ctx,
+                                                  real_user ? real_user : user,
+                                                  realm, new_pw, 0);
+               } else {
+                       cred = build_credential(ctx,
+                                               real_user ? real_user : user,
+                                               realm, new_pw, sizeof(new_pw));
+               }
        }
        free(real_user);
        if (!cred) {
@@ -1471,7 +1488,7 @@ static xml_node_t * hs20_user_input_free_remediation(struct hs20_svc *ctx,
                return NULL;
        }
 
-       cred = build_credential_pw(ctx, free_account, realm, pw);
+       cred = build_credential_pw(ctx, free_account, realm, pw, 1);
        free(free_account);
        free(pw);
        if (!cred) {
diff --git a/hs20/server/www/remediation-pw.php b/hs20/server/www/remediation-pw.php
new file mode 100644 (file)
index 0000000..76fdccb
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+require('config.php');
+
+$db = new PDO($osu_db);
+if (!$db) {
+   die($sqliteerror);
+}
+
+if (isset($_POST["id"]))
+  $id = preg_replace("/[^a-fA-F0-9]/", "", $_POST["id"]);
+else
+  die("Missing session id");
+
+$pw = $_POST["password"];
+if (strlen($id) < 32 || !isset($pw)) {
+  die("Invalid POST data");
+}
+
+$row = $db->query("SELECT rowid,* FROM sessions WHERE id='$id'")->fetch();
+if ($row == false) {
+   die("Session not found");
+}
+$user = $row['user'];
+$realm = $row['realm'];
+
+$uri = $row['redirect_uri'];
+$rowid = $row['rowid'];
+
+if (!$db->exec("UPDATE sessions SET password='$pw' WHERE rowid=$rowid")) {
+  die("Failed to update session database");
+}
+
+$db->exec("INSERT INTO eventlog(user,realm,sessionid,timestamp,notes) " .
+       "VALUES ('$user', '$realm', '$id', " .
+       "strftime('%Y-%m-%d %H:%M:%f','now'), " .
+       "'completed user input response for subscription remediation')");
+
+header("Location: $uri", true, 302);
+
+?>
index 392a7bd7e59a12f91508ca72b8ad4d5dde6629fb..3628065ac225ec540009802fe8fceb5ab3d4f69e 100644 (file)
@@ -6,13 +6,50 @@
 
 <?php
 
-echo "SessionID: " . $_GET["session_id"] . "<br>\n";
+require('config.php');
 
-echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Complete user subscription remediation</a><br>\n";
+$db = new PDO($osu_db);
+if (!$db) {
+   die($sqliteerror);
+}
 
-?>
+if (isset($_GET["session_id"]))
+       $id = preg_replace("/[^a-fA-F0-9]/", "", $_GET["session_id"]);
+else
+       $id = 0;
+echo "SessionID: " . $id . "<br>\n";
+
+$row = $db->query("SELECT * FROM sessions WHERE id='$id'")->fetch();
+if ($row == false) {
+   die("Session not found");
+}
+
+$username = $row['user'];
+echo "User: " . $username . "@" . $row['realm'] . "<br>\n";
+
+$user = $db->query("SELECT machine_managed,methods FROM users WHERE identity='$username'")->fetch();
+if ($user == false) {
+   die("User not found");
+}
 
-This will provide a new machine-generated password.
+echo "<hr><br>\n";
+
+$cert = $user['methods'] == "TLS" || strncmp($username, "cert-", 5) == 0;
+
+if ($cert) {
+   echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Complete user subscription remediation</a><br>\n";
+} else if ($user['machine_managed'] == "1") {
+   echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Complete user subscription remediation</a><br>\n";
+   echo "This will provide a new machine-generated password.<br>\n";
+} else {
+   echo "<form action=\"remediation-pw.php\" method=\"POST\">\n";
+   echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n";
+   echo "New password: <input type=\"password\" name=\"password\"><br>\n";
+   echo "<input type=\"submit\" value=\"Change password\">\n";
+   echo "</form>\n";
+}
+
+?>
 
 </body>
 </html>