Skip to content

Instantly share code, notes, and snippets.

@bolshakov
Created May 30, 2018 08:50
Show Gist options
  • Save bolshakov/e4111a22049d04a7937a17999fa723a8 to your computer and use it in GitHub Desktop.
Save bolshakov/e4111a22049d04a7937a17999fa723a8 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"flag"
"fmt"
"log"
"net/http"
"os/exec"
"regexp"
)
type ScanResult struct {
isFileSafe bool
}
func scanFile(settings Settings, filePath string) (ScanResult, bool) {
var command *exec.Cmd
if settings.useSudo {
command = exec.Command("sudo", "-n", settings.kasperskyPath, "--scan-file", filePath)
} else {
command = exec.Command(settings.kasperskyPath, fmt.Sprintf("--scan-file %s", filePath))
}
var stdout bytes.Buffer
var stderr bytes.Buffer
command.Stdout = &stdout
command.Stderr = &stderr
err := command.Run()
if err != nil {
log.Printf("[ERROR] Scanning file `%s` failed: %s", filePath, stderr.String())
return ScanResult{}, false
} else {
safeFileRegexp := regexp.MustCompile("Threats found:\\s+0")
var isFileSafe = safeFileRegexp.MatchString(stdout.String())
log.Printf("[INFO] Scanning file: %s, safe: %t", filePath, isFileSafe)
return ScanResult{isFileSafe: isFileSafe}, true
}
}
func fastScanHandler(settings Settings) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Content-Type", "application/json; charset=utf-8") // normal header
filePath := request.URL.Query().Get("file_path")
if filePath != "" {
result, ok := scanFile(settings, filePath)
if ok {
json := fmt.Sprintf("{ \"safe\": %t}", result.isFileSafe)
fmt.Fprintf(writer, json)
} else {
writer.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(writer, "{ \"error\": \"something went wrong while scanning the file, see logs for details\"}")
}
} else {
writer.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(writer, "{ \"error\": \"missing `file_path` parameter\"}")
}
}
}
type Settings struct {
kasperskyPath string
useSudo bool
}
const defaultBinding = "127.0.0.1:8080"
const defaultKasperskyPath = "/opt/kaspersky/kav4fs/bin/kav4fs-control"
func main() {
bind := flag.String("bind", defaultBinding, "bind address - defaults to '127.0.0.1:8080'")
kasperskyPath := flag.String("kaspersky-path", defaultKasperskyPath, "full path to kav4fs-control binary")
useSudo := flag.Bool("sudo", false, "use sudo or not")
flag.Parse()
settings := Settings{kasperskyPath: *kasperskyPath, useSudo: *useSudo}
log.Printf("[INFO] Starting HTTP server on %s", *bind)
http.HandleFunc("/fast_scan", fastScanHandler(settings))
err := http.ListenAndServe(*bind, nil)
log.Printf("[ERROR] %s", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment