HS 2.0 server: Subscription remediation with user selected new password
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>
This commit is contained in:
parent
f718e5e22c
commit
cc5f797593
3 changed files with 107 additions and 12 deletions
|
@ -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,
|
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;
|
xml_node_t *node;
|
||||||
|
|
||||||
|
@ -548,7 +549,8 @@ static int add_username_password(struct hs20_svc *ctx, xml_node_t *cred,
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return -1;
|
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_text_node(ctx, node, "SoftTokenApp", "");
|
||||||
add_eap_ttls(ctx, node);
|
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,
|
static xml_node_t * build_credential_pw(struct hs20_svc *ctx,
|
||||||
const char *user, const char *realm,
|
const char *user, const char *realm,
|
||||||
const char *pw)
|
const char *pw, int machine_managed)
|
||||||
{
|
{
|
||||||
xml_node_t *cred;
|
xml_node_t *cred;
|
||||||
|
|
||||||
|
@ -583,7 +585,7 @@ static xml_node_t * build_credential_pw(struct hs20_svc *ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
add_creation_date(ctx, cred);
|
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);
|
xml_node_free(ctx->xml, cred);
|
||||||
return NULL;
|
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)
|
if (new_password(new_pw, new_pw_len) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
debug_print(ctx, 1, "Update password to '%s'", new_pw);
|
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,9 +712,24 @@ static xml_node_t * build_sub_rem_resp(struct hs20_svc *ctx,
|
||||||
cred = build_credential_cert(ctx, real_user ? real_user : user,
|
cred = build_credential_cert(ctx, real_user ? real_user : user,
|
||||||
realm, cert);
|
realm, cert);
|
||||||
} else {
|
} else {
|
||||||
cred = build_credential(ctx, real_user ? real_user : user,
|
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));
|
realm, new_pw, sizeof(new_pw));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(real_user);
|
free(real_user);
|
||||||
if (!cred) {
|
if (!cred) {
|
||||||
debug_print(ctx, 1, "Could not build credential");
|
debug_print(ctx, 1, "Could not build credential");
|
||||||
|
@ -1471,7 +1488,7 @@ static xml_node_t * hs20_user_input_free_remediation(struct hs20_svc *ctx,
|
||||||
return NULL;
|
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(free_account);
|
||||||
free(pw);
|
free(pw);
|
||||||
if (!cred) {
|
if (!cred) {
|
||||||
|
|
41
hs20/server/www/remediation-pw.php
Normal file
41
hs20/server/www/remediation-pw.php
Normal file
|
@ -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);
|
||||||
|
|
||||||
|
?>
|
|
@ -6,13 +6,50 @@
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
echo "SessionID: " . $_GET["session_id"] . "<br>\n";
|
require('config.php');
|
||||||
|
|
||||||
|
$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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
This will provide a new machine-generated password.
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue