mod args; mod handler; mod tls; use std::net::TcpListener; use std::sync::Arc; use std::thread; fn main() { let args = args::parse_args(); if args.init { match zagan_bet::server::setup::init_identity(std::path::Path::new("."), "localhost") { Ok(report) => { println!("TLS identity created:"); println!(" {} (PKCS#12, empty password)", report.identity.display()); println!(" {} (private key)", report.key.display()); println!(" {} (certificate)", report.cert.display()); println!("\nStart the server with:\n cargo run --bin server"); println!("Clients will trust this certificate on first contact."); } Err(error) => { eprintln!("TLS setup failed:\n{error}"); std::process::exit(1); } } return; } let listener = match TcpListener::bind(format!("{}:{}", args.ip, args.port)) { Ok(l) => l, Err(e) => { eprintln!("Failed to bind to {}:{}: {}", args.ip, args.port, e); std::process::exit(1); } }; let tls = match tls::TlsServer::new("identity.p12") { Ok(t) => Arc::new(t), Err(e) => { eprintln!("Failed to initialize TLS: {}", e); std::process::exit(1); } }; println!( "Server listening on {} (TLS enabled){}", listener.local_addr().unwrap(), if args.unsafe_mode { " [UNSAFE MODE]" } else { "" } ); for stream in listener.incoming() { let stream = stream.unwrap(); let tls = tls.clone(); thread::spawn(move || match tls.accept(stream) { Ok(tls_stream) => { handler::handle_client_tls(tls_stream); } Err(e) => { eprintln!("TLS handshake failed: {}", e); } }); } }