no longer uploading files to scanners, sharing filesystem instead
This commit is contained in:
parent
2638e5f9a3
commit
34ac340cad
12 changed files with 45 additions and 149 deletions
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ deps:
|
|||
|
||||
build:
|
||||
echo "Building..."
|
||||
tailwindcss -o web/assets/styles.css
|
||||
tailwindcss -o server/web/assets/styles.css
|
||||
templ generate
|
||||
go build -o main.out server/main.go
|
||||
|
||||
|
|
4
go.mod
4
go.mod
|
@ -4,22 +4,18 @@ go 1.24.1
|
|||
|
||||
require (
|
||||
github.com/a-h/templ v0.3.857
|
||||
github.com/gorilla/handlers v1.5.2
|
||||
github.com/gorilla/securecookie v1.1.2
|
||||
github.com/gorilla/sessions v1.4.0
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/mattn/go-sqlite3 v1.14.27
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.20.1
|
||||
golang.org/x/crypto v0.32.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/sagikazarmark/locafero v0.7.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
|
|
10
go.sum
10
go.sum
|
@ -2,12 +2,9 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
|||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/a-h/templ v0.3.857 h1:6EqcJuGZW4OL+2iZ3MD+NnIcG7nGkaQeF2Zq5kf9ZGg=
|
||||
github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
|
@ -20,14 +17,10 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
|
||||
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
|
@ -47,7 +40,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
|
||||
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
|
@ -56,8 +48,6 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
|
|||
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||
|
|
|
@ -2,11 +2,11 @@ import os
|
|||
|
||||
class Config:
|
||||
# Read values from environment variables or use defaults
|
||||
UPLOAD_FOLDER = os.environ.get("UPLOAD_FOLDER", "/tmp/uploads")
|
||||
FILE_DIRECTORY = os.environ.get("FILE_DIRECTORY", "/tmp/uploads")
|
||||
HOST = os.environ.get("HOST", "127.0.0.1")
|
||||
PORT = int(os.environ.get("PORT", 5000))
|
||||
DEBUG = os.environ.get("DEBUG", "False").lower() in ("true", "1")
|
||||
|
||||
# Ensure upload directory exists
|
||||
if not os.path.exists(Config.UPLOAD_FOLDER):
|
||||
os.makedirs(Config.UPLOAD_FOLDER)
|
||||
if not os.path.exists(Config.FILE_DIRECTORY):
|
||||
os.makedirs(Config.FILE_DIRECTORY)
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
from flask import Blueprint, request, jsonify
|
||||
from os import path
|
||||
from oletools import olevba, mraptor
|
||||
from utils.file_handler import allowed_file, save_file, delete_file
|
||||
import config
|
||||
|
||||
mraptor_bp = Blueprint('mraptor', __name__)
|
||||
|
||||
@mraptor_bp.route('/analyze', methods=['POST'])
|
||||
def analyze_mraptor():
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'No file uploaded'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
if file.filename == '' or not allowed_file(file.filename):
|
||||
return jsonify({'error': 'Invalid or unsupported file type'}), 400
|
||||
|
||||
filepath = save_file(file)
|
||||
|
||||
data = request.form
|
||||
file = data['file']
|
||||
filepath = path.join(config.Config.FILE_DIRECTORY, file)
|
||||
# Analyze with olevba
|
||||
vbaparser = olevba.VBA_Parser(filepath)
|
||||
if vbaparser.detect_vba_macros():
|
||||
|
@ -22,15 +17,12 @@ def analyze_mraptor():
|
|||
try:
|
||||
vba_code = vbaparser.get_vba_code_all_modules()
|
||||
except Exception as e:
|
||||
delete_file(filepath)
|
||||
return jsonify({'error': e})
|
||||
delete_file(filepath)
|
||||
raptor = mraptor.MacroRaptor(vba_code)
|
||||
raptor.scan()
|
||||
if raptor.suspicious:
|
||||
return jsonify({'filename': file.filename, 'result': mraptor.Result_Suspicious, 'flags': raptor.get_flags(), 'matches': raptor.matches})
|
||||
return jsonify({'filename': file, 'result': mraptor.Result_Suspicious, 'flags': raptor.get_flags(), 'matches': raptor.matches})
|
||||
else:
|
||||
return jsonify({'filename': file.filename, 'result': mraptor.Result_MacroOK, 'flags': raptor.get_flags(), 'matches': raptor.matches})
|
||||
return jsonify({'filename': file, 'result': mraptor.Result_MacroOK, 'flags': raptor.get_flags(), 'matches': raptor.matches})
|
||||
else:
|
||||
delete_file(filepath)
|
||||
return jsonify({'filename': file.filename, 'result': mraptor.Result_NoMacro})
|
||||
return jsonify({'filename': file, 'result': mraptor.Result_NoMacro})
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
from flask import Blueprint, request, jsonify
|
||||
from os import path
|
||||
import oletools.oleid
|
||||
from utils.file_handler import allowed_file, delete_file, save_file
|
||||
import config
|
||||
|
||||
oleid_bp = Blueprint('oleid', __name__)
|
||||
|
||||
@oleid_bp.route('/analyze', methods=['POST'])
|
||||
def analyze_ole():
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'No file uploaded'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
if file.filename == '' or not allowed_file(file.filename):
|
||||
return jsonify({'error': 'Invalid or unsupported file type'}), 400
|
||||
|
||||
filepath = save_file(file)
|
||||
|
||||
data = request.form
|
||||
file = data['file']
|
||||
filepath = path.join(config.Config.FILE_DIRECTORY, file)
|
||||
# Analyze with oleid
|
||||
oid = oletools.oleid.OleID(filepath)
|
||||
indicators = oid.check()
|
||||
results = {indicator.name: indicator.value for indicator in indicators}
|
||||
delete_file(filepath)
|
||||
|
||||
return jsonify({'filename': file.filename, 'analysis': results})
|
||||
return jsonify({'filename': file, 'analysis': results})
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
from os import path
|
||||
from flask import Blueprint, request, jsonify
|
||||
import config
|
||||
import oletools.olevba
|
||||
from utils.file_handler import allowed_file, save_file, delete_file
|
||||
|
||||
olevba_bp = Blueprint('olevba', __name__)
|
||||
|
||||
@olevba_bp.route('/analyze', methods=['POST'])
|
||||
def analyze_vba():
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'No file uploaded'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
if file.filename == '' or not allowed_file(file.filename):
|
||||
return jsonify({'error': 'Invalid or unsupported file type'}), 400
|
||||
|
||||
filepath = save_file(file)
|
||||
data = request.form
|
||||
file = data['file']
|
||||
filepath = path.join(config.Config.FILE_DIRECTORY, file)
|
||||
|
||||
# Analyze with olevba
|
||||
vbaparser = oletools.olevba.VBA_Parser(filepath)
|
||||
results = vbaparser.analyze_macros()
|
||||
delete_file(filepath)
|
||||
|
||||
|
||||
return jsonify({'filename': file.filename, 'macros': results})
|
||||
return jsonify({'filename': file, 'macros': results})
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
Copyright © 2025 Johannes Bülow <johannes.buelow@jmbit.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "scanfile",
|
||||
Short: "A brief description of your application",
|
||||
Long: `A longer description that spans multiple lines and likely contains
|
||||
examples and usage of using your application. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
// Uncomment the following line if your bare application
|
||||
// has an action associated with it:
|
||||
// Run: func(cmd *cobra.Command, args []string) { },
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() {
|
||||
err := rootCmd.Execute()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.scanfile.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
func initConfig() {
|
||||
if cfgFile != "" {
|
||||
// Use config file from the flag.
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
// Find home directory.
|
||||
home, err := os.UserHomeDir()
|
||||
cobra.CheckErr(err)
|
||||
|
||||
// Search config in home directory with name ".scanfile" (without extension).
|
||||
viper.AddConfigPath(home)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName(".scanfile")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
// If a config file is found, read it in.
|
||||
if err := viper.ReadInConfig(); err == nil {
|
||||
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
|
||||
}
|
||||
}
|
|
@ -21,13 +21,19 @@ import (
|
|||
"log/slog"
|
||||
"os"
|
||||
|
||||
"git.jmbit.de/jmb/scanfile/server/cmd"
|
||||
"git.jmbit.de/jmb/scanfile/server/internal/config"
|
||||
"git.jmbit.de/jmb/scanfile/server/internal/server"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stderr)
|
||||
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil)))
|
||||
//TODO don't use cobra for this
|
||||
cmd.Execute()
|
||||
config.ReadConfigFile("")
|
||||
if viper.GetBool("web.tls") {
|
||||
server.NewServer().ListenAndServeTLS(viper.GetString("web.cert"), viper.GetString("web.key"))
|
||||
} else {
|
||||
server.NewServer().ListenAndServe()
|
||||
}
|
||||
}
|
||||
|
|
1
server/web/assets/htmx.min.js
vendored
Normal file
1
server/web/assets/htmx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -27,6 +27,7 @@ templ Base(title string) {
|
|||
<p>{viper.GetString("ui.name")} by <a href={templ.URL(viper.GetString("ui.byurl"))}>{viper.GetString("ui.byname")}</a> licenced under AGPLv3, </p>
|
||||
<p><a href={templ.URL(viper.GetString("ui.source"))}>Source</a></p>
|
||||
</div>
|
||||
<script src="/assets/htmx.min.js"></script>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
|
10
tailwind.config.js
Normal file
10
tailwind.config.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./server/web/*.{go,js,templ,html}"
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
Loading…
Add table
Reference in a new issue