+ }
+
+ async fn auth_pk(
+ &self,
+ h: &mut thrussh::client::Handle<SshClient>,
+ key_path: &mut PathBuf,
+ ) -> bool {
+ if h.is_closed() {
+ return false;
+ }
+ let mut authenticated = false;
+ let mut keys = Vec::new();
+ if let Some(ref file) = self.config.identity_file {
+ keys.push(file.as_str())
+ } else {
+ keys.push("id_ed25519");
+ keys.push("id_rsa");
+ }
+ for k in keys.iter() {
+ key_path.push(k);
+ let k = match thrussh_keys::load_secret_key(&key_path, None) {
+ Ok(k) => k,
+ Err(thrussh_keys::Error::KeyIsEncrypted) => {
+ let password = dialoguer::Password::with_theme(
+ crate::config::load_theme()
+ .expect("Could not load config")
+ .as_ref(),
+ )
+ .with_prompt(format!("Password for encrypted private key"))
+ .allow_empty_password(false)
+ .interact()
+ .unwrap();
+ if let Ok(k) = thrussh_keys::load_secret_key(&key_path, Some(&password)) {
+ k
+ } else {
+ continue
+ }
+ }
+ Err(_) => {
+ key_path.pop();
+ continue;
+ }
+ };
+ if let Ok(auth) = h
+ .authenticate_publickey(&self.config.user, Arc::new(k))
+ .await
+ {
+ authenticated = auth
+ }
+ key_path.pop();
+ if authenticated {
+ return true;
+ }
+ }
+ false