summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorYves Fischer <yvesf-git@xapek.org>2016-12-17 15:50:27 +0100
committerYves Fischer <yvesf-git@xapek.org>2016-12-17 16:00:19 +0100
commit8ceac0236c555979a9172c69c1a9e895d7487d6f (patch)
tree390740422d514ac62bc572d61c64e7375f2d7a27 /src/main.rs
parentf355162fde31a4c79b7e665b43cef2de3ba05cb5 (diff)
downloadauth-xmppmessage-8ceac0236c555979a9172c69c1a9e895d7487d6f.tar.gz
auth-xmppmessage-8ceac0236c555979a9172c69c1a9e895d7487d6f.zip
replace all with subdirectory rust/
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..30d4f8b
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,98 @@
+use std::env;
+use std::iter::repeat;
+use std::sync::Arc;
+use std::thread;
+
+extern crate ascii;
+extern crate crypto;
+extern crate getopts;
+#[macro_use] extern crate log;
+extern crate tiny_http;
+extern crate time;
+extern crate rand;
+extern crate rustc_serialize;
+extern crate simple_logger;
+
+use crypto::digest::Digest;
+use crypto::sha1::Sha1;
+use getopts::Options;
+use rand::{thread_rng, Rng};
+use log::LogLevel;
+
+mod apachelog;
+mod handler;
+mod message;
+mod sendxmpp;
+mod token;
+
+fn print_usage(program: &str, opts: Options) {
+ let brief = format!("Usage: {} [options]", program);
+ print!("{}", opts.usage(&brief));
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ let program = args[0].clone();
+ let mut opts = Options::new();
+ opts.optopt("j", "jid", "bot jid", "JID");
+ opts.optopt("p", "password", "bot password", "PASSWORD");
+ opts.optopt("s", "secret", "server secret for token generation", "SECRET");
+ opts.optopt("t", "time", "Validity of the token in hours (default 48)", "HOURS");
+ opts.optopt("o", "port", "TCP Port to listen on", "PORT");
+ opts.optflag("d", "debug", "Use loglevel Debug instead of Warn");
+ opts.optflag("n", "nosend", "Don't send XMPP message, just print debug infos");
+ opts.optflag("h", "help", "print this help menu");
+ let matches = opts.parse(&args[1..]).unwrap_or_else(|f| panic!(f.to_string()));
+
+ if matches.opt_present("h") {
+ print_usage(&program, opts);
+ return;
+ }
+
+ if !(matches.opt_present("j") && matches.opt_present("p")) && !matches.opt_present("n") {
+ print_usage(&program, opts);
+ panic!("Missing jid or password");
+ }
+
+ simple_logger::init_with_level(if matches.opt_present("d") { LogLevel::Debug } else { LogLevel::Warn }).unwrap();
+
+ let mut hasher = Sha1::new();
+ let mut secret: Vec<u8> = repeat(0).take((hasher.output_bits() + 7) / 8).collect();
+ matches.opt_str("s").and_then(|s| {
+ hasher.input_str(s.as_str());
+ hasher.result(&mut secret);
+ Some(())
+ }).unwrap_or_else(|| {
+ println!("No secret (-s/--secret) given, using random value");
+ thread_rng().fill_bytes(&mut secret);
+ });
+ let secret = secret.into_iter().take(16).collect::<Vec<u8>>();
+ let validity: i64 = matches.opt_str("t").unwrap_or(String::from("48")).parse()
+ .unwrap_or_else(|_| { panic!("Failed to parse time") });
+ let port = matches.opt_str("o").unwrap_or(String::from("8080")).parse()
+ .unwrap_or_else(|_| { panic!("Failed to parse port number") });
+
+ let handler = handler::AuthHandler::make(matches.opt_str("j").unwrap_or(String::from("<jid>")),
+ matches.opt_str("p").unwrap_or(String::from("<password>")),
+ time::Duration::hours(validity),
+ secret,
+ matches.opt_present("n"));
+ let handler = Arc::new(handler);
+ let server = Arc::new(tiny_http::Server::http(("0.0.0.0", port)).unwrap());
+
+ let mut threads = Vec::new();
+
+ for _ in 0..2 {
+ let server = server.clone();
+ let handler = handler.clone();
+ threads.push(thread::spawn(move || {
+ for request in server.incoming_requests() {
+ let response = handler.call(&request);
+ let _ = request.respond(response);
+ }
+ }));
+ }
+ for h in threads {
+ h.join().unwrap();
+ }
+} \ No newline at end of file