diec and refractoring

This commit is contained in:
Johannes Bülow 2025-06-10 10:06:28 +02:00
parent a62157e8e5
commit 0d715ccb37
Signed by: jmb
GPG key ID: B56971CF7B8F83A6
20 changed files with 355 additions and 200 deletions

View file

@ -35,7 +35,6 @@ func CreateFile(ctx context.Context, name string, fileBytes []byte) (sqlc.File,
err = nil err = nil
} }
//Using UUIDs instead of the file hash to make switching storage backends easier //Using UUIDs instead of the file hash to make switching storage backends easier
_, err = store.SaveFile(file.ID.String(), fileBytes) _, err = store.SaveFile(file.ID.String(), fileBytes)
if err != nil { if err != nil {

View file

@ -11,7 +11,6 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
var pool *pgxpool.Pool var pool *pgxpool.Pool
func Connect() (*pgxpool.Pool, error) { func Connect() (*pgxpool.Pool, error) {

View file

@ -28,3 +28,20 @@ func InsertFileProperties(properties sqlc.InsertFilePropertiesParams) error {
} }
return err return err
} }
// InsertJsonResult() into one of the following tables:
// diec, msoffice_mraptor, msoffice_oleid, msoffice_olevba
func InsertJsonResult(fileID pgtype.UUID, data []byte, table string) error {
query := sqlc.New(pool)
var err error
switch table {
case "diec":
err = query.InsertFileDIEC(context.Background(), sqlc.InsertFileDIECParams{FileID: fileID, Data: data})
case "msoffice_oleid":
}
if err != nil {
slog.Error("Unable to insert DIEC results", "file-uuid", fileID.String(), "error", err)
}
return err
}

View file

@ -3,4 +3,27 @@ INSERT INTO file_properties (
id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple
) VALUES ($1, $2, $3, $4, $5, $6); ) VALUES ($1, $2, $3, $4, $5, $6);
-- name: GetFileProperties :one
SELECT * FROM file_properties
WHERE id = $1;
-- name: InsertFileDIEC :exec
INSERT INTO diec (
file_id, data
) VALUES ($1, $2);
-- name: InsertFileMsofficeOleid :exec
INSERT INTO msoffice_oleid (
file_id, data
) VALUES ($1, $2);
-- name: InsertFileMsofficeOlevba :exec
INSERT INTO msoffice_olevba (
file_id, data
) VALUES ($1, $2);
-- name: InsertFileMsofficeMraptor :exec
INSERT INTO msoffice_mraptor (
file_id, data
) VALUES ($1, $2);

View file

