diff --git a/deps.edn b/deps.edn index 4844d8df4..6dd84a1cb 100644 --- a/deps.edn +++ b/deps.edn @@ -23,7 +23,7 @@ com.layerware/hugsql-adapter-next-jdbc {:mvn/version "0.5.1"} com.zaxxer/HikariCP {:mvn/version "5.0.0" :exclusions [org.slf4j/slf4j-api]} - ;; Pedestal and Jetty webserver deps + ;; Pedestal and Jetty webserver deps io.pedestal/pedestal.jetty {:mvn/version "0.6.1" :exclusions @@ -50,9 +50,12 @@ :exclusions [buddy/buddy-core]} org.bouncycastle/bcprov-jdk18on {:mvn/version "1.75"} less-awful-ssl/less-awful-ssl {:mvn/version "1.0.6"} + xyz.capybara/clamav-client {:mvn/version "2.1.2"} ;; Yet Analytics deps com.yetanalytics/lrs - {:mvn/version "1.2.15" + {;; :mvn/version "1.2.15" + :git/url "https://github.com/yetanalytics/lrs.git" + :git/sha "ea6922af2cba3a34a67c40aa8b056298b59b0b35" :exclusions [org.clojure/clojure org.clojure/clojurescript com.yetanalytics/xapi-schema]} diff --git a/src/main/lrsql/init/clamav.clj b/src/main/lrsql/init/clamav.clj new file mode 100644 index 000000000..09c77a1bb --- /dev/null +++ b/src/main/lrsql/init/clamav.clj @@ -0,0 +1,32 @@ +(ns lrsql.init.clamav + "ClamAV virus scanning" + (:require [clojure.string :as cs] + [clojure.java.io :as io]) + (:import [xyz.capybara.clamav ClamavClient] + [xyz.capybara.clamav.commands.scan.result ScanResult ScanResult$OK])) + +;; questions +;; +;; * What do we want to know about found viruses? Anything? +;; * + +(defn init-file-scanner + "Given ClamAV config, creates a client and returns a function that reads in + the input and scans it with ClamAV. + Compatible with build-routes' :file-scanner argument" + [{:keys [clamav-host + clamav-port] + :or {clamav-host "localhost" + clamav-port 3310}}] + (let [client (new ClamavClient clamav-host clamav-port)] + (fn [input] + (with-open [in (io/input-stream input)] + (let [^ScanResult scan-result (.scan client in)] + (when-not (instance? ScanResult$OK scan-result) + (let [virus-list (-> scan-result + bean ;; FIXME: Normal property access? + :foundViruses + (get "stream") + (->> (into [])))] + {:message (format "Submitted file failed scan. Found: %s" + (cs/join ", " virus-list))}))))))) diff --git a/src/main/lrsql/system/webserver.clj b/src/main/lrsql/system/webserver.clj index 99aff67c0..e7cd48211 100644 --- a/src/main/lrsql/system/webserver.clj +++ b/src/main/lrsql/system/webserver.clj @@ -8,6 +8,7 @@ [clojure.core :refer [format]] [lrsql.admin.routes :refer [add-admin-routes]] [lrsql.init.oidc :as oidc] + [lrsql.init.clamav :as clamav] [lrsql.spec.config :as cs] [lrsql.system.util :refer [assert-config redact-config-vars]] [lrsql.util.cert :as cu] @@ -42,7 +43,10 @@ jwt-no-val-uname jwt-no-val-issuer jwt-no-val-role-key - jwt-no-val-role] + jwt-no-val-role + enable-clamav + clamav-host + clamav-port] jwt-exp :jwt-exp-time jwt-lwy :jwt-exp-leeway} config @@ -66,7 +70,11 @@ :wrap-interceptors (into [i/error-interceptor (handle-json-parse-exn)] - oidc-resource-interceptors)}) + oidc-resource-interceptors) + :file-scanner (when enable-clamav + (clamav/init-file-scanner + {:clamav-host clamav-host + :clamav-port clamav-port}))}) (add-admin-routes {:lrs lrs :exp jwt-exp