fixed newline when querying user input

This commit is contained in:
NoOneBtw 2021-11-17 14:19:05 +01:00
parent 6259840c43
commit 88d743227a
2 changed files with 34 additions and 110 deletions

View file

@ -16,6 +16,21 @@ struct Opts {
file: String, file: String,
} }
fn fix_newline_ref(line: &mut String) {
if line.ends_with('\n') {
line.pop();
if line.ends_with('\r') {
line.pop();
}
}
}
fn fix_newline(mut line: String) -> String {
fix_newline_ref(&mut line);
line
}
fn main() -> OsshResult<()> { fn main() -> OsshResult<()> {
let opts = Opts::parse(); let opts = Opts::parse();
println!("Generating ed25519 keypair:"); println!("Generating ed25519 keypair:");
@ -23,12 +38,24 @@ fn main() -> OsshResult<()> {
print!("Enter a passphrase: "); print!("Enter a passphrase: ");
std::io::stdout().flush()?; std::io::stdout().flush()?;
let passphrase = rpassword::read_password()?; let passphrase = rpassword::read_password()?;
print!("Re-enter the same passphrase: ");
std::io::stdout().flush()?;
let passphrase2 = rpassword::read_password()?;
if passphrase != passphrase2 {
println!("passphrases do not match.");
Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"passphrase did not match.",
))?;
}
print!("Enter an optional ID []: "); print!("Enter an optional ID []: ");
std::io::stdout().flush()?; std::io::stdout().flush()?;
let id = { let id = {
let mut id = String::new(); let mut id = String::new();
std::io::stdin().read_line(&mut id)?; std::io::stdin().read_line(&mut id)?;
fix_newline_ref(&mut id);
if id.is_empty() { if id.is_empty() {
None None
@ -45,10 +72,15 @@ fn main() -> OsshResult<()> {
let encrypt = { let encrypt = {
let mut line = String::new(); let mut line = String::new();
std::io::stdin().read_line(&mut line)?; std::io::stdin().read_line(&mut line)?;
fix_newline_ref(&mut line);
line.to_lowercase() == "y" line.to_lowercase() == "y"
}; };
if encrypt {
println!("Using passphrase to encrypt key..");
}
let fingerprint = let fingerprint =
keypair.fingerprint(osshkeys::keys::FingerprintHash::SHA256)?; keypair.fingerprint(osshkeys::keys::FingerprintHash::SHA256)?;
@ -63,7 +95,7 @@ fn main() -> OsshResult<()> {
println!("RandomArt:\n{}", randomart); println!("RandomArt:\n{}", randomart);
let private_key = keypair.serialize_openssh( let private_key = keypair.serialize_openssh(
Some(&passphrase), encrypt.then(|| passphrase.as_str()),
osshkeys::cipher::Cipher::Aes256_Ctr, osshkeys::cipher::Cipher::Aes256_Ctr,
)?; )?;
std::fs::write(&opts.file, private_key)?; std::fs::write(&opts.file, private_key)?;

View file

@ -1,113 +1,6 @@
use osshkeys::{error::OsshResult, keys::ed25519::Ed25519KeyPair, KeyPair}; use osshkeys::{error::OsshResult, keys::ed25519::Ed25519KeyPair, KeyPair};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
#[cfg(all(feature = "base64", feature = "bytes"))]
mod asdf {
use std::io::{Cursor, Read};
use bytes::Buf;
pub struct Ed25519PrivateKey {}
const OPENSSH_BEGIN: &str = "-----BEGIN OPENSSH PRIVATE KEY-----";
const OPENSSH_END: &str = "-----END OPENSSH PRIVATE KEY-----";
const OPENSSH_MAGIC: &str = "openssh-key-v1\0";
impl Ed25519PrivateKey {
pub fn parse<S>(text: S) -> Option<()>
where
S: AsRef<str>,
{
let mut lines = text.as_ref().lines();
let data = (lines.next() == Some(OPENSSH_BEGIN))
.then(|| {
let base64_content = lines
.take_while(|&line| line != OPENSSH_END)
.fold(String::new(), |mut acc, line| {
acc.push_str(line);
acc
});
base64::decode(&base64_content).ok()
})
.flatten()
.map(|data| Cursor::new(data))
.and_then(|mut data| {
let mut magic = vec![0u8; OPENSSH_MAGIC.len()];
data.read_exact(&mut magic).unwrap();
// cypher name
let cypher_len = data.get_u32();
let mut cypher_name = vec![0u8; cypher_len as usize];
data.read_exact(&mut cypher_name).unwrap();
// kdf name
let kdf_name_len = data.get_u32();
let mut kdf_name = vec![0u8; kdf_name_len as usize];
data.read_exact(&mut kdf_name).unwrap();
// kdf
let kdf_len = data.get_u32();
let kdf = (kdf_len > 0).then(|| {
let mut kdf = vec![0u8; kdf_len as usize];
data.read_exact(&mut kdf).unwrap();
kdf
});
// key_count should always be `1`
let key_count = data.get_u32();
assert_eq!(key_count, 1);
// ssh public key
let pubkey_len = data.get_u32() as usize;
let keytype_len = data.get_u32() as usize;
let mut keytype = vec![0u8; keytype_len];
data.read_exact(&mut keytype).unwrap();
let pub1_len = data.get_u32() as usize;
let mut pub1 = vec![0u8; pub1_len];
data.read_exact(&mut pub1).unwrap();
let pub2_len = data.get_u32() as usize;
let mut pub2 = vec![0u8; pub2_len];
data.read_exact(&mut pub2).unwrap();
println!("magic: {}", String::from_utf8_lossy(&magic));
println!(
"cypher: {}",
String::from_utf8_lossy(&cypher_name)
);
println!("kdf: {}", String::from_utf8_lossy(&kdf_name));
println!("keytype: {}", String::from_utf8_lossy(&keytype));
println!("pub1[{}]: {:?}", pub1_len, &pub1);
println!("pub2[{}]: {:?}", pub2_len, &pub2);
Some(())
});
Some(())
}
}
mod tests {
use super::Ed25519PrivateKey;
#[test]
fn test_ed25519() {
Ed25519PrivateKey::parse(include_str!("../ed25519"));
}
#[test]
fn test_ed25519_passphrased() {
Ed25519PrivateKey::parse(include_str!("../ed25519-passphrased"));
}
}
}
pub fn generate_ed25519_keypair<S1, S2>( pub fn generate_ed25519_keypair<S1, S2>(
passphrase: S1, passphrase: S1,
id: Option<S2>, id: Option<S2>,
@ -132,8 +25,6 @@ where
pub mod randomart { pub mod randomart {
use std::fmt::Write; use std::fmt::Write;
use osshkeys::error::OsshResult;
const WIDTH: usize = 17; const WIDTH: usize = 17;
const HEIGHT: usize = 9; const HEIGHT: usize = 9;
const TILES: &[char] = &[ const TILES: &[char] = &[
@ -229,6 +120,7 @@ pub mod randomart {
} }
} }
#[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;