@ -10,7 +10,7 @@ import (
"git.jmbit.de/jmb/scanfile/server/internal/store" "git.jmbit.de/jmb/scanfile/server/internal/store"
) )
//BasicProcessing() determines type agnostic information about the file // BasicProcessing() determines type agnostic information about the file
func BasicProcessing(job sqlc.ProcessingJob) error { func BasicProcessing(job sqlc.ProcessingJob) error {
fileBytes, err := store.GetFileBytes(job.FileID.String()) fileBytes, err := store.GetFileBytes(job.FileID.String())
if err != nil { if err != nil {
@ -21,6 +21,7 @@ func BasicProcessing(job sqlc.ProcessingJob) error {
md5sum := md5.Sum(fileBytes) md5sum := md5.Sum(fileBytes)
fileCmdResult, err := FileCmd(job.FileID.String()) fileCmdResult, err := FileCmd(job.FileID.String())
if err != nil { if err != nil {
database.FailProcessingJob(job.ID, err)
slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err) slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err)
return err return err
} }
@ -32,9 +33,11 @@ func BasicProcessing(job sqlc.ProcessingJob) error {
fileProperties.LibmagicMime.String = fileCmdResult.MimeType fileProperties.LibmagicMime.String = fileCmdResult.MimeType
fileProperties.LibmagicApple.String = fileCmdResult.Apple fileProperties.LibmagicApple.String = fileCmdResult.Apple
fileProperties.LibmagicExtension.String = fileCmdResult.Extension fileProperties.LibmagicExtension.String = fileCmdResult.Extension
database.InsertFileProperties(fileProperties) err = database.InsertFileProperties(fileProperties)
if err != nil {
slog.Error("Error inserting basic file properties into database", "file-uuid", job.FileID.String(), "error", err)
return err
}
return nil return nil
} }

View file

@ -0,0 +1,25 @@
package basic
import (
"log/slog"
"os/exec"
"git.jmbit.de/jmb/scanfile/server/internal/store"
)
// DiecScan() runs diec -jdu on the file
func DiecScan(fileName string) ([]byte, error) {
var by []byte
filepath, err := store.AbsPath(fileName)
if err != nil {
slog.Error("Error in DiecScan", "file-uuid", fileName, "error", err)
return by, err
}
cmd := exec.Command("/usr/bin/diec", "-jdu", filepath)
result, err := cmd.Output()
if err != nil {
slog.Error("Error in DiecScan", "file-uuid", fileName, "error", err)
return by, err
}
return result, nil
}

View file

@ -8,7 +8,6 @@ import (
"git.jmbit.de/jmb/scanfile/server/internal/store" "git.jmbit.de/jmb/scanfile/server/internal/store"
) )
type FileCmdResult struct { type FileCmdResult struct {
Type string Type string
MimeType string MimeType string
@ -16,11 +15,12 @@ type FileCmdResult struct {
Extension string Extension string
} }
//FileCmd() runs "/usr/bin/file" on the object. Should be replaced with libmagic bindings instead // FileCmd() runs "/usr/bin/file" on the object. Should be replaced with libmagic bindings instead
func FileCmd(fileName string) (FileCmdResult, error) { func FileCmd(fileName string) (FileCmdResult, error) {
var returnStruct FileCmdResult var returnStruct FileCmdResult
filepath, err := store.AbsPath(fileName) filepath, err := store.AbsPath(fileName)
if err != nil { if err != nil {
slog.Error("Error in FileCmd", "file-uuid", fileName, "error", err)
return returnStruct, err return returnStruct, err
} }
cmd := exec.Command("/usr/bin/file", "-b", filepath) cmd := exec.Command("/usr/bin/file", "-b", filepath)

View file

@ -14,7 +14,8 @@ import (
var semaphore chan struct{} var semaphore chan struct{}
var swg *sync.WaitGroup var swg *sync.WaitGroup
//Used to determine if a task was started by a previous instance that stalled out or died
// Used to determine if a task was started by a previous instance that stalled out or died
var startup time.Time var startup time.Time
func Setup(wg *sync.WaitGroup) { func Setup(wg *sync.WaitGroup) {
@ -23,7 +24,7 @@ func Setup(wg *sync.WaitGroup) {
} }
// Submit() starts the analysis process for a file. // Submit() starts the analysis process for a file.
func Submit(ctx context.Context, file pgtype.UUID ) error { func Submit(ctx context.Context, file pgtype.UUID) error {
job, err := database.NewProcessingJob(ctx, file, TypeBasic) job, err := database.NewProcessingJob(ctx, file, TypeBasic)
if err != nil { if err != nil {
slog.Error("Could not submit processing job", "error", err, "file-uuid", file) slog.Error("Could not submit processing job", "error", err, "file-uuid", file)
@ -34,7 +35,6 @@ func Submit(ctx context.Context, file pgtype.UUID ) error {
return nil return nil
} }
func processJob(job sqlc.ProcessingJob) { func processJob(job sqlc.ProcessingJob) {
} }

View file

@ -5,18 +5,23 @@ import (
"strings" "strings"
) )
const TypeBasic = "Basic" const TypeBasic = "Basic"
// Microsoft Office Document // Microsoft Office Document
const TypeMSOffice = "MSOffice" const TypeMSOffice = "MSOffice"
// Microsoft Windows Portable Executable // Microsoft Windows Portable Executable
const TypePE = "PE" const TypePE = "PE"
// Linux/UNIX Executable Linkable Format // Linux/UNIX Executable Linkable Format
const TypeELF = "ELF" const TypeELF = "ELF"
// Java Archive (JAR) // Java Archive (JAR)
const TypeJAR = "JAR" const TypeJAR = "JAR"
// Archives (compressed etc.) // Archives (compressed etc.)
const TypeArchive = "Archive" const TypeArchive = "Archive"
// Anything not implemented (yet) // Anything not implemented (yet)
const TypeOther = "Other" const TypeOther = "Other"

View file

@ -11,6 +11,89 @@ import (
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
) )
const getFileProperties = `-- name: GetFileProperties :one
SELECT id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple FROM file_properties
WHERE id = $1
`
func (q *Queries) GetFileProperties(ctx context.Context, id pgtype.UUID) (FileProperty, error) {
row := q.db.QueryRow(ctx, getFileProperties, id)
var i FileProperty
err := row.Scan(
&i.ID,
&i.Sha256,
&i.Md5,
&i.LibmagicMime,
&i.LibmagicExtension,
&i.LibmagicApple,
)
return i, err
}
const insertFileDIEC = `-- name: InsertFileDIEC :exec
INSERT INTO diec (
file_id, data
) VALUES ($1, $2)
`
type InsertFileDIECParams struct {
FileID pgtype.UUID
Data []byte
}
func (q *Queries) InsertFileDIEC(ctx context.Context, arg InsertFileDIECParams) error {
_, err := q.db.Exec(ctx, insertFileDIEC, arg.FileID, arg.Data)
return err
}
const insertFileMsofficeMraptor = `-- name: InsertFileMsofficeMraptor :exec
INSERT INTO msoffice_mraptor (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeMraptorParams struct {
FileID pgtype.UUID
Data []byte
}
func (q *Queries) InsertFileMsofficeMraptor(ctx context.Context, arg InsertFileMsofficeMraptorParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeMraptor, arg.FileID, arg.Data)
return err
}
const insertFileMsofficeOleid = `-- name: InsertFileMsofficeOleid :exec
INSERT INTO msoffice_oleid (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeOleidParams struct {
FileID pgtype.UUID
Data []byte
}
func (q *Queries) InsertFileMsofficeOleid(ctx context.Context, arg InsertFileMsofficeOleidParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeOleid, arg.FileID, arg.Data)
return err
}
const insertFileMsofficeOlevba = `-- name: InsertFileMsofficeOlevba :exec
INSERT INTO msoffice_olevba (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeOlevbaParams struct {
FileID pgtype.UUID
Data []byte
}
func (q *Queries) InsertFileMsofficeOlevba(ctx context.Context, arg InsertFileMsofficeOlevbaParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeOlevba, arg.FileID, arg.Data)
return err
}
const insertFileProperties = `-- name: InsertFileProperties :exec const insertFileProperties = `-- name: InsertFileProperties :exec
INSERT INTO file_properties ( INSERT INTO file_properties (
id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple

View file

@ -33,7 +33,7 @@ func GetFileType(fileId string) (string, error) {
return kind.MIME.Value, nil return kind.MIME.Value, nil
} }
//Returns the MimeType for a []byte // Returns the MimeType for a []byte
// We only have to pass the file header = first 261 bytes // We only have to pass the file header = first 261 bytes
func GetBytesFileType(data []byte) (string, error) { func GetBytesFileType(data []byte) (string, error) {
kind, err := filetype.Match(data) kind, err := filetype.Match(data)

View file

@ -1,5 +1,6 @@
// templui component icon - version: main installed by templui v0.71.0 // templui component icon - version: main installed by templui v0.71.0
package icon package icon
// This file is auto generated // This file is auto generated
// Using Lucide icons version 0.507.0 // Using Lucide icons version 0.507.0
var ALargeSmall = Icon("a-large-small") var ALargeSmall = Icon("a-large-small")