Skip to content

Commit

Permalink
Initial support for encrypted password
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Nov 12, 2024
1 parent 976f695 commit 88ef1c3
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 10 deletions.
6 changes: 5 additions & 1 deletion rust/agama-lib/src/users/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +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 auto-login should enabled or not
pub autologin: bool,
}
Expand All @@ -46,7 +48,8 @@ impl FirstUser {
full_name: data.0,
user_name: data.1,
password: data.2,
autologin: data.3,
encrypted_password: data.3,
autologin: data.4,
})
}
}
Expand Down Expand Up @@ -107,6 +110,7 @@ impl<'a> UsersClient<'a> {
&first_user.full_name,
&first_user.user_name,
&first_user.password,
first_user.encrypted_password,
first_user.autologin,
std::collections::HashMap::new(),
)
Expand Down
3 changes: 3 additions & 0 deletions rust/agama-lib/src/users/proxies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ use zbus::proxy;
/// * full name
/// * user name
/// * password
/// * encrypted_password (true = encrypted, false = plain text)
/// * auto-login (enabled or not)
/// * some optional and additional data
// NOTE: Manually added to this file.
Expand All @@ -55,6 +56,7 @@ pub type FirstUser = (
String,
String,
bool,
bool,
std::collections::HashMap<String, zbus::zvariant::OwnedValue>,
);

Expand All @@ -77,6 +79,7 @@ pub trait Users1 {
full_name: &str,
user_name: &str,
password: &str,
encrypted_password: bool,
auto_login: bool,
data: std::collections::HashMap<&str, &zbus::zvariant::Value<'_>>,
) -> zbus::Result<(bool, Vec<String>)>;
Expand Down
4 changes: 4 additions & 0 deletions rust/agama-lib/src/users/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ pub struct FirstUserSettings {
pub user_name: Option<String>,
/// First user's password (in clear text)
pub password: Option<String>,
/// Whether the password is encrypted or is plain text
pub encrypted_password: Option<bool>,
/// Whether auto-login should enabled or not
pub autologin: Option<bool>,
}
Expand All @@ -56,6 +58,8 @@ pub struct RootUserSettings {
/// Root's password (in clear text)
#[serde(skip_serializing)]
pub password: Option<String>,
/// Whether the password is encrypted or is plain text
pub encrypted_password: Option<bool>,
/// Root SSH public key
pub ssh_public_key: Option<String>,
}
6 changes: 5 additions & 1 deletion rust/agama-lib/src/users/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +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),
};
let mut root_user = RootUserSettings::default();
let ssh_public_key = self.users_client.root_ssh_key().await?;
Expand Down Expand Up @@ -77,16 +78,19 @@ 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.clone().unwrap_or_default(),
..Default::default()
};
self.users_client.set_first_user(&first_user).await?;
Ok(())
}

async fn store_root_user(&self, settings: &RootUserSettings) -> Result<(), ServiceError> {
let encrypted_password = settings.encrypted_password.clone().unwrap_or_default();

if let Some(root_password) = &settings.password {
self.users_client
.set_root_password(root_password, false)
.set_root_password(root_password, encrypted_password)
.await?;
}

Expand Down
3 changes: 2 additions & 1 deletion rust/agama-server/src/users/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ async fn first_user_changed_stream(
full_name: user.0,
user_name: user.1,
password: user.2,
autologin: user.3,
encrypted_password: user.3,
autologin: user.4,
};
return Some(Event::FirstUserChanged(user_struct));
}
Expand Down
11 changes: 6 additions & 5 deletions service/lib/agama/dbus/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ def issues
USERS_INTERFACE = "org.opensuse.Agama.Users1"
private_constant :USERS_INTERFACE

FUSER_SIG = "in FullName:s, in UserName:s, in Password:s, in AutoLogin:b, in data:a{sv}"
FUSER_SIG = "in FullName:s, in UserName:s, in Password:s, in EncryptedPassword:b, in AutoLogin:b, in data:a{sv}"
private_constant :FUSER_SIG

dbus_interface USERS_INTERFACE do
dbus_reader :root_password_set, "b"

dbus_reader :root_ssh_key, "s", dbus_name: "RootSSHKey"

dbus_reader :first_user, "(sssba{sv})"
dbus_reader :first_user, "(sssbba{sv})"

dbus_method :SetRootPassword,
"in Value:s, in Encrypted:b, out result:u" do |value, encrypted|
Expand Down Expand Up @@ -97,9 +97,9 @@ def issues
dbus_method :SetFirstUser,
# 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, auto_login, data|
FUSER_SIG + ", out result:(bas)" do |full_name, user_name, password, encrypted_password, auto_login, data|
logger.info "Setting first user #{full_name}"
user_issues = backend.assign_first_user(full_name, user_name, password, auto_login, data)
user_issues = backend.assign_first_user(full_name, user_name, password, encrypted_password, auto_login, data)

if user_issues.empty?
dbus_properties_changed(USERS_INTERFACE, { "FirstUser" => first_user }, [])
Expand Down Expand Up @@ -133,12 +133,13 @@ def root_ssh_key
def first_user
user = backend.first_user

return ["", "", "", false, {}] unless user
return ["", "", "", false, false, {}] unless user

[
user.full_name,
user.name,
user.password_content || "",
user.password&.value&.encrypted? || false,
backend.autologin?(user),
{}
]
Expand Down
10 changes: 8 additions & 2 deletions service/lib/agama/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,21 @@ 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 auto_login [Boolean]
# @param _data [Hash]
# @return [Array] the list of fatal issues found
def assign_first_user(full_name, user_name, password, auto_login, _data)
def assign_first_user(full_name, user_name, password, encrypted_password, auto_login, _data)
remove_first_user

user = Y2Users::User.new(user_name)
user.gecos = [full_name]
user.password = Y2Users::Password.create_plain(password)
user.password = if encrypted_password
Y2Users::Password.create_encrypted(password)
else
Y2Users::Password.create_plain(password)
end

fatal_issues = user.issues.map.select(&:error?)
return fatal_issues.map(&:message) unless fatal_issues.empty?

Expand Down
4 changes: 4 additions & 0 deletions web/src/components/users/FirstUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ 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 password was previously set from CLI
user.encryptedPassword = false;
}
delete user.passwordConfirmation;
user.autologin = !!user.autologin;
Expand Down
1 change: 1 addition & 0 deletions web/src/types/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type FirstUser = {
fullName: string;
userName: string;
password: string;
encryptedPassword: boolean;
autologin: boolean;
};

Expand Down

0 comments on commit 88ef1c3

Please sign in to comment.