Skip to content
This repository was archived by the owner on Dec 19, 2024. It is now read-only.

Commit f9a1058

Browse files
committed
feat: add support for clamav virus scanning
closes #27
1 parent 2606e0a commit f9a1058

File tree

7 files changed

+62
-3
lines changed

7 files changed

+62
-3
lines changed

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "autumn"
3-
version = "1.1.8"
3+
version = "1.1.9"
44
authors = ["Paul Makles <[email protected]>"]
55
edition = "2018"
66

@@ -38,3 +38,6 @@ actix-web = "4.0.0-beta.9"
3838
actix-cors = "0.6.0-beta.2"
3939
actix-files = "0.6.0-beta.7"
4040
actix-multipart = "0.4.0-beta.6"
41+
42+
# virus scanning
43+
revolt_clamav-client = { version = "0.1.5" }

src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub mod db;
33
pub mod routes;
44
pub mod util;
55
pub mod version;
6+
pub mod virus_scan;
67

78
use futures::StreamExt;
89
use util::variables::{CONFIG, HOST, LOCAL_STORAGE_PATH, USE_S3};
@@ -38,6 +39,8 @@ async fn main() -> std::io::Result<()> {
3839

3940
info!("Starting Autumn server.");
4041

42+
virus_scan::init();
43+
4144
db::connect().await;
4245

4346
if !*USE_S3 {

src/routes/upload.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::config::{get_tag, Config, ContentType};
22
use crate::db::*;
33
use crate::util::result::Error;
4-
use crate::util::variables::{get_s3_bucket, LOCAL_STORAGE_PATH, USE_S3};
4+
use crate::util::variables::{get_s3_bucket, LOCAL_STORAGE_PATH, USE_S3, USE_CLAMD, CLAMD_HOST};
55

66
use actix_multipart::Multipart;
77
use actix_web::{web, HttpRequest, HttpResponse};
@@ -203,6 +203,17 @@ pub async fn post(req: HttpRequest, mut payload: Multipart) -> Result<HttpRespon
203203
if inspect(&buf).is_text() {
204204
Metadata::Text
205205
} else {
206+
// Scan the file for malware
207+
if *USE_CLAMD {
208+
let scan_response =
209+
revolt_clamav_client::scan_buffer_tcp(&buf, CLAMD_HOST.to_string(), None).unwrap();
210+
211+
let file_clean = revolt_clamav_client::clean(&scan_response).unwrap();
212+
if !file_clean {
213+
return Err(Error::Malware)
214+
}
215+
}
216+
206217
Metadata::File
207218
}
208219
}

src/util/result.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub enum Error {
1616
UnknownTag,
1717
ProbeError,
1818
NotFound,
19+
Malware,
1920
IOError,
2021
S3Error,
2122
LabelMe,
@@ -42,6 +43,7 @@ impl ResponseError for Error {
4243
Error::IOError => StatusCode::INTERNAL_SERVER_ERROR,
4344
Error::S3Error => StatusCode::INTERNAL_SERVER_ERROR,
4445
Error::LabelMe => StatusCode::INTERNAL_SERVER_ERROR,
46+
Error::Malware => StatusCode::FORBIDDEN,
4547
}
4648
}
4749

src/util/variables.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ lazy_static! {
1515
env::var("AUTUMN_MONGO_DATABASE").unwrap_or_else(|_| "revolt".to_string());
1616
pub static ref CORS_ALLOWED_ORIGIN: String =
1717
env::var("AUTUMN_CORS_ALLOWED_ORIGIN").expect("Missing AUTUMN_CORS_ALLOWED_ORIGIN environment variable.");
18+
pub static ref CLAMD_HOST: String =
19+
env::var("CLAMD_HOST").expect("Missing CLAMD_HOST environment variable.");
1820

1921
// Storage Settings
2022
pub static ref LOCAL_STORAGE_PATH: String =
@@ -27,6 +29,7 @@ lazy_static! {
2729

2830
// Application Flags
2931
pub static ref USE_S3: bool = env::var("AUTUMN_S3_REGION").is_ok() && env::var("AUTUMN_S3_ENDPOINT").is_ok();
32+
pub static ref USE_CLAMD: bool = env::var("CLAMD_HOST").is_ok();
3033
}
3134

3235
pub fn get_s3_bucket(bucket: &str) -> Result<s3::Bucket, Error> {

src/virus_scan.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::time::Duration;
2+
3+
use log::{error, info};
4+
5+
use crate::util::variables::{CLAMD_HOST, USE_CLAMD};
6+
7+
pub fn init() {
8+
if *USE_CLAMD {
9+
info!("Waiting for clamd to be ready...");
10+
11+
loop {
12+
let clamd_available = match revolt_clamav_client::ping_tcp(CLAMD_HOST.to_string()) {
13+
Ok(ping_response) => ping_response == b"PONG\0",
14+
Err(_) => false,
15+
};
16+
17+
if clamd_available {
18+
info!("clamd is ready, virus protection enabled!");
19+
break;
20+
} else {
21+
error!(
22+
"Could not ping clamd host at {}, retrying in 10 seconds...",
23+
CLAMD_HOST.to_string()
24+
);
25+
26+
std::thread::sleep(Duration::from_secs(10));
27+
}
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)