Created
May 30, 2018 08:50
-
-
Save bolshakov/e4111a22049d04a7937a17999fa723a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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