wip: convert prototype

This commit is contained in:
Michael Hohn
2024-05-13 19:38:00 -07:00
committed by =Michael Hohn
parent 5b324e092a
commit f1dd151891
2 changed files with 111 additions and 5 deletions

View File

@@ -2,14 +2,20 @@
package lcmem
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"log/slog"
"net/http"
"strconv"
"strings"
"github.com/advanced-security/mrvacommander/interfaces/mci"
"github.com/advanced-security/mrvacommander/types/mct"
"github.com/gorilla/mux"
"github.com/hohn/ghes-mirva-server/analyze"
"github.com/hohn/ghes-mirva-server/api"
@@ -200,10 +206,11 @@ func (c *Commander) MirvaRequest(w http.ResponseWriter, r *http.Request) {
// TODO Change this to functional style?
// session := new(MirvaSession)
session_id := c.st.Storage.NextID()
slog.Info("id: ", session_id)
// session_owner = vars["owner"]
// session_controller_repo = vars["repo"]
// session_collect_info(w, r)
session_owner := vars["owner"]
session_controller_repo := vars["repo"]
slog.Info("new run", "id: ", fmt.Sprint(session_id), session_owner, session_controller_repo)
c.collectRequestInfo(w, r)
// session_find_available_DBs()
@@ -211,3 +218,95 @@ func (c *Commander) MirvaRequest(w http.ResponseWriter, r *http.Request) {
// session_submit_response(w)
// session_save()
}
func (c *Commander) collectRequestInfo(w http.ResponseWriter, r *http.Request) {
slog.Debug("Collecting session info")
if r.Body == nil {
err := "Missing request body"
log.Println(err)
http.Error(w, err, http.StatusNoContent)
return
}
buf, err := io.ReadAll(r.Body)
if err != nil {
var w http.ResponseWriter
slog.Error("Error reading MRVA submission body", "error", err.Error())
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
msg, err := TrySubmitMsg(buf)
if err != nil {
// Unknown message
slog.Error("Unknown MRVA submission body format")
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Decompose the SubmitMsg and keep information in the MirvaSession
// 1. Save the query pack and keep the location
if !isBase64Gzip([]byte(msg.QueryPack)) {
slog.Error("MRVA submission body querypack has invalid format")
err := errors.New("MRVA submission body querypack has invalid format")
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err = sn.extract_tgz(msg.QueryPack)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 2. Save the language
sn.language = msg.Language
// 3. Save the repositories
for _, v := range msg.Repositories {
t := strings.Split(v, "/")
if len(t) != 2 {
slog.Error("Invalid owner / repository entry", "entry", t)
http.Error(w, err.Error(), http.StatusBadRequest)
}
sn.repositories = append(sn.repositories,
co.OwnerRepo{t[0], t[1]})
}
sn.save()
}
// Try to extract a SubmitMsg from a json-encoded buffer
func TrySubmitMsg(buf []byte) (mct.SubmitMsg, error) {
buf1 := make([]byte, len(buf))
copy(buf1, buf)
dec := json.NewDecoder(bytes.NewReader(buf1))
dec.DisallowUnknownFields()
var m mct.SubmitMsg
err := dec.Decode(&m)
return m, err
}
// Some important payloads can be listed via
// base64 -d < foo1 | gunzip | tar t|head -20
//
// This function checks the request body up to the `gunzip` part.
func isBase64Gzip(val []byte) bool {
if len(val) >= 4 {
// Extract header
hdr := make([]byte, base64.StdEncoding.DecodedLen(4))
_, err := base64.StdEncoding.Decode(hdr, []byte(val[0:4]))
if err != nil {
log.Println("WARNING: IsBase64Gzip decode error:", err)
return false
}
// Check for gzip heading
magic := []byte{0x1f, 0x8b}
if bytes.Equal(hdr[0:2], magic) {
return true
} else {
return false
}
} else {
return false
}
}

View File

@@ -1,4 +1,4 @@
package types
package mct
type DownloadResponse struct {
Repository DownloadRepo `json:"repository"`
@@ -210,3 +210,10 @@ type StatusResponse struct {
ScannedRepositories []ScannedRepo `json:"scanned_repositories"`
SkippedRepositories SkippedRepositories `json:"skipped_repositories"`
}
type SubmitMsg struct {
ActionRepoRef string `json:"action_repo_ref"`
Language string `json:"language"`
QueryPack string `json:"query_pack"`
Repositories []string `json:"repositories"`
}