diff --git a/src/config.rs b/src/config.rs index 3610071..b400703 100644 --- a/src/config.rs +++ b/src/config.rs @@ -28,6 +28,7 @@ pub struct Context { pub flags: Flags, pub sas: HashMap, pub hashwd: HashMap, + pub reloadinterval: isize, } #[derive(Debug, Clone)] @@ -35,7 +36,7 @@ pub struct SetMap { pub filename: String, pub fullpath: String, pub regex: Regex, - pub set: Set, + pub set: SetCfg, pub watchedfiles: HashMap, pub wd: WatchDescriptor, } @@ -64,6 +65,7 @@ impl Context { sas: HashMap::new(), blocklist: HashMap::new(), hashwd: HashMap::new(), + reloadinterval: 5, }; print!("Loading config ... "); @@ -282,7 +284,7 @@ impl Context { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Config { - pub sets: HashMap, + pub sets: HashMap, #[serde(skip_serializing)] pub trustnets: Vec, pub ws: HashMap, @@ -294,7 +296,7 @@ impl Config { Self { sets: HashMap::from([ ("smtp".to_string(), - Set { + SetCfg { src: "smtp".to_string(), filename: "mail.log".to_string(), regex: "(SASL LOGIN authentication failed)".to_string(), @@ -303,7 +305,7 @@ impl Config { tryfail: 5, }), ("ssh".to_string(), - Set { + SetCfg { src: "ssh".to_string(), filename: "auth.log".to_string(), regex: "(Invalid user|BREAK|not allowed because|no matching key exchange method found)".to_string(), @@ -312,7 +314,7 @@ impl Config { tryfail: 5, },), ("http".to_string(), - Set { + SetCfg { src: "http".to_string(), filename: "".to_string(), regex: "(anonymousfox.co)".to_string(), @@ -321,7 +323,7 @@ impl Config { tryfail: 5, },), ("openvpn".to_string(), - Set { + SetCfg { src: "openvpn".to_string(), filename: "status".to_string(), regex: "(UNDEF)".to_string(), @@ -350,96 +352,40 @@ impl Config { } pub async fn load(&mut self, server: &String) -> Result<(), ReqError> { - self.get_global_config(server).await?; - self.get_trustnets(server).await?; - self.get_sets(server).await?; - self.get_ws_config(server).await?; + self.get_config(server).await?; Ok(()) } - async fn get_global_config(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = - httpclient().get(format!("{server}/config")).send().await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: HashMap = match req.json::>().await { - Ok(res) => { - let mut out: HashMap = HashMap::new(); - res.into_iter().map(|x| x).for_each(|x| { - out.insert(x.key.to_string(), x); - }); - out - } - Err(err) => return Err(err), - }; - let key = "".to_string(); - self.api = data - .get(&key.to_string()) - .unwrap_or(&GlobalConfig { - key: "api".to_string(), - value: "127.0.0.1:8060".to_string(), - }) - .value - .clone(); - Ok(()) - } - - async fn get_trustnets(&mut self, server: &String) -> Result<(), ReqError> { + async fn get_config(&mut self, server: &String) -> Result<(), ReqError> { let resp: Result = httpclient() - .get(format!("{server}/config/trustlist")) + .get(format!("{server}/config?v=2")) .send() .await; let req = match resp { Ok(re) => re, Err(err) => return Err(err), }; - let data: Vec = match req.json::>().await { + let data: GlobalConfigV2 = match req.json::().await { Ok(res) => res, Err(err) => return Err(err), }; - self.trustnets = data; - Ok(()) - } - async fn get_sets(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = httpclient() - .get(format!("{server}/config/sets")) - .send() - .await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: Vec = match req.json::>().await { - Ok(res) => res, - Err(err) => return Err(err), - }; - for d in data { + for d in data.sets { self.sets.insert(d.src.clone(), d); } - Ok(()) - } - async fn get_ws_config(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = - httpclient().get(format!("{server}/config/ws")).send().await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: HashMap = match req.json::>().await { - Ok(res) => { - let mut out: HashMap = HashMap::new(); - res.into_iter().map(|x| x).for_each(|x| { - out.insert(x.t.to_string(), x); - }); - out - } - Err(err) => return Err(err), - }; - self.ws = data; + self.trustnets = data.trustlists; + + data.ws.into_iter().map(|x| x).for_each(|x| { + self.ws.insert(x.t.to_string(), x); + }); + + self.api = data + .cfg + .get(&"api".to_string()) + .unwrap_or(&self.api) + .clone(); + Ok(()) } @@ -508,13 +454,15 @@ pub fn httpclient() -> Client { } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GlobalConfig { - pub key: String, - pub value: String, +pub struct GlobalConfigV2 { + pub cfg: HashMap, + pub sets: Vec, + pub trustlists: Vec, + pub ws: Vec, } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Set { +pub struct SetCfg { pub src: String, pub filename: String, pub regex: String, @@ -543,13 +491,13 @@ pub struct URL { pub path: String, } -impl PartialEq for Set { +impl PartialEq for SetCfg { fn eq(&self, other: &Self) -> bool { self.src == other.src } } -impl Hash for Set { +impl Hash for SetCfg { fn hash(&self, state: &mut H) { self.src.hash(state); } diff --git a/src/monitoring.rs b/src/monitoring.rs index 456691a..583a6c2 100644 --- a/src/monitoring.rs +++ b/src/monitoring.rs @@ -24,33 +24,46 @@ pub async fn apiserver(ctxarc: &Arc>) -> io::Result<()> { loop { match listener.accept().await { Ok((stream, _addr)) => { - //let mut buf = [0; 1024]; - let data; - { - let ctx = ctxarc.read().await; - data = serde_json::to_string(&ctx.blocklist); - } + stream.readable().await.unwrap(); + let (reader, mut writer) = stream.into_split(); + let mut buf: [u8; 16] = [0; 16]; - match data { - Ok(dt) => { - let (_reader, mut writer) = stream.into_split(); - match writer.write_all(format!("{dt}").as_bytes()).await { - Ok(_) => {} - Err(err) => { - println!("{err}"); - } - } + match reader.try_read(&mut buf) { + Ok(_) => {} + Err(e) => { + println!("error: {}", e); } + }; + let msg = match String::from_utf8(buf.to_vec()) { + Ok(o) => o.trim_matches(char::from(0)).trim().to_string(), + Err(_) => "".to_string(), + }; + + let res = format_result(&ctxarc, msg.as_str()).await; + + match writer.write_all(format!("{res}").as_bytes()).await { + Ok(_) => {} Err(err) => { - println!("unable to serialize data: {err}"); + println!("ee {err}"); } } } Err(err) => { - println!("couldn't get client: {}", err) + println!("unable to serialize data: {err}"); } } } }); Ok(()) } + +async fn format_result(ctxarc: &Arc>, mode: &str) -> String { + let data; + let ctx = ctxarc.read().await; + match mode { + "cfg" => data = serde_json::to_string(&ctx.cfg).unwrap(), + "blocklist" => data = serde_json::to_string(&ctx.blocklist).unwrap(), + _ => data = serde_json::to_string(&ctx.blocklist).unwrap(), + }; + data +}