From 82b871170e0041df72d251d4cb2544a2130dcb5f Mon Sep 17 00:00:00 2001 From: serxoz Date: Wed, 17 Apr 2024 17:58:25 +0200 Subject: [PATCH] starting with sqlite to save suspicious IP addr --- .gitignore | 1 + Cargo.lock | 115 +++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + config.toml | 3 ++ src/config.rs | 20 +++++++-- src/database.rs | 63 ++++++++++++++++++++++++++ src/main.rs | 18 ++++++-- 7 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 src/database.rs diff --git a/.gitignore b/.gitignore index 1a4595e..f5908da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target *.log +*.db diff --git a/Cargo.lock b/Cargo.lock index b7bf90c..73469b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -41,6 +59,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bumpalo" version = "3.16.0" @@ -106,6 +130,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fnv" version = "1.0.7" @@ -128,6 +164,19 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" +dependencies = [ + "hashbrown", +] [[package]] name = "hermit-abi" @@ -198,6 +247,17 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libsqlite3-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "lock_api" version = "0.4.9" @@ -332,6 +392,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -392,7 +458,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "rusqlite" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" +dependencies = [ + "bitflags 2.5.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", ] [[package]] @@ -486,6 +566,7 @@ dependencies = [ "log", "log4rs", "rand", + "rusqlite", "serde", "tokio", "toml", @@ -654,6 +735,18 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -874,3 +967,23 @@ checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" dependencies = [ "memchr", ] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] diff --git a/Cargo.toml b/Cargo.toml index 951067b..6437e06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" log = "0.4.21" log4rs = "1.3.0" rand = "0.8.5" +rusqlite = { version = "0.31.0", features = ["bundled"] } serde = { version = "1.0.197", features = ["derive"] } tokio = { version = "1", features = ["full"] } toml = "0.8.12" diff --git a/config.toml b/config.toml index 7e11de1..addfa15 100644 --- a/config.toml +++ b/config.toml @@ -14,3 +14,6 @@ level = "INFO" [tarpit] # delay in milliseconds delay = 1500 + +[sqlite] +location = "tarpit.db" diff --git a/src/config.rs b/src/config.rs index aea654e..fa4a1e7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,7 +4,8 @@ use serde::{Deserialize, Serialize}; struct ConfigToml { listen: Option, log: Option, - tarpit: Option + tarpit: Option, + sqlite: Option } #[derive(Serialize, Deserialize, Debug)] @@ -24,6 +25,11 @@ struct ConfigTomlTarpit { delay: Option, } +#[derive(Serialize, Deserialize, Debug)] +struct ConfigTomlSqlite { + location: Option, +} + #[derive(Serialize, Deserialize, Debug)] pub struct Config { pub bind_addr: String, @@ -31,6 +37,7 @@ pub struct Config { pub log_file: String, pub log_level: String, pub delay: u64, + pub database_location: String } impl Config { @@ -57,7 +64,8 @@ impl Config { ConfigToml { listen: None, log: None, - tarpit: None + tarpit: None, + sqlite: None } }); @@ -82,12 +90,18 @@ impl Config { None => 0 }; + let database_location = match config_toml.sqlite { + Some(ConfigTomlSqlite { location }) => location.unwrap_or("./tarpit.db".to_owned()), + None => "./tarpit.db".to_owned() + }; + Config { bind_addr, bind_port, log_file, log_level, - delay + delay, + database_location } } } diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 0000000..9b40205 --- /dev/null +++ b/src/database.rs @@ -0,0 +1,63 @@ +use rusqlite::{Connection, Result}; +use std::time::SystemTime; + +pub struct Suspicious { + ip_addr: String, + banned: bool, + date_added: String, +} + +pub fn init_db(path: &str) -> Result { + let conn = Connection::open(path)?; + conn.execute( + "CREATE TABLE IF NOT EXISTS suspicious ( + ip_addr VARCHAR(128) PRIMARY KEY, + banned BOOLEAN NOT NULL, + date_added DATE + )", [])?; + + Ok(conn) +} + +pub fn get_all_suspicious(conn: &Connection) -> Result, rusqlite::Error> { + let mut stmt = conn.prepare("SELECT * FROM suspicious")?; + let rows = stmt.query_map([], |row| { + Ok(Suspicious { + ip_addr: row.get(0)?, + banned: row.get(1)?, + date_added: row.get(2)?, + }) + })?; + + Ok(rows.collect::, _>>()?) +} + +pub fn get_suspicious_by_ip_addr(conn: &Connection, ip_addr: &str) -> Result { + let mut stmt = conn.prepare("SELECT * FROM suspicious WHERE ip_addr = ?")?; + let row = stmt.query_row([ip_addr], |row| { + Ok(Suspicious { + ip_addr: row.get(0)?, + banned: row.get(1)?, + date_added: row.get(2)?, + }) + })?; + Ok(row) +} + +pub fn add_suspicious(conn: &Connection, mut ip_addr: &str) -> Result<(), rusqlite::Error> { + + //if ip_addr has ":" in it means it has port, we insert only IP addr + if ip_addr.contains(":") { + ip_addr = ip_addr.split(":").collect::>()[0]; + } + + let mut stmt = conn.prepare("INSERT OR IGNORE INTO suspicious (ip_addr, banned, date_added) VALUES (?, ?, ?)")?; + stmt.execute([ip_addr, "false", SystemTime::now()])?; + Ok(()) +} + +pub fn delete_suspicious(conn: &Connection, ip_addr: &str) -> Result<(), rusqlite::Error> { + let mut stmt = conn.prepare("DELETE FROM suspicious WHERE ip_addr = ?")?; + stmt.execute([ip_addr])?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 0f7dd37..d3cf9e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,12 +5,14 @@ */ mod sip; mod config; +mod database; use crate::sip::generic::*; use crate::sip::not_found::*; use crate::sip::options::*; use crate::sip::register::*; use crate::sip::unauthorized::*; +use crate::database::*; use rand::Rng; use std::error::Error; use std::net::SocketAddr; @@ -22,12 +24,14 @@ use log4rs::append::file::FileAppender; use log4rs::append::console::ConsoleAppender; use log4rs::config::{Appender, Config, Root}; use log4rs::encode::pattern::PatternEncoder; +use rusqlite::Connection; struct Server { socket: UdpSocket, buf: Vec, to_send: Option<(usize, SocketAddr)>, - config: config::Config + config: config::Config, + db_con: Connection } impl Server { @@ -36,7 +40,8 @@ impl Server { socket, mut buf, mut to_send, - config + config, + db_con } = self; loop { @@ -45,7 +50,11 @@ impl Server { // until it's writable and we're able to do so. if let Some((size, peer)) = to_send { log::info!("Suspicious peer: {}", peer); - // + match add_suspicious(&db_con, peer.to_string().as_str()) { + Ok(_) => {}, + Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Error adding suspicious peer to database")), + } + // test type of message received let msg = String::from_utf8(buf[..size].to_vec()).unwrap(); match msg { @@ -206,6 +215,8 @@ async fn main() -> Result<(), Box> { log4rs::init_config(logconfig).unwrap(); + let db_con = init_db(config.database_location.as_str())?; + let addr = format!("{}:{}", config.bind_addr, config.bind_port); let socket = UdpSocket::bind(&addr).await?; log::info!("Listening on: {}", socket.local_addr()?); @@ -215,6 +226,7 @@ async fn main() -> Result<(), Box> { buf: vec![0; 1024], to_send: None, config, + db_con }; // This starts the server task.