diff --git a/live/root/etc/systemd/system/live-password-cmdline.service b/live/root/etc/systemd/system/live-password-cmdline.service index 0893c64b19..3307967f7b 100644 --- a/live/root/etc/systemd/system/live-password-cmdline.service +++ b/live/root/etc/systemd/system/live-password-cmdline.service @@ -9,7 +9,7 @@ Before=agama-web-server.service Before=live-password-dialog.service Before=live-password-systemd.service -# plain text password or encrypted password passed via kernel command line +# plain text password or hashed password passed via kernel command line ConditionKernelCommandLine=|live.password ConditionKernelCommandLine=|live.password_hash diff --git a/rust/agama-lib/share/profile.schema.json b/rust/agama-lib/share/profile.schema.json index 83ddee9ca2..d71f7576d0 100644 --- a/rust/agama-lib/share/profile.schema.json +++ b/rust/agama-lib/share/profile.schema.json @@ -382,12 +382,12 @@ "examples": ["jane.doe"] }, "password": { - "title": "User password (plain text or encrypted depending on the \"encryptedPassword\" field)", + "title": "User password (plain text or hashed depending on the \"hashedPassword\" field)", "type": "string", "examples": ["nots3cr3t"] }, - "encryptedPassword": { - "title": "Flag for encrypted password (true) or plain text password (false or not defined)", + "hashedPassword": { + "title": "Flag for hashed password (true) or plain text password (false or not defined)", "type": "boolean" } }, @@ -399,11 +399,11 @@ "additionalProperties": false, "properties": { "password": { - "title": "Root password (plain text or encrypted depending on the \"encryptedPassword\" field)", + "title": "Root password (plain text or hashed depending on the \"hashedPassword\" field)", "type": "string" }, - "encryptedPassword": { - "title": "Flag for encrypted password (true) or plain text password (false or not defined)", + "hashedPassword": { + "title": "Flag for hashed password (true) or plain text password (false or not defined)", "type": "boolean" }, "sshPublicKey": { diff --git a/rust/agama-lib/src/users/client.rs b/rust/agama-lib/src/users/client.rs index 9747619236..6faafd8961 100644 --- a/rust/agama-lib/src/users/client.rs +++ b/rust/agama-lib/src/users/client.rs @@ -35,8 +35,8 @@ pub struct FirstUser { pub user_name: String, /// First user's password (in clear text) pub password: String, - /// Whether the password is encrypted (true) or is plain text (false) - pub encrypted_password: bool, + /// Whether the password is hashed (true) or is plain text (false) + pub hashed_password: bool, /// Whether auto-login should enabled or not pub autologin: bool, } @@ -48,7 +48,7 @@ impl FirstUser { full_name: data.0, user_name: data.1, password: data.2, - encrypted_password: data.3, + hashed_password: data.3, autologin: data.4, }) } @@ -73,12 +73,8 @@ impl<'a> UsersClient<'a> { } /// SetRootPassword method - pub async fn set_root_password( - &self, - value: &str, - encrypted: bool, - ) -> Result { - Ok(self.users_proxy.set_root_password(value, encrypted).await?) + pub async fn set_root_password(&self, value: &str, hashed: bool) -> Result { + Ok(self.users_proxy.set_root_password(value, hashed).await?) } pub async fn remove_root_password(&self) -> Result { @@ -110,7 +106,7 @@ impl<'a> UsersClient<'a> { &first_user.full_name, &first_user.user_name, &first_user.password, - first_user.encrypted_password, + first_user.hashed_password, first_user.autologin, std::collections::HashMap::new(), ) diff --git a/rust/agama-lib/src/users/http_client.rs b/rust/agama-lib/src/users/http_client.rs index a879826ddc..1008ed48d8 100644 --- a/rust/agama-lib/src/users/http_client.rs +++ b/rust/agama-lib/src/users/http_client.rs @@ -58,15 +58,11 @@ impl UsersHTTPClient { /// SetRootPassword method. /// Returns 0 if successful (always, for current backend) - pub async fn set_root_password( - &self, - value: &str, - encrypted: bool, - ) -> Result { + pub async fn set_root_password(&self, value: &str, hashed: bool) -> Result { let rps = RootPatchSettings { sshkey: None, password: Some(value.to_owned()), - encrypted_password: Some(encrypted), + hashed_password: Some(hashed), }; let ret = self.client.patch("/users/root", &rps).await?; Ok(ret) @@ -84,7 +80,7 @@ impl UsersHTTPClient { let rps = RootPatchSettings { sshkey: Some(value.to_owned()), password: None, - encrypted_password: None, + hashed_password: None, }; let ret = self.client.patch("/users/root", &rps).await?; Ok(ret) diff --git a/rust/agama-lib/src/users/model.rs b/rust/agama-lib/src/users/model.rs index 66d93c9d6f..90e07fecfe 100644 --- a/rust/agama-lib/src/users/model.rs +++ b/rust/agama-lib/src/users/model.rs @@ -35,6 +35,6 @@ pub struct RootPatchSettings { pub sshkey: Option, /// empty string here means remove password for root pub password: Option, - /// specify if patched password is provided in encrypted form - pub encrypted_password: Option, + /// specify if patched password is provided in plain text (default) or hashed + pub hashed_password: Option, } diff --git a/rust/agama-lib/src/users/proxies.rs b/rust/agama-lib/src/users/proxies.rs index b3743701de..f75921b2ee 100644 --- a/rust/agama-lib/src/users/proxies.rs +++ b/rust/agama-lib/src/users/proxies.rs @@ -47,7 +47,7 @@ use zbus::proxy; /// * full name /// * user name /// * password -/// * encrypted_password (true = encrypted, false = plain text) +/// * hashed_password (true = hashed, false = plain text) /// * auto-login (enabled or not) /// * some optional and additional data // NOTE: Manually added to this file. @@ -79,13 +79,13 @@ pub trait Users1 { full_name: &str, user_name: &str, password: &str, - encrypted_password: bool, + hashed_password: bool, auto_login: bool, data: std::collections::HashMap<&str, &zbus::zvariant::Value<'_>>, ) -> zbus::Result<(bool, Vec)>; /// SetRootPassword method - fn set_root_password(&self, value: &str, encrypted: bool) -> zbus::Result; + fn set_root_password(&self, value: &str, hashed: bool) -> zbus::Result; /// SetRootSSHKey method #[zbus(name = "SetRootSSHKey")] diff --git a/rust/agama-lib/src/users/settings.rs b/rust/agama-lib/src/users/settings.rs index bd5eea47af..546e5de193 100644 --- a/rust/agama-lib/src/users/settings.rs +++ b/rust/agama-lib/src/users/settings.rs @@ -43,8 +43,8 @@ pub struct FirstUserSettings { pub user_name: Option, /// First user's password (in clear text) pub password: Option, - /// Whether the password is encrypted or is plain text - pub encrypted_password: Option, + /// Whether the password is hashed or is plain text + pub hashed_password: Option, /// Whether auto-login should enabled or not pub autologin: Option, } @@ -58,9 +58,9 @@ pub struct RootUserSettings { /// Root's password (in clear text) #[serde(skip_serializing)] pub password: Option, - /// Whether the password is encrypted or is plain text + /// Whether the password is hashed or is plain text #[serde(skip_serializing)] - pub encrypted_password: Option, + pub hashed_password: Option, /// Root SSH public key pub ssh_public_key: Option, } diff --git a/rust/agama-lib/src/users/store.rs b/rust/agama-lib/src/users/store.rs index 67289d57d4..77995a027f 100644 --- a/rust/agama-lib/src/users/store.rs +++ b/rust/agama-lib/src/users/store.rs @@ -47,7 +47,7 @@ impl UsersStore { autologin: Some(first_user.autologin), full_name: Some(first_user.full_name), password: Some(first_user.password), - encrypted_password: Some(first_user.encrypted_password), + hashed_password: Some(first_user.hashed_password), }; let mut root_user = RootUserSettings::default(); let ssh_public_key = self.users_client.root_ssh_key().await?; @@ -78,17 +78,17 @@ impl UsersStore { full_name: settings.full_name.clone().unwrap_or_default(), autologin: settings.autologin.unwrap_or_default(), password: settings.password.clone().unwrap_or_default(), - encrypted_password: settings.encrypted_password.unwrap_or_default(), + hashed_password: settings.hashed_password.unwrap_or_default(), }; self.users_client.set_first_user(&first_user).await } async fn store_root_user(&self, settings: &RootUserSettings) -> Result<(), ServiceError> { - let encrypted_password = settings.encrypted_password.unwrap_or_default(); + let hashed_password = settings.hashed_password.unwrap_or_default(); if let Some(root_password) = &settings.password { self.users_client - .set_root_password(root_password, encrypted_password) + .set_root_password(root_password, hashed_password) .await?; } @@ -128,7 +128,7 @@ mod test { "fullName": "Tux", "userName": "tux", "password": "fish", - "encryptedPassword": false, + "hashedPassword": false, "autologin": true }"#, ); @@ -153,13 +153,13 @@ mod test { full_name: Some("Tux".to_owned()), user_name: Some("tux".to_owned()), password: Some("fish".to_owned()), - encrypted_password: Some(false), + hashed_password: Some(false), autologin: Some(true), }; let root_user = RootUserSettings { // FIXME this is weird: no matter what HTTP reports, we end up with None password: None, - encrypted_password: None, + hashed_password: None, ssh_public_key: Some("keykeykey".to_owned()), }; let expected = UserSettings { @@ -184,7 +184,7 @@ mod test { when.method(PUT) .path("/api/users/first") .header("content-type", "application/json") - .body(r#"{"fullName":"Tux","userName":"tux","password":"fish","encryptedPassword":false,"autologin":true}"#); + .body(r#"{"fullName":"Tux","userName":"tux","password":"fish","hashedPassword":false,"autologin":true}"#); then.status(200); }); // note that we use 2 requests for root @@ -192,14 +192,14 @@ mod test { when.method(PATCH) .path("/api/users/root") .header("content-type", "application/json") - .body(r#"{"sshkey":null,"password":"1234","encryptedPassword":false}"#); + .body(r#"{"sshkey":null,"password":"1234","hashedPassword":false}"#); then.status(200).body("0"); }); let root_mock2 = server.mock(|when, then| { when.method(PATCH) .path("/api/users/root") .header("content-type", "application/json") - .body(r#"{"sshkey":"keykeykey","password":null,"encryptedPassword":null}"#); + .body(r#"{"sshkey":"keykeykey","password":null,"hashedPassword":null}"#); then.status(200).body("0"); }); let url = server.url("/api"); @@ -210,12 +210,12 @@ mod test { full_name: Some("Tux".to_owned()), user_name: Some("tux".to_owned()), password: Some("fish".to_owned()), - encrypted_password: Some(false), + hashed_password: Some(false), autologin: Some(true), }; let root_user = RootUserSettings { password: Some("1234".to_owned()), - encrypted_password: Some(false), + hashed_password: Some(false), ssh_public_key: Some("keykeykey".to_owned()), }; let settings = UserSettings { diff --git a/rust/agama-server/src/users/web.rs b/rust/agama-server/src/users/web.rs index de9c2901d7..260ec35133 100644 --- a/rust/agama-server/src/users/web.rs +++ b/rust/agama-server/src/users/web.rs @@ -90,7 +90,7 @@ async fn first_user_changed_stream( full_name: user.0, user_name: user.1, password: user.2, - encrypted_password: user.3, + hashed_password: user.3, autologin: user.4, }; return Some(Event::FirstUserChanged(user_struct)); @@ -243,7 +243,7 @@ async fn patch_root( } else { state .users - .set_root_password(&password, config.encrypted_password == Some(true)) + .set_root_password(&password, config.hashed_password == Some(true)) .await? } } diff --git a/service/lib/agama/autoyast/root_reader.rb b/service/lib/agama/autoyast/root_reader.rb index 84737c8a80..6cc1866269 100755 --- a/service/lib/agama/autoyast/root_reader.rb +++ b/service/lib/agama/autoyast/root_reader.rb @@ -41,7 +41,7 @@ def read return {} unless root_user hsh = { "password" => root_user.password.value.to_s } - hsh["encryptedPassword"] = true if root_user.password.value.encrypted? + hsh["hashedPassword"] = true if root_user.password.value.encrypted? public_key = root_user.authorized_keys.first hsh["sshPublicKey"] = public_key if public_key diff --git a/service/lib/agama/autoyast/user_reader.rb b/service/lib/agama/autoyast/user_reader.rb index 84335845bb..5c01291075 100755 --- a/service/lib/agama/autoyast/user_reader.rb +++ b/service/lib/agama/autoyast/user_reader.rb @@ -46,7 +46,7 @@ def read "password" => user.password.value.to_s } - hsh["encryptedPassword"] = true if user.password.value.encrypted? + hsh["hashedPassword"] = true if user.password.value.encrypted? { "user" => hsh } end diff --git a/service/lib/agama/dbus/users.rb b/service/lib/agama/dbus/users.rb index e44e2b09a8..57b30a0b82 100644 --- a/service/lib/agama/dbus/users.rb +++ b/service/lib/agama/dbus/users.rb @@ -58,7 +58,7 @@ def issues USERS_INTERFACE = "org.opensuse.Agama.Users1" private_constant :USERS_INTERFACE - FUSER_SIG = "in FullName:s, in UserName:s, in Password:s, in EncryptedPassword:b, " \ + FUSER_SIG = "in FullName:s, in UserName:s, in Password:s, in HashedPassword:b, " \ "in AutoLogin:b, in data:a{sv}" private_constant :FUSER_SIG @@ -70,9 +70,9 @@ def issues dbus_reader :first_user, "(sssbba{sv})" dbus_method :SetRootPassword, - "in Value:s, in Encrypted:b, out result:u" do |value, encrypted| + "in Value:s, in Hashed:b, out result:u" do |value, hashed| logger.info "Setting Root Password" - backend.assign_root_password(value, encrypted) + backend.assign_root_password(value, hashed) dbus_properties_changed(USERS_INTERFACE, { "RootPasswordSet" => !value.empty? }, []) 0 @@ -99,10 +99,10 @@ def issues # It returns an Struct with the first field with the result of the operation as a boolean # and the second parameter as an array of issues found in case of failure FUSER_SIG + ", out result:(bas)" do - |full_name, user_name, password, encrypted_password, auto_login, data| + |full_name, user_name, password, hashed_password, auto_login, data| logger.info "Setting first user #{full_name}" user_issues = backend.assign_first_user(full_name, user_name, password, - encrypted_password, auto_login, data) + hashed_password, auto_login, data) if user_issues.empty? dbus_properties_changed(USERS_INTERFACE, { "FirstUser" => first_user }, []) diff --git a/service/lib/agama/users.rb b/service/lib/agama/users.rb index 84c17cef65..7fa0f921de 100644 --- a/service/lib/agama/users.rb +++ b/service/lib/agama/users.rb @@ -60,8 +60,8 @@ def root_ssh_key? !root_ssh_key.empty? end - def assign_root_password(value, encrypted) - pwd = if encrypted + def assign_root_password(value, hashed) + pwd = if hashed Y2Users::Password.create_encrypted(value) else Y2Users::Password.create_plain(value) @@ -99,16 +99,16 @@ def remove_root_password # @param full_name [String] # @param user_name [String] # @param password [String] - # @param encrypted_password [Boolean] true = encrypted password, false = plain text password + # @param hashed_password [Boolean] true = hashed password, false = plain text password # @param auto_login [Boolean] # @param _data [Hash] # @return [Array] the list of fatal issues found - def assign_first_user(full_name, user_name, password, encrypted_password, auto_login, _data) + def assign_first_user(full_name, user_name, password, hashed_password, auto_login, _data) remove_first_user user = Y2Users::User.new(user_name) user.gecos = [full_name] - user.password = if encrypted_password + user.password = if hashed_password Y2Users::Password.create_encrypted(password) else Y2Users::Password.create_plain(password) diff --git a/service/test/agama/users_test.rb b/service/test/agama/users_test.rb index 4314ec25eb..38b93ae1c9 100644 --- a/service/test/agama/users_test.rb +++ b/service/test/agama/users_test.rb @@ -37,15 +37,15 @@ describe "#assign_root_password" do let(:root_user) { instance_double(Y2Users::User) } - context "when the password is encrypted" do - it "sets the password as encrypted" do - subject.assign_root_password("encrypted", true) + context "when the password is hashed" do + it "sets the password as hashed" do + subject.assign_root_password("hashed", true) root_user = users_config.users.root - expect(root_user.password).to eq(Y2Users::Password.create_encrypted("encrypted")) + expect(root_user.password).to eq(Y2Users::Password.create_encrypted("hashed")) end end - context "when the password is not encrypted" do + context "when the password is not hashed" do it "sets the password in clear text" do subject.assign_root_password("12345", false) root_user = users_config.users.root diff --git a/web/src/App.test.tsx b/web/src/App.test.tsx index c9140400ae..a7a58a5e8d 100644 --- a/web/src/App.test.tsx +++ b/web/src/App.test.tsx @@ -110,7 +110,7 @@ describe("App", () => { }); mockProducts = [tumbleweed, microos]; - mockRootUser = { password: true, encryptedPassword: false, sshkey: "FAKE-SSH-KEY" }; + mockRootUser = { password: true, hashedPassword: false, sshkey: "FAKE-SSH-KEY" }; }); afterEach(() => { @@ -165,7 +165,7 @@ describe("App", () => { describe("when there are no authentication method for root user", () => { beforeEach(() => { - mockRootUser = { password: false, encryptedPassword: false, sshkey: "" }; + mockRootUser = { password: false, hashedPassword: false, sshkey: "" }; }); it("redirects to root user edition", async () => { @@ -176,7 +176,7 @@ describe("App", () => { describe("when only root password is set", () => { beforeEach(() => { - mockRootUser = { password: true, encryptedPassword: false, sshkey: "" }; + mockRootUser = { password: true, hashedPassword: false, sshkey: "" }; }); it("renders the application content", async () => { installerRender(, { withL10n: true }); @@ -186,7 +186,7 @@ describe("App", () => { describe("when only root SSH public key is set", () => { beforeEach(() => { - mockRootUser = { password: false, encryptedPassword: false, sshkey: "FAKE-SSH-KEY" }; + mockRootUser = { password: false, hashedPassword: false, sshkey: "FAKE-SSH-KEY" }; }); it("renders the application content", async () => { installerRender(, { withL10n: true }); diff --git a/web/src/components/users/FirstUserForm.tsx b/web/src/components/users/FirstUserForm.tsx index 9a93832749..e4ce5cf243 100644 --- a/web/src/components/users/FirstUserForm.tsx +++ b/web/src/components/users/FirstUserForm.tsx @@ -135,9 +135,9 @@ export default function FirstUserForm() { if (!changePassword) { delete user.password; } else { - // the web UI only supports plain text passwords, this resets the flag if an encrypted + // the web UI only supports plain text passwords, this resets the flag if a hashed // password was previously set from CLI - user.encryptedPassword = false; + user.hashedPassword = false; } delete user.passwordConfirmation; user.autologin = !!user.autologin; diff --git a/web/src/components/users/RootAuthMethodsPage.test.tsx b/web/src/components/users/RootAuthMethodsPage.test.tsx index 2d9694989e..480c097668 100644 --- a/web/src/components/users/RootAuthMethodsPage.test.tsx +++ b/web/src/components/users/RootAuthMethodsPage.test.tsx @@ -53,7 +53,7 @@ describe("RootAuthMethodsPage", () => { await user.click(acceptButton); expect(mockRootUserMutation.mutateAsync).toHaveBeenCalledWith({ password: "t0ps3cr3t", - encryptedPassword: false, + hashedPassword: false, }); // After submitting the data, it must navigate diff --git a/web/src/components/users/RootAuthMethodsPage.tsx b/web/src/components/users/RootAuthMethodsPage.tsx index f4a826a896..3fce9489dd 100644 --- a/web/src/components/users/RootAuthMethodsPage.tsx +++ b/web/src/components/users/RootAuthMethodsPage.tsx @@ -52,7 +52,7 @@ function RootAuthMethodsPage() { e.preventDefault(); if (isEmpty(password)) return; - await setRootUser.mutateAsync({ password, encryptedPassword: false }); + await setRootUser.mutateAsync({ password, hashedPassword: false }); navigate(location.state?.from || PATHS.root, { replace: true }); }; diff --git a/web/src/components/users/RootPasswordPopup.jsx b/web/src/components/users/RootPasswordPopup.jsx index 2ec42eab5d..547b48a9a4 100644 --- a/web/src/components/users/RootPasswordPopup.jsx +++ b/web/src/components/users/RootPasswordPopup.jsx @@ -55,9 +55,9 @@ export default function RootPasswordPopup({ title = _("Root password"), isOpen, const accept = async (e) => { e.preventDefault(); // TODO: handle errors - // the web UI only supports plain text passwords, this resets the flag if an encrypted password + // the web UI only supports plain text passwords, this resets the flag if a hashed password // was previously set from CLI - if (password !== "") await setRootUser.mutateAsync({ password, encryptedPassword: false }); + if (password !== "") await setRootUser.mutateAsync({ password, hashedPassword: false }); close(); }; diff --git a/web/src/components/users/RootPasswordPopup.test.jsx b/web/src/components/users/RootPasswordPopup.test.jsx index 6e6800cd2f..db8725256e 100644 --- a/web/src/components/users/RootPasswordPopup.test.jsx +++ b/web/src/components/users/RootPasswordPopup.test.jsx @@ -77,7 +77,7 @@ describe("when it is open", () => { expect(mockRootUserMutation.mutateAsync).toHaveBeenCalledWith({ password, - encryptedPassword: false, + hashedPassword: false, }); expect(onCloseCallback).toHaveBeenCalled(); }); diff --git a/web/src/queries/users.ts b/web/src/queries/users.ts index cc01396995..9263cb8b3b 100644 --- a/web/src/queries/users.ts +++ b/web/src/queries/users.ts @@ -83,12 +83,12 @@ const useFirstUserChanges = () => { return client.onEvent((event) => { if (event.type === "FirstUserChanged") { - const { fullName, userName, password, encryptedPassword, autologin, data } = event; + const { fullName, userName, password, hashedPassword, autologin, data } = event; queryClient.setQueryData(["users", "firstUser"], { fullName, userName, password, - encryptedPassword, + hashedPassword, autologin, data, }); @@ -155,7 +155,7 @@ const useRootUserChanges = () => { const newRoot = { ...oldRoot }; if (password !== undefined) { newRoot.password = password; - newRoot.encryptedPassword = false; + newRoot.hashedPassword = false; } if (sshkey) { diff --git a/web/src/types/users.ts b/web/src/types/users.ts index 678fb3ffda..f6b09d22f4 100644 --- a/web/src/types/users.ts +++ b/web/src/types/users.ts @@ -24,19 +24,19 @@ type FirstUser = { fullName: string; userName: string; password: string; - encryptedPassword: boolean; + hashedPassword: boolean; autologin: boolean; }; type RootUser = { password: boolean; - encryptedPassword: boolean; + hashedPassword: boolean; sshkey: string; }; type RootUserChanges = { password: string; - encryptedPassword: boolean; + hashedPassword: boolean; sshkey: string; };