mysqladm-rs/authenticated-unix-socket/lib.rs

74 lines
2.4 KiB
Rust

// TODO:
// On responding to an incoming client request, the following should happen:
// 1. Before intializing it's request, the client should open an "authentication" socket with permissions 644.
// 2. Client opens a request to the server on the "normal" socket where the server is listening.
// 2. Server receives the request with auth socket address, a uid and a secret from the client.
// 3. Server validates that the owner of the auth socket address is the same as the uid.
// 4. Server connects to the auth socket address and receives the same secret.
// 5. Server validates that the secret is the same as the one it originally received.
// 6. Client closes the authentication socket. Normal socket is used for communication.
// (because the auth socket was readable globally)
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Message {
ClientHello {
uid: u32,
secret: u64,
auth_socket: String,
},
RequestSecret,
ResponseSecret(u64),
Authenticated,
SecretDidNotMatch,
Exit,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Error {
AuthenticationError,
InvalidRequest,
InvalidResponse,
}
// TODO: set timeout?
fn create_auth_socket() -> Result<UnixSocket, Error> {
let socket = UnixSocket::new()?;
socket.bind("/tmp/auth.sock")?;
socket.listen(1)?;
Ok(socket)
}
async fn client_authenticate(socket: &mut UnixSocket) -> Result<(), Error> {
let secret = rand::random::<u64>();
let uid = nix::unistd::getuid();
let auth_socket = create_auth_socket()?;
let client_hello = Message::ClientHello {
uid,
secret,
auth_socket: auth_socket.get_addr(),
};
socket.write(&client_hello)?;
// TODO: create threaded loop to handle multiple requests for secrets,
// until either the server respons in the main thread that something
// went wrong, something went right, or there is a timeout.
Ok(())
}
pub struct UID(u32);
async fn server_authenticate(socket: &mut UnixSocket) -> Result<UID, Error> {
let client_hello = socket.read::<Message>()?;
let (uid, secret, auth_socket) = match client_hello {
Message::ClientHello { uid, secret, auth_socket } => (uid, secret, auth_socket),
_ => return Err(Error::InvalidRequest),
};
/// TODO: open auth socket and request and validate secret
}