Skip to content

Commit

Permalink
webui: crypt user password by default before passing it to backend
Browse files Browse the repository at this point in the history
NOTE: using the same method as the current Gtk GUI
  • Loading branch information
rvykydal committed Nov 23, 2023
1 parent eabdf42 commit 743039c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
10 changes: 7 additions & 3 deletions src/components/AnacondaWizard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { getDefaultScenario } from "./storage/InstallationScenario.jsx";
import { MountPointMapping, getPageProps as getMountPointMappingProps } from "./storage/MountPointMapping.jsx";
import { DiskEncryption, getStorageEncryptionState, getPageProps as getDiskEncryptionProps } from "./storage/DiskEncryption.jsx";
import { InstallationLanguage, getPageProps as getInstallationLanguageProps } from "./localization/InstallationLanguage.jsx";
import { Accounts, getPageProps as getAccountsProps, getAccountsState, accountsToDbusUsers } from "./users/Accounts.jsx";
import { Accounts, getPageProps as getAccountsProps, getAccountsState, accountsToDbusUsers, cryptUserPassword } from "./users/Accounts.jsx";
import { InstallationProgress } from "./installation/InstallationProgress.jsx";
import { ReviewConfiguration, ReviewConfigurationConfirmModal, getPageProps as getReviewConfigurationProps } from "./review/ReviewConfiguration.jsx";
import { exitGui } from "../helpers/exit.js";
Expand Down Expand Up @@ -362,8 +362,12 @@ const Footer = ({
},
});
} else if (activeStep.id === "accounts") {
setUsers(accountsToDbusUsers(accounts));
onNext();
cryptUserPassword(accounts.password)
.then(cryptedPassword => {
const users = accountsToDbusUsers({ ...accounts, password: cryptedPassword });
setUsers(users);
onNext();
}, onCritFail({ context: N_("Password ecryption failed.") }));
} else {
onNext();
}
Expand Down
9 changes: 8 additions & 1 deletion src/components/users/Accounts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import cockpit from "cockpit";
import React, { useState, useEffect } from "react";
import * as python from "python.js";
import encryptUserPw from "../../scripts/encrypt-user-pw.py";

import {
Form,
Expand Down Expand Up @@ -45,12 +47,17 @@ export function getAccountsState (
};
}

export const cryptUserPassword = async (password) => {
const crypted = await python.spawn(encryptUserPw, password, { err: "message", environ: ["LC_ALL=C.UTF-8"] });
return crypted;
};

export const accountsToDbusUsers = (accounts) => {
return [{
name: cockpit.variant("s", accounts.userAccount || ""),
gecos: cockpit.variant("s", accounts.fullName || ""),
password: cockpit.variant("s", accounts.password || ""),
"is-crypted": cockpit.variant("b", false),
"is-crypted": cockpit.variant("b", true),
groups: cockpit.variant("as", ["wheel"]),
}];
};
Expand Down
42 changes: 42 additions & 0 deletions src/scripts/encrypt-user-pw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import crypt
from random import SystemRandom as sr
import sys

# Using the function from pyanaconda/core/users.py

def crypt_password(password):
"""Crypt a password.
Process a password with appropriate salted one-way algorithm.
:param str password: password to be crypted
:returns: crypted representation of the original password
:rtype: str
"""
# yescrypt is not supported by Python's crypt module,
# so we need to generate the setting ourselves
b64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
setting = "$y$j9T$" + "".join(sr().choice(b64) for _sc in range(24))

# and try to compute the password hash using our yescrypt setting
try:
cryptpw = crypt.crypt(password, setting)

# Fallback to sha512crypt, if yescrypt is not supported
except OSError:
sys.stderr.write("yescrypt is not supported, falling back to sha512crypt\n")
try:
cryptpw = crypt.crypt(password, crypt.METHOD_SHA512)
except OSError as exc:
raise RuntimeError(
"Unable to encrypt password: unsupported algorithm {}".format(crypt.METHOD_SHA512)
) from exc

return cryptpw


try:
print(crypt_password(sys.argv[1]), end="")
except Exception as e:
sys.stderr.write(str(e) + "\n")
sys.exit(1)
3 changes: 1 addition & 2 deletions test/check-users
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ class TestUsers(anacondalib.VirtInstallMachineCase):

users = u.dbus_get_users()
self.assertIn('"groups" as 1 "wheel"', users)
self.assertIn('"is-crypted" b false', users)
self.assertIn('"password" s "password"', users)
self.assertIn('"is-crypted" b true', users)

if __name__ == '__main__':
test_main()

0 comments on commit 743039c

Please sign in to comment.