@@ -5,6 +5,7 @@ use rustix::process::geteuid;
5
5
use rustix:: process:: getuid;
6
6
use rustix:: thread:: set_thread_res_uid;
7
7
use serde_json:: Value ;
8
+ use std:: collections:: BTreeMap ;
8
9
use std:: collections:: BTreeSet ;
9
10
use std:: fmt:: Display ;
10
11
use std:: fmt:: Formatter ;
@@ -102,11 +103,45 @@ impl Display for UserKeys {
102
103
}
103
104
}
104
105
106
+ #[ derive( Debug ) ]
107
+ struct SshdConfig < ' a > {
108
+ authorized_keys_files : Vec < & ' a str > ,
109
+ authorized_keys_command : & ' a str ,
110
+ authorized_keys_command_user : & ' a str ,
111
+ }
112
+
113
+ impl < ' a > SshdConfig < ' a > {
114
+ pub fn parse ( sshd_output : & ' a str ) -> Result < SshdConfig < ' a > > {
115
+ let config = sshd_output
116
+ . lines ( )
117
+ . filter_map ( |line| line. split_once ( ' ' ) )
118
+ . collect :: < BTreeMap < & str , & str > > ( ) ;
119
+
120
+ let authorized_keys_files: Vec < & str > = config
121
+ . get ( "authorizedkeysfile" )
122
+ . unwrap_or ( & "none" )
123
+ . split_whitespace ( )
124
+ . collect ( ) ;
125
+ let authorized_keys_command = config. get ( "authorizedkeyscommand" ) . unwrap_or ( & "none" ) ;
126
+ let authorized_keys_command_user =
127
+ config. get ( "authorizedkeyscommanduser" ) . unwrap_or ( & "none" ) ;
128
+
129
+ Ok ( Self {
130
+ authorized_keys_files,
131
+ authorized_keys_command,
132
+ authorized_keys_command_user,
133
+ } )
134
+ }
135
+ }
136
+
105
137
pub ( crate ) fn get_all_users_keys ( ) -> Result < Vec < UserKeys > > {
106
138
let loginctl_user_names = loginctl_users ( ) . context ( "enumerate users" ) ?;
107
139
108
140
let mut all_users_authorized_keys = Vec :: new ( ) ;
109
141
142
+ let sshd_config = SshdConfig :: parse ( ) ?;
143
+ tracing:: debug!( "parsed sshd config: {:?}" , sshd_config) ;
144
+
110
145
for user_name in loginctl_user_names {
111
146
let user_info = uzers:: get_user_by_name ( user_name. as_str ( ) )
112
147
. context ( format ! ( "user {} not found" , user_name) ) ?;
0 commit comments