11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4+ //! This module provides functionality for provisioning SSH keys for a user.
5+ //!
6+ //! It includes functions to create the necessary `.ssh` directory, set the appropriate
7+ //! permissions, and write the provided public keys to the `authorized_keys` file.
8+
49use std:: {
510 fs:: { self , OpenOptions , Permissions } ,
611 io:: { self , Read , Write } ,
@@ -17,6 +22,7 @@ use tempfile::NamedTempFile;
1722use tracing:: { error, info, instrument} ;
1823
1924lazy_static ! {
25+ /// A regular expression to match the `PasswordAuthentication` setting in the SSH configuration.
2026 static ref PASSWORD_REGEX : Regex = Regex :: new(
2127 r"(?m)^\s*#?\s*PasswordAuthentication\s+(yes|no)\s*$"
2228 )
@@ -25,6 +31,25 @@ lazy_static! {
2531 ) ;
2632}
2733
34+ /// Provisions SSH keys for the specified user.
35+ ///
36+ /// Creates the `.ssh` directory in the user's home directory, sets the appropriate
37+ /// permissions, and writes the provided public keys to the `authorized_keys` file.
38+ ///
39+ /// # Arguments
40+ ///
41+ /// * `user` - A reference to the user for whom the SSH keys are being provisioned.
42+ /// * `keys` - A slice of `PublicKeys` to be added to the `authorized_keys` file.
43+ /// * `authorized_keys_path_string` - An optional string specifying the path to the `authorized_keys` file.
44+ ///
45+ /// # Returns
46+ ///
47+ /// This function returns `Result<(), Error>` indicating success or failure.
48+ ///
49+ /// # Errors
50+ ///
51+ /// This function will return an error if it fails to create the `.ssh` directory, set permissions,
52+ /// or write to the `authorized_keys` file.
2853#[ instrument( skip_all, name = "ssh" ) ]
2954pub ( crate ) fn provision_ssh (
3055 user : & nix:: unistd:: User ,
@@ -61,6 +86,19 @@ pub(crate) fn provision_ssh(
6186 Ok ( ( ) )
6287}
6388
89+ /// Retrieves the path to the `authorized_keys` file from the SSH daemon configuration.
90+ ///
91+ /// Runs the SSH daemon to get the configuration and extracts
92+ /// the `AuthorizedKeysFile` setting.
93+ ///
94+ /// # Arguments
95+ ///
96+ /// * `sshd_config_command_runner` - A function that runs the SSH daemon command and returns its output.
97+ ///
98+ /// # Returns
99+ ///
100+ /// This function returns a path to the `authorized_keys` file if found,
101+ /// or `None` if the setting is not found.
64102fn get_authorized_keys_path_from_sshd (
65103 sshd_config_command_runner : impl Fn ( ) -> io:: Result < Output > ,
66104) -> Option < String > {
@@ -73,6 +111,15 @@ fn get_authorized_keys_path_from_sshd(
73111 path
74112}
75113
114+ /// Runs the SSH daemon command to get its configuration.
115+ ///
116+ /// # Arguments
117+ ///
118+ /// * `sshd_config_command_runner` - A function that runs the SSH daemon command and returns its output.
119+ ///
120+ /// # Returns
121+ ///
122+ /// This function returns an output of the command.
76123fn run_sshd_command (
77124 sshd_config_command_runner : impl Fn ( ) -> io:: Result < Output > ,
78125) -> Option < Output > {
@@ -105,6 +152,19 @@ fn run_sshd_command(
105152 }
106153}
107154
155+ /// Extracts the `AuthorizedKeysFile` path from the SSH daemon configuration output.
156+ ///
157+ /// Parses the output of the SSH daemon configuration command and extracts the
158+ /// `AuthorizedKeysFile` setting.
159+ ///
160+ /// # Arguments
161+ ///
162+ /// * `sshd_config_output` - A byte slice containing the output of the SSH daemon configuration command.
163+ ///
164+ /// # Returns
165+ ///
166+ /// This function returns an `Option<String>` containing the path to the `authorized_keys` file if found,
167+ /// or `None` if the setting is not found.
108168fn extract_authorized_keys_file_path ( stdout : & [ u8 ] ) -> Option < String > {
109169 let output = String :: from_utf8_lossy ( stdout) ;
110170 for line in output. lines ( ) {
@@ -124,6 +184,22 @@ fn extract_authorized_keys_file_path(stdout: &[u8]) -> Option<String> {
124184 None
125185}
126186
187+ /// Updates the SSH daemon configuration to ensure `PasswordAuthentication` is set to `yes`.
188+ ///
189+ /// Checks if the `sshd_config` file exists and updates the `PasswordAuthentication`
190+ /// setting to `yes`. If the file does not exist, it creates a new one with the appropriate setting.
191+ ///
192+ /// # Arguments
193+ ///
194+ /// * `sshd_config_path` - A string slice containing the path to the `sshd_config` file.
195+ ///
196+ /// # Returns
197+ ///
198+ /// This function returns `Result<(), io::Error>` indicating success or failure.
199+ ///
200+ /// # Errors
201+ ///
202+ /// This function will return an error if it fails to read, write, or create the `sshd_config` file.
127203pub ( crate ) fn update_sshd_config (
128204 sshd_config_path : & str ,
129205) -> Result < ( ) , io:: Error > {
0 commit comments