diff --git a/lib/lib/config.go b/lib/lib/config.go deleted file mode 100644 index 56a5175..0000000 --- a/lib/lib/config.go +++ /dev/null @@ -1,33 +0,0 @@ -package lib - -import ( - "encoding/json" - "os" -) - -type Config struct { - Pools []Pool `json:"pools"` -} - -func (c *Config) Load(list *[]Package, file string) error { - var ( - content []byte - err error - ) - - if content, err = os.ReadFile(file); err != nil { - return err - } - - if err = json.Unmarshal(content, c); err != nil { - return err - } - - for _, p := range c.Pools { - if err = p.Load(list); err != nil { - return err - } - } - - return nil -} diff --git a/lib/lib/package.go b/lib/lib/package.go deleted file mode 100644 index 6fcb7e2..0000000 --- a/lib/lib/package.go +++ /dev/null @@ -1,135 +0,0 @@ -package lib - -import ( - "archive/tar" - "bufio" - "compress/gzip" - "fmt" - "io" - "net/url" - "os" - "path" - "strings" - - "git.matterlinux.xyz/matter/tracker/log" - "github.com/bigkevmcd/go-configparser" -) - -type Package struct { - Name string `json:"name"` - Pool *Pool `json:"-"` - Version string `json:"version"` - Depends []string `json:"depends"` - Size string `json:"size"` - Desc string `json:"desc"` - Archive string `json:"archive"` -} - -func (p *Package) Files() []string { - var ( - gzip_reader io.Reader - header *tar.Header - result []string - file *os.File - err error - ) - - if file, err = os.Open(p.Archive); err != nil { - log.Error("Failed to open %s", p.Archive) - return result - } - defer file.Close() - - if gzip_reader, err = gzip.NewReader(bufio.NewReader(file)); err != nil { - log.Error("Failed to create reader for %s", p.Archive) - return result - } - - reader := tar.NewReader(gzip_reader) - - for header, err = reader.Next(); err == nil; header, err = reader.Next() { - if header.Typeflag != tar.TypeReg { - continue - } - - if path.Base(header.Name) != "files.tar.gz" { - continue - } - - if result, err = GetFiles(reader); err == nil { - break - } - - log.Error("Failed to get file list for %s: %s", p.Archive, err.Error()) - return []string{} - } - - return result -} - -func (p *Package) URL() string { - if nil == p.Pool { - return "" - } - url, _ := url.JoinPath(p.Pool.Source, "src/branch/"+p.Pool.Branch+"/src", p.Name) - return url -} - -func (p *Package) DependsToStr() string { - var depends string = "" - for _, d := range p.Depends { - depends += fmt.Sprintf("%s ", d) - } - return depends -} - -func (p *Package) Load(r io.Reader) error { - var ( - err error - size int64 - depends string = "" - section string = "DEFAULT" - ) - - parser := configparser.New() - if err = parser.ParseReader(r); err != nil { - return err - } - - for _, s := range parser.Sections() { - if s == "DEFAULT" { - continue - } - section = s - break - } - - if section == "DEFAULT" { - return fmt.Errorf("DATA does not contain any sections") - } - - p.Name = section - - if p.Version, err = parser.Get(section, "version"); err != nil { - return err - } - - if size, err = parser.GetInt64(section, "size"); err != nil { - return err - } - p.Size = SizeFromBytes(size) - - if p.Desc, err = parser.Get(section, "desc"); err != nil { - return err - } - - depends, _ = parser.Get(section, "depends") - - if depends == "" { - p.Depends = []string{} - } else { - p.Depends = strings.Split(depends, ",") - } - - return nil -} diff --git a/lib/lib/pool.go b/lib/lib/pool.go deleted file mode 100644 index f06b4ec..0000000 --- a/lib/lib/pool.go +++ /dev/null @@ -1,145 +0,0 @@ -package lib - -import ( - "archive/tar" - "bufio" - "compress/gzip" - "fmt" - "io" - "os" - "path" - - "github.com/bigkevmcd/go-configparser" -) - -type Pool struct { - Maintainer string `json:"-"` - Pubkey string `json:"-"` - Size string `json:"-"` - - Display string `json:"display"` - Branch string `json:"branch"` - Source string `json:"source"` - Name string `json:"name"` - URL string `json:"url"` - Dir string `json:"dir"` -} - -func (p *Pool) Load(list *[]Package) error { - var err error - - if p.Dir == "" { - return fmt.Errorf("pool directory is not specified") - } - - if err = p.LoadInfo(); err != nil { - return err - } - - if err = p.LoadList(list); err != nil { - return err - } - - return nil -} - -func (p *Pool) LoadList(list *[]Package) error { - var ( - list_path string - list_file *os.File - gzip_reader io.Reader - header *tar.Header - err error - ) - - list_path = path.Join(p.Dir, "LIST") - - if list_file, err = os.Open(list_path); err != nil { - return err - } - defer list_file.Close() - - if gzip_reader, err = gzip.NewReader(bufio.NewReader(list_file)); err != nil { - return err - } - - reader := tar.NewReader(gzip_reader) - - for header, err = reader.Next(); err == nil; header, err = reader.Next() { - if header.Typeflag != tar.TypeReg { - continue - } - - if path.Base(header.Name) != "DATA" { - return fmt.Errorf("LIST archive contains an unknown file") - } - - var pkg Package - - if err = pkg.Load(reader); err != nil { - return err - } - - pkg.Archive = path.Join(p.Dir, fmt.Sprintf("%s_%s.mpf", pkg.Name, pkg.Version)) - pkg.Pool = p - - *list = append(*list, pkg) - } - - return nil -} - -func (p *Pool) LoadInfo() error { - var ( - info_path string - info_file *os.File - section string - size int64 - err error - ) - - info_path = path.Join(p.Dir, "INFO") - - if info_file, err = os.Open(info_path); err != nil { - return err - } - - parser := configparser.New() - - if err = parser.ParseReader(bufio.NewReader(info_file)); err != nil { - return err - } - - section = "DEFAULT" - - for _, s := range parser.Sections() { - if s == "DEFAULT" { - continue - } - section = s - break - } - - if section == "DEFAULT" { - return fmt.Errorf("DATA does not contain any sections") - } - - if p.Name != section { - return fmt.Errorf("pool name (\"%s\") doesn't match with \"%s\"", p.Name, section) - } - - if p.Maintainer, err = parser.Get(p.Name, "maintainer"); err != nil { - return err - } - - if size, err = parser.GetInt64(section, "size"); err != nil { - return err - } - p.Size = SizeFromBytes(size) - - if p.Pubkey, err = parser.Get(section, "pubkey"); err != nil { - return err - } - - return nil -} diff --git a/lib/lib/util.go b/lib/lib/util.go deleted file mode 100644 index 45c6fd3..0000000 --- a/lib/lib/util.go +++ /dev/null @@ -1,104 +0,0 @@ -package lib - -import ( - "archive/tar" - "compress/gzip" - "fmt" - "io" - "strings" - "time" - - "github.com/gofiber/fiber/v2" -) - -func GetFiles(r io.Reader) ([]string, error) { - var ( - gzip_reader io.Reader - header *tar.Header - result []string - err error - ) - - if gzip_reader, err = gzip.NewReader(r); err != nil { - return result, err - } - - reader := tar.NewReader(gzip_reader) - - for header, err = reader.Next(); err == nil; header, err = reader.Next() { - if header.Typeflag != tar.TypeReg { - continue - } - - result = append(result, header.Name) - } - - return result, nil -} - -func ListToStr(l []string) string { - res := "" - for _, e := range l { - res += e + " " - } - return res -} - -func RenderError(c *fiber.Ctx, code int) error { - var msg string = "Server Error" - c.Status(code) - - switch code { - case 404: - msg = "Not Found" - } - - return c.Render("error", fiber.Map{ - "msg": msg, - }) -} - -func SizeFromBytes(size int64) string { - if size > 1024*1024*1024 { - return fmt.Sprintf("%dGB", (size / 1024 / 1024 / 1024)) - } else if size > 1024*1024 { - return fmt.Sprintf("%dMB", (size / 1024 / 1024)) - } else if size > 1024 { - return fmt.Sprintf("%dKB", (size / 1024)) - } - return fmt.Sprintf("%dB", size) -} - -func TimePassed(t time.Time) string { - diff := time.Since(t) - res := fmt.Sprintf( - "%ds ago", - int(diff.Seconds()), - ) - - if diff.Minutes() > 1 { - res = fmt.Sprintf( - "%dm and %ds ago", - int(diff.Minutes()), int(diff.Seconds())-(int(diff.Minutes())*60), - ) - } - - if diff.Hours() > 1 { - res = fmt.Sprintf("%dh and %dm ago", - int(diff.Hours()), - int(diff.Minutes())-(int(diff.Hours())*60), - ) - } - - return res -} - -func SanitizeXSS(s string) string { - var bad []string = []string{"~", "'", "\"", "/", "<", ">", "?", "=", "#", "(", ")", "{", "}", "*", "!", "`", "[", "]"} - - for _, c := range bad { - s = strings.ReplaceAll(s, c, "") - } - - return s -} diff --git a/lib/vuln.go b/lib/vuln.go index 7097c13..3bb8b4d 100644 --- a/lib/vuln.go +++ b/lib/vuln.go @@ -34,7 +34,7 @@ func ValidSeverity(s string) bool { return false } -func (v Vuln) StatusColor() string { +func (v *Vuln) StatusColor() string { switch v.Status { case "Waiting for review": return "blue" diff --git a/log/log.go b/log/log.go new file mode 100644 index 0000000..e0eb92f --- /dev/null +++ b/log/log.go @@ -0,0 +1,23 @@ +package log + +import ( + "fmt" + "time" +) + +func Log(p string, f string, args ...interface{}) { + now := time.Now() + nstr := now.Format("[02/01/06 15:04:05]") + + fmt.Printf("%s -%s- ", nstr, p) + fmt.Printf(f, args...) + fmt.Println() +} + +func Info(f string, args ...interface{}) { + Log("INFO", f, args...) +} + +func Error(f string, args ...interface{}) { + Log("ERROR", f, args...) +} diff --git a/main.go b/main.go index aa4efb4..d406be8 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ /* - * security | MatterLinux Package Security Tracker + * security | MatterLinux package security tracker * MatterLinux 2023-2024 (https://matterlinux.xyz) * This program is free software: you can redistribute it and/or modify @@ -21,17 +21,14 @@ package main import ( - "log" - "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "git.matterlinux.xyz/matter/security/routes" "github.com/gofiber/fiber/v2" "github.com/gofiber/template/html/v2" ) func main() { - log.SetFlags(log.Lshortfile | log.Ltime) - engine := html.New("./templates", ".html") app := fiber.New(fiber.Config{ DisableStartupMessage: true, @@ -40,29 +37,30 @@ func main() { err := lib.LoadDatabase() if err != nil { - log.Fatalf("Failed to load database: %s", err.Error()) + log.Error("Failed to load database: %s", err.Error()) + return } app.Static("/", "./public") - app.Get("/", routes.GETIndex) - app.Get("/details/:id", routes.GETDetails) + app.Get("/", routes.GET_Index) + app.Get("/details/:id", routes.GET_Details) - app.Get("/login", routes.GETLogin) - app.Post("/login", routes.POSTLogin) + app.Get("/login", routes.GET_Login) + app.Post("/login", routes.POST_Login) app.Use("/manage", routes.MiddleAuth) - app.Get("/manage", routes.GETManage) - app.Get("/manage/logout", routes.GETLogout) - app.Post("/manage/new", routes.POSTNew) - app.Post("/manage/status", routes.POSTStatus) + app.Get("/manage", routes.GET_Manage) + app.Get("/manage/logout", routes.GET_Logout) + app.Post("/manage/new", routes.POST_New) + app.Post("/manage/status", routes.POST_Status) app.Get("*", func(c *fiber.Ctx) error { return lib.RenderError(c, 404) }) - log.Printf("Starting MatterLinux Security Tracker on port 9876") - err = app.Listen(":9876") - if err != nil { - log.Fatalf("Error starting server: %s", err) + log.Info("Starting MatterLinux security tracker on port 9876") + + if err = app.Listen(":9876"); err != nil { + log.Info("Error starting server: %s", err) } } diff --git a/routes/index.go b/routes/index.go index ad11d7d..76877a4 100644 --- a/routes/index.go +++ b/routes/index.go @@ -1,12 +1,12 @@ package routes import ( - "log" "math" "strconv" "strings" "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "github.com/gofiber/fiber/v2" ) @@ -21,7 +21,7 @@ func GetPage(c *fiber.Ctx) (int, int, int) { return page, page * PAGE_SIZE, (page * PAGE_SIZE) - PAGE_SIZE } -func GETDetails(c *fiber.Ctx) error { +func GET_Details(c *fiber.Ctx) error { id := c.Params("id") if id == "" || !strings.HasPrefix(id, "MPSI-") { return lib.RenderError(c, 404) @@ -32,19 +32,17 @@ func GETDetails(c *fiber.Ctx) error { return lib.RenderError(c, 404) } - return c.Render("details", fiber.Map{ - "v": v, - }) + return c.Render("details", &v) } -func GETIndex(c *fiber.Ctx) error { +func GET_Index(c *fiber.Ctx) error { cur, max, min := GetPage(c) search_qu := c.Query("q") search_in := c.Query("i") vulns, err := lib.LoadVulns() if err != nil { - log.Printf("Failed to load vulns: %s", err.Error()) + log.Error("Failed to load vulns: %s", err.Error()) return lib.RenderError(c, 500) } @@ -74,7 +72,6 @@ func GETIndex(c *fiber.Ctx) error { } results = append(results, vulns[i]) - } pages := int64(math.Ceil(float64(len(results)) / float64(PAGE_SIZE))) diff --git a/routes/login.go b/routes/login.go index 027042c..a44150b 100644 --- a/routes/login.go +++ b/routes/login.go @@ -1,13 +1,12 @@ package routes import ( - "log" - "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "github.com/gofiber/fiber/v2" ) -func POSTLogin(c *fiber.Ctx) error { +func POST_Login(c *fiber.Ctx) error { body := struct { Username string `form:"username"` Password string `form:"password"` @@ -20,7 +19,7 @@ func POSTLogin(c *fiber.Ctx) error { users, err := lib.LoadUsers() if err != nil { - log.Printf("Failed to load users: %s", err.Error()) + log.Error("Failed to load users: %s", err.Error()) return lib.RenderError(c, 500) } @@ -34,7 +33,7 @@ func POSTLogin(c *fiber.Ctx) error { }) err = lib.UpdateUser(u) if err != nil { - log.Printf("Failed to update user: %s", err.Error()) + log.Error("Failed to update user: %s", err.Error()) return lib.RenderError(c, 500) } return c.Redirect("/manage") @@ -45,7 +44,7 @@ func POSTLogin(c *fiber.Ctx) error { return c.Render("login", fiber.Map{}) } -func GETLogin(c *fiber.Ctx) error { +func GET_Login(c *fiber.Ctx) error { if c.Cookies("auth") != "" { return c.Redirect("/manage") } diff --git a/routes/manage.go b/routes/manage.go index 7470af8..7e2712d 100644 --- a/routes/manage.go +++ b/routes/manage.go @@ -1,9 +1,8 @@ package routes import ( - "log" - "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "github.com/gofiber/fiber/v2" ) @@ -16,7 +15,7 @@ func MiddleAuth(c *fiber.Ctx) error { users, err := lib.LoadUsers() if err != nil { - log.Printf("Failed to load users: %s", err.Error()) + log.Error("Failed to load users: %s", err.Error()) return lib.RenderError(c, 500) } @@ -34,21 +33,21 @@ func MiddleAuth(c *fiber.Ctx) error { return c.Redirect("/login") } -func GETManage(c *fiber.Ctx) error { +func GET_Manage(c *fiber.Ctx) error { return c.Render("manage", fiber.Map{}) } -func GETLogout(c *fiber.Ctx) error { +func GET_Logout(c *fiber.Ctx) error { user, err := lib.GetUser(c) if err != nil { - log.Printf("Failed to load user: %s", err.Error()) + log.Error("Failed to load user: %s", err.Error()) return lib.RenderError(c, 500) } user.Cookie = "notset" err = lib.UpdateUser(user) if err != nil { - log.Printf("Failed to save users: %s", err.Error()) + log.Error("Failed to save users: %s", err.Error()) return lib.RenderError(c, 500) } diff --git a/routes/new.go b/routes/new.go index 0b6b26b..f4310d1 100644 --- a/routes/new.go +++ b/routes/new.go @@ -1,13 +1,12 @@ package routes import ( - "log" - "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "github.com/gofiber/fiber/v2" ) -func POSTNew(c *fiber.Ctx) error { +func POST_New(c *fiber.Ctx) error { body := struct { Desc string `form:"desc"` Source string `form:"source"` @@ -23,7 +22,7 @@ func POSTNew(c *fiber.Ctx) error { user, err := lib.GetUser(c) if err != nil { - log.Printf("Failed to get the user: %s", err.Error()) + log.Error("Failed to get the user: %s", err.Error()) return lib.RenderError(c, 500) } @@ -47,7 +46,7 @@ func POSTNew(c *fiber.Ctx) error { err = lib.AddVuln(v) if err != nil { - log.Printf("Failed to add vuln: %s", err.Error()) + log.Error("Failed to add vuln: %s", err.Error()) return lib.RenderError(c, 500) } diff --git a/routes/status.go b/routes/status.go index 20a2cfa..cde48f1 100644 --- a/routes/status.go +++ b/routes/status.go @@ -1,15 +1,15 @@ package routes import ( - "log" "strings" "git.matterlinux.xyz/matter/security/lib" + "git.matterlinux.xyz/matter/security/log" "github.com/gofiber/fiber/v2" _ "github.com/mattn/go-sqlite3" ) -func POSTStatus(c *fiber.Ctx) error { +func POST_Status(c *fiber.Ctx) error { body := struct { ID string `form:"id"` Status string `form:"status"` @@ -23,7 +23,7 @@ func POSTStatus(c *fiber.Ctx) error { user, err := lib.GetUser(c) if err != nil { - log.Printf("Failed to get the user: %s", err.Error()) + log.Error("Failed to get the user: %s", err.Error()) return lib.RenderError(c, 500) } @@ -40,7 +40,7 @@ func POSTStatus(c *fiber.Ctx) error { err = lib.UpdateVuln(vuln) if err != nil { - log.Printf("Failed to update the vuln: %s", err.Error()) + log.Error("Failed to update the vuln: %s", err.Error()) return lib.RenderError(c, 500) } diff --git a/templates/details.html b/templates/details.html index 1e2bc95..227ac9f 100644 --- a/templates/details.html +++ b/templates/details.html @@ -1,7 +1,7 @@ - MatterLinux | {{.v.ID}} + MatterLinux | {{.ID}} @@ -12,41 +12,41 @@
-

{{.v.ID}}

-

{{.v.Severity}}

+

{{.ID}}

+

{{.Severity}}

-

{{.v.Desc}}

+

{{.Desc}}

- + - + - + - + - + - +
Status - {{.v.Status}} -
{{.v.Message}} + {{.Status}} +
{{.Message}}
Created on{{.v.Date}}{{.Date}}
Updated on{{.v.Updated}}{{.Updated}}
Author(s){{.v.Author}}{{.Author}}
Source{{.v.Source}}{{.Source}}
Affected package{{.v.Package}}{{.Package}}
Affected versions{{.v.Versions}}{{.Versions}}