First pass, creates socket, should listen and respond
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
Generated
+140
@@ -0,0 +1,140 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-chain"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hostname"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"match_cfg",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.119"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "match_cfg"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "saslauthd"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"syslog",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syslog"
|
||||||
|
version = "6.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "978044cc68150ad5e40083c9f6a725e6fd02d7ba1bcf691ec2ff0d66c0b41acc"
|
||||||
|
dependencies = [
|
||||||
|
"error-chain",
|
||||||
|
"hostname",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "saslauthd"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syslog = "^6.0"
|
||||||
|
yaml-rust = "0.4"
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
use std::fs::{metadata, set_permissions};
|
||||||
|
use std::io::{Error, ErrorKind, Read, Write};
|
||||||
|
use std::net::Shutdown;
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
use std::os::unix::net::{UnixListener, UnixStream};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
extern crate yaml_rust;
|
||||||
|
|
||||||
|
use yaml_rust::{YamlEmitter, YamlLoader};
|
||||||
|
|
||||||
|
const RESPONSE_NO: [u8; 4] = [0x0, 0x2, b'N', b'O'];
|
||||||
|
const RESPONSE_OK: [u8; 4] = [0x0, 0x2, b'O', b'K'];
|
||||||
|
|
||||||
|
struct SaslSock {
|
||||||
|
name: PathBuf,
|
||||||
|
listener: UnixListener,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SaslSock {
|
||||||
|
pub fn new(name: &str) -> Result<SaslSock, Error> {
|
||||||
|
let path = PathBuf::from(&name);
|
||||||
|
if path.exists() {
|
||||||
|
std::fs::remove_file(&path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let listener = UnixListener::bind(&name)?;
|
||||||
|
|
||||||
|
let mut perms = metadata(&path)?.permissions();
|
||||||
|
perms.set_mode(0o0777);
|
||||||
|
set_permissions(&path, perms)?;
|
||||||
|
|
||||||
|
Ok(SaslSock {
|
||||||
|
name: PathBuf::from(&name),
|
||||||
|
listener,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for SaslSock {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _result = std::fs::remove_file(&self.name);
|
||||||
|
println!("Shutting down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The saslauthd protocol transmits strings as
|
||||||
|
/// 16-bit unsigned network-byte-order lengths followed
|
||||||
|
/// by the string itself.
|
||||||
|
///
|
||||||
|
fn read_string(stream: &mut UnixStream) -> Result<String, Error> {
|
||||||
|
let mut length_buffer = [0u8, 0u8];
|
||||||
|
|
||||||
|
stream.read_exact(&mut length_buffer)?;
|
||||||
|
let length = u16::from_be_bytes(length_buffer);
|
||||||
|
|
||||||
|
let mut string_buffer = vec![0u8; length as usize];
|
||||||
|
|
||||||
|
stream.read_exact(&mut string_buffer)?;
|
||||||
|
|
||||||
|
match String::from_utf8(string_buffer) {
|
||||||
|
Ok(str) => Ok(str),
|
||||||
|
Err(_err) => Err(Error::new(ErrorKind::Other, "Invalid UTF-8 sent")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string(s: &str, stream: &mut UnixStream) -> Result<(), Error> {
|
||||||
|
let length = s.len();
|
||||||
|
|
||||||
|
if length > 0xffff {
|
||||||
|
return Err(Error::new(ErrorKind::Other, "String too long to write"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let length_buffer = [(length >> 8) as u8, (length & 0xff) as u8];
|
||||||
|
|
||||||
|
stream.write_all(&length_buffer)?;
|
||||||
|
stream.write_all(s.as_bytes())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_auth(mut stream: UnixStream) -> Result<(), Error> {
|
||||||
|
let userid = read_string(&mut stream)?;
|
||||||
|
let password = read_string(&mut stream)?;
|
||||||
|
let service = read_string(&mut stream)?;
|
||||||
|
let _realm = read_string(&mut stream)?;
|
||||||
|
|
||||||
|
stream.write_all(&RESPONSE_NO)?;
|
||||||
|
stream.shutdown(Shutdown::Both)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_client(stream: UnixStream) {
|
||||||
|
if let Err(error) = check_auth(stream) {
|
||||||
|
eprint!("{}", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let sock = SaslSock::new("/tmp/saslauthd.sock")?;
|
||||||
|
|
||||||
|
// accept connections and process them, spawning a new thread for each one
|
||||||
|
for stream in sock.listener.incoming() {
|
||||||
|
match stream {
|
||||||
|
Ok(stream) => {
|
||||||
|
/* connection succeeded */
|
||||||
|
thread::spawn(|| handle_client(stream));
|
||||||
|
}
|
||||||
|
Err(_err) => {
|
||||||
|
/* connection failed */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user