use ascii::AsciiString;
use awol2005ex_kerbeiros::{TgtRequester, Credential};
use awol2005ex_kerberos_crypto::Key;
use std::net::{IpAddr, ToSocketAddrs};
use std::error::Error;
use crate::utils;
pub fn kinit_with_password(principal: &str, password: &str, kdc_ip: &str) -> Result<Credential, Box<dyn Error>> {
println!("Performing kinit with password authentication...");
println!("Principal: {}", principal);
println!("KDC IP: {}", kdc_ip);
let (username, realm) = utils::parse_principal(principal)?;
let kdc_address: IpAddr = match kdc_ip.parse() {
Ok(ip) => ip,
Err(_) => {
let kdc_socket = format!("{}:88", kdc_ip);
match kdc_socket.to_socket_addrs() {
Ok(mut addrs) => {
match addrs.next() {
Some(addr) => addr.ip(),
None => return Err(format!("Could not resolve KDC hostname: {}", kdc_ip).into()),
}
}
Err(e) => return Err(format!("Could not resolve KDC hostname '{}': {}", kdc_ip, e).into()),
}
}
};
let realm_ascii = AsciiString::from_ascii(realm)
.map_err(|e| format!("Invalid realm: {}", e))?;
let username_ascii = AsciiString::from_ascii(username)
.map_err(|e| format!("Invalid username: {}", e))?;
let user_key = Key::Secret(password.to_owned());
let tgt_requester = TgtRequester::new(realm_ascii, kdc_address);
let credential = tgt_requester.request(&username_ascii, Some(&user_key))
.map_err(|e| format!("TGT request failed: {}", e))?;
println!("Successfully obtained TGT for {}", principal);
Ok(credential)
}
pub fn kinit_with_keytab(keytab_path: &str, principal: &str, kdc_ip: &str) -> Result<Credential, Box<dyn Error>> {
println!("Performing kinit with keytab...");
println!("Keytab: {}", keytab_path);
println!("Principal: {}", principal);
println!("KDC IP: {}", kdc_ip);
let (_, realm) = utils::parse_principal(principal)?;
let user_key = crate::keytab::load_key_from_keytab(keytab_path, principal)?;
let kdc_address: IpAddr = match kdc_ip.parse() {
Ok(ip) => ip,
Err(_) => {
let kdc_socket = format!("{}:88", kdc_ip);
match kdc_socket.to_socket_addrs() {
Ok(mut addrs) => {
match addrs.next() {
Some(addr) => addr.ip(),
None => return Err(format!("Could not resolve KDC hostname: {}", kdc_ip).into()),
}
}
Err(e) => return Err(format!("Could not resolve KDC hostname '{}': {}", kdc_ip, e).into()),
}
}
};
let realm_ascii = AsciiString::from_ascii(realm)
.map_err(|e| format!("Invalid realm: {}", e))?;
let username_ascii = AsciiString::from_ascii(utils::get_username(principal)?)
.map_err(|e| format!("Invalid username: {}", e))?;
let tgt_requester = TgtRequester::new(realm_ascii, kdc_address);
let credential = tgt_requester.request(&username_ascii, Some(&user_key))
.map_err(|e| format!("TGT request failed: {}", e))?;
println!("Successfully obtained TGT for {}", principal);
Ok(credential)
}