uniauth 2.1.1

Easy-to-use abstraction over authentication
Documentation
//! Easy to use abstraction over authentication
//! Both servers and clients must use `make_challenge`.
//! Clients must communicate with the authentication daemon using `daemon::Daemon`.
//! Servers use `AnyPubkey::verify` on signature sent by a connecting client

#[cfg(feature = "any")]
pub mod any;
#[cfg(feature = "client")]
pub mod daemon;
#[cfg(feature = "error")]
pub mod error;
pub mod requests;
pub mod status;
pub mod util;

use std::io::Write;
#[cfg(feature = "daemon")]
use std::{
	env,
	path::PathBuf
};

#[cfg(feature = "daemon")]
/// Get the default path to the daemon's unix socket
pub fn daemon_path() -> PathBuf {
	let runtime_dir = env::var("XDG_RUNTIME_DIR")
		.expect("Missing XDG_RUNTIME_DIR environment variable");
	let mut path = PathBuf::from(runtime_dir);
	path.push("uniauth2.sock");
	path
}

/// Create challenge text that the authenticator will sign.
/// It should not be parsed as any field can contain / and "break" the format
pub fn make_challenge(service: &str, name: &str, action: &str, nonce: &[u8]) -> Vec<u8> {
	// 7 = UNIAUTH
	// 4 = '/' * 4
	let len = 11 + service.len() + name.len() + action.len() + nonce.len();
	util::make_packet(len, |p| {
		p.write_all(b"UNIAUTH")?;
		p.push(b'/');
		p.write_all(service.as_bytes())?;
		p.push(b'/');
		p.write_all(name.as_bytes())?;
		p.push(b'/');
		p.write_all(action.as_bytes())?;
		p.push(b'/');
		p.write_all(nonce)
	}).unwrap()
}