use std::{env, error::Error, os::unix::net::UnixStream}; use greetd_ipc::{codec::SyncCodec, AuthMessageType, ErrorType, Request, Response}; use crate::{Session, User}; pub enum LoginResult { Success, Failure, } pub fn login( user: &User, session: &Session, password: &str, ) -> Result> { let mut stream = UnixStream::connect(env::var("GREETD_SOCK")?)?; Request::CreateSession { username: user.name.clone(), } .write_to(&mut stream)?; let mut starting = false; loop { match Response::read_from(&mut stream)? { Response::Success => { if starting { return Ok(LoginResult::Success); } else { starting = true; let cmd = vec![user.shell.to_str().unwrap().to_owned()]; let env = vec![]; Request::StartSession { cmd, env }.write_to(&mut stream)?; } } Response::Error { error_type, description, } => { Request::CancelSession.write_to(&mut stream)?; match error_type { ErrorType::Error => { return Err(format!("login error: {:?}", description).into()) } ErrorType::AuthError => return Ok(LoginResult::Failure), } } Response::AuthMessage { auth_message_type, auth_message, } => { let response = match auth_message_type { AuthMessageType::Visible => todo!(), AuthMessageType::Secret => Some(password.to_string()), AuthMessageType::Info => todo!(), AuthMessageType::Error => todo!(), }; Request::PostAuthMessageResponse { response }.write_to(&mut stream)?; } } } }