update: better CSS border colors

This commit is contained in:
ngn 2024-08-13 22:25:36 +03:00
parent b24a970962
commit 4641faefc2
21 changed files with 873 additions and 445 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
docker-compose.yml
compose.yml
security
db/

9
Makefile Normal file
View File

@ -0,0 +1,9 @@
all: security
security: */*.go *.go
go build -o $@
format:
gofmt -s -w .
.PHONY: format

View File

@ -1,12 +1,26 @@
# security | MatterLinux Security Tracker
# security | MatterLinux security tracker
Soruce code of MatterLinux's security tracker, located at
[security.matterlinux.xyz](https://security.matterlinux.xyz)
### Deployment
Web server can be built and deployed with docker:
Web server can be built and deployed with docker compose, here is an
example configuration:
```yaml
version: "3"
services:
security:
image: mattersecurity
restart: unless-stopped
build:
context: ./
ports:
- "127.0.0.1:9876:9876"
volumes:
- "./db:/app/db"
```
After saving the configuration file, you can build and run the docker container:
```bash
docker build --tag mattersecurity .
mkdir -pv db
docker-compose up -d
```

View File

@ -1,12 +0,0 @@
version: "3"
services:
security:
image: mattersecurity
restart: unless-stopped
build:
context: ./
ports:
- "127.0.0.1:9876:9876"
volumes:
- "./db:/app/db"

View File

@ -5,7 +5,7 @@ import (
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
_ "github.com/mattn/go-sqlite3"
)
var Db *sql.DB
@ -35,34 +35,32 @@ const create_vulns string = `
`
func LoadDatabase() error {
_, err := os.Stat("db")
if err != nil && os.IsNotExist(err) {
err = os.Mkdir("db", os.ModePerm)
if err != nil {
return err
}
}
_, err := os.Stat("db")
if err != nil && os.IsNotExist(err) {
err = os.Mkdir("db", os.ModePerm)
if err != nil {
return err
}
}
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot access to db directory")
}
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot access to db directory")
}
Db, err = sql.Open("sqlite3", "db/data.db")
if err != nil {
return err
}
Db, err = sql.Open("sqlite3", "db/data.db")
if err != nil {
return err
}
_, err = Db.Exec(create_users)
if err != nil {
return err
}
_, err = Db.Exec(create_users)
if err != nil {
return err
}
_, err = Db.Exec(create_vulns)
if err != nil {
return err
}
_, err = Db.Exec(create_vulns)
if err != nil {
return err
}
return nil
return nil
}

33
lib/lib/config.go Normal file
View File

@ -0,0 +1,33 @@
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
}

135
lib/lib/package.go Normal file
View File

@ -0,0 +1,135 @@
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
}

145
lib/lib/pool.go Normal file
View File

@ -0,0 +1,145 @@
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
}

104
lib/lib/util.go Normal file
View File

@ -0,0 +1,104 @@
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
}

View File

@ -7,54 +7,54 @@ import (
)
type User struct {
Username string
Password string
Cookie string
Username string
Password string
Cookie string
}
func GetUser(c *fiber.Ctx) (User, error) {
users, err := LoadUsers()
if err != nil {
return User{}, err
}
users, err := LoadUsers()
if err != nil {
return User{}, err
}
for i, u := range users {
if c.Cookies("auth") == u.Cookie {
return users[i], nil
}
}
for i, u := range users {
if c.Cookies("auth") == u.Cookie {
return users[i], nil
}
}
return User{}, fmt.Errorf("user not found")
return User{}, fmt.Errorf("user not found")
}
func LoadUsers() ([]User, error) {
var users []User
var users []User
rows, err := Db.Query("SELECT * FROM users")
if err != nil {
return users, err
}
defer rows.Close()
rows, err := Db.Query("SELECT * FROM users")
if err != nil {
return users, err
}
defer rows.Close()
for rows.Next() {
var u User
rows.Scan(&u.Username, &u.Password, &u.Cookie)
users = append(users, u)
}
for rows.Next() {
var u User
rows.Scan(&u.Username, &u.Password, &u.Cookie)
users = append(users, u)
}
return users, nil
return users, nil
}
func UpdateUser(u User) error {
smt, err := Db.Prepare("UPDATE users SET password=?, cookie=? WHERE username=?")
if err != nil {
return err
}
smt, err := Db.Prepare("UPDATE users SET password=?, cookie=? WHERE username=?")
if err != nil {
return err
}
_, err = smt.Exec(u.Password, u.Cookie, u.Username)
if err != nil {
return err
}
_, err = smt.Exec(u.Password, u.Cookie, u.Username)
if err != nil {
return err
}
return nil
return nil
}

View File

@ -12,46 +12,46 @@ import (
)
func GetFTime() string {
return time.Now().Format("01/02/2006")
return time.Now().Format("01/02/2006")
}
func GetRandom() string {
buf := make([]byte, 128)
_, err := rand.Read(buf)
if err != nil {
log.Fatalf("Failed to get random bytes: %s", err.Error())
}
buf := make([]byte, 128)
_, err := rand.Read(buf)
if err != nil {
log.Fatalf("Failed to get random bytes: %s", err.Error())
}
return GetSHA256(buf)
return GetSHA256(buf)
}
func GetSHA256(s []byte) string {
sum := sha256.Sum256(s)
return fmt.Sprintf("%x", sum)
sum := sha256.Sum256(s)
return fmt.Sprintf("%x", sum)
}
func ContainsCase(s1 string, s2 string) bool {
return strings.Contains(
strings.ToLower(s1), strings.ToLower(s2),
)
return strings.Contains(
strings.ToLower(s1), strings.ToLower(s2),
)
}
func RenderError(c *fiber.Ctx, code int) error{
var msg string = "Server Error"
c.Status(code)
func RenderError(c *fiber.Ctx, code int) error {
var msg string = "Server Error"
c.Status(code)
switch code {
case 404:
msg = "Not Found"
case 500:
msg = "Server error"
case 403:
msg = "Forbidden"
case 400:
msg = "Bad request"
}
switch code {
case 404:
msg = "Not Found"
case 500:
msg = "Server error"
case 403:
msg = "Forbidden"
case 400:
msg = "Bad request"
}
return c.Render("error", fiber.Map{
"msg": msg,
})
return c.Render("error", fiber.Map{
"msg": msg,
})
}

View File

@ -7,131 +7,131 @@ import (
)
type Vuln struct {
ID string
Desc string
Source string
Severity string
Package string
Versions string
Status string
Message string
Author string
Date string
Updated string
ID string
Desc string
Source string
Severity string
Package string
Versions string
Status string
Message string
Author string
Date string
Updated string
}
func ValidSeverity(s string) bool {
switch s {
case "Low":
return true
case "Medium":
return true
case "High":
return true
case "Critical":
return true
}
return false
switch s {
case "Low":
return true
case "Medium":
return true
case "High":
return true
case "Critical":
return true
}
return false
}
func (v Vuln) StatusColor() string {
switch v.Status {
case "Waiting for review":
return "blue"
case "Ongoing review":
return "blue"
case "Working on a patch":
return "blue"
case "Won't patch":
return "red"
case "Patched":
return "green"
case "Not affected":
return "red"
}
switch v.Status {
case "Waiting for review":
return "blue"
case "Ongoing review":
return "blue"
case "Working on a patch":
return "blue"
case "Won't patch":
return "red"
case "Patched":
return "green"
case "Not affected":
return "red"
}
return ""
return ""
}
func GetID() string {
now := time.Now()
mic := strconv.FormatInt(now.UnixMicro(), 10)
sig := GetSHA256([]byte(mic))[:5]
now := time.Now()
mic := strconv.FormatInt(now.UnixMicro(), 10)
sig := GetSHA256([]byte(mic))[:5]
return fmt.Sprintf(
"MPSI-%s%s-%s",
now.Format("06"), now.Format("01"), sig,
)
return fmt.Sprintf(
"MPSI-%s%s-%s",
now.Format("06"), now.Format("01"), sig,
)
}
func LoadVulns() ([]Vuln, error) {
var vulns []Vuln
var vulns []Vuln
rows, err := Db.Query("SELECT * FROM vulns")
if err != nil {
return vulns, err
}
defer rows.Close()
rows, err := Db.Query("SELECT * FROM vulns")
if err != nil {
return vulns, err
}
defer rows.Close()
for rows.Next() {
var v Vuln
rows.Scan(
&v.ID, &v.Desc, &v.Source, &v.Severity,
&v.Package, &v.Versions, &v.Status, &v.Message,
&v.Author, &v.Date, &v.Updated)
vulns = append(vulns, v)
}
for rows.Next() {
var v Vuln
rows.Scan(
&v.ID, &v.Desc, &v.Source, &v.Severity,
&v.Package, &v.Versions, &v.Status, &v.Message,
&v.Author, &v.Date, &v.Updated)
vulns = append(vulns, v)
}
return vulns, nil
return vulns, nil
}
func FindVuln(id string) (Vuln, bool) {
var vuln Vuln
var vuln Vuln
smt, err := Db.Prepare("SELECT * FROM vulns WHERE id=?")
if err != nil {
return vuln, false
}
smt, err := Db.Prepare("SELECT * FROM vulns WHERE id=?")
if err != nil {
return vuln, false
}
row := smt.QueryRow(id)
err = row.Scan(
&vuln.ID, &vuln.Desc, &vuln.Source, &vuln.Severity,
&vuln.Package, &vuln.Versions, &vuln.Status, &vuln.Message,
&vuln.Author, &vuln.Date, &vuln.Updated)
if err != nil {
return vuln, false
}
row := smt.QueryRow(id)
err = row.Scan(
&vuln.ID, &vuln.Desc, &vuln.Source, &vuln.Severity,
&vuln.Package, &vuln.Versions, &vuln.Status, &vuln.Message,
&vuln.Author, &vuln.Date, &vuln.Updated)
if err != nil {
return vuln, false
}
return vuln, true
return vuln, true
}
func AddVuln(v Vuln) error{
smt, err := Db.Prepare("INSERT INTO vulns VALUES(?,?,?,?,?,?,?,?,?,?,?)")
if err != nil {
return err
}
func AddVuln(v Vuln) error {
smt, err := Db.Prepare("INSERT INTO vulns VALUES(?,?,?,?,?,?,?,?,?,?,?)")
if err != nil {
return err
}
_, err = smt.Exec(&v.ID, &v.Desc, &v.Source, &v.Severity,
&v.Package, &v.Versions, &v.Status, &v.Message,
&v.Author, &v.Date, &v.Updated)
if err != nil {
return err
}
_, err = smt.Exec(&v.ID, &v.Desc, &v.Source, &v.Severity,
&v.Package, &v.Versions, &v.Status, &v.Message,
&v.Author, &v.Date, &v.Updated)
if err != nil {
return err
}
return nil
return nil
}
func UpdateVuln(v Vuln) error {
smt, err := Db.Prepare("UPDATE vulns SET status=?, message=?, author=?, severity=?, updated=? WHERE id=?")
if err != nil {
return err
}
smt, err := Db.Prepare("UPDATE vulns SET status=?, message=?, author=?, severity=?, updated=? WHERE id=?")
if err != nil {
return err
}
_, err = smt.Exec(v.Status, v.Message,
v.Author, v.Severity, GetFTime(), v.ID)
if err != nil {
return err
}
_, err = smt.Exec(v.Status, v.Message,
v.Author, v.Severity, GetFTime(), v.ID)
if err != nil {
return err
}
return nil
return nil
}

58
main.go
View File

@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
*/
package main
@ -30,39 +30,39 @@ import (
)
func main() {
log.SetFlags(log.Lshortfile | log.Ltime)
log.SetFlags(log.Lshortfile | log.Ltime)
engine := html.New("./templates", ".html")
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
Views: engine,
})
engine := html.New("./templates", ".html")
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
Views: engine,
})
err := lib.LoadDatabase()
if err != nil {
log.Fatalf("Failed to load database: %s", err.Error())
}
err := lib.LoadDatabase()
if err != nil {
log.Fatalf("Failed to load database: %s", err.Error())
}
app.Static("/", "./public")
app.Get("/", routes.GETIndex)
app.Get("/details/:id", routes.GETDetails)
app.Static("/", "./public")
app.Get("/", routes.GETIndex)
app.Get("/details/:id", routes.GETDetails)
app.Get("/login", routes.GETLogin)
app.Post("/login", routes.POSTLogin)
app.Get("/login", routes.GETLogin)
app.Post("/login", routes.POSTLogin)
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.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("*", func(c *fiber.Ctx) error {
return lib.RenderError(c, 404)
})
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.Printf("Starting MatterLinux Security Tracker on port 9876")
err = app.Listen(":9876")
if err != nil {
log.Fatalf("Error starting server: %s", err)
}
}

View File

@ -1,7 +1,7 @@
.vuln {
padding: 30px;
background: var(--dark-second);
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
color: var(--bright-second);
}
@ -113,7 +113,7 @@
gap: 10px;
background: var(--dark-second);
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
}
.search-header {

View File

@ -1,7 +1,7 @@
form {
background: var(--dark-second);
padding: 30px;
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
display: flex;
flex-direction: column;

View File

@ -3,7 +3,7 @@ main a {
flex-direction: column;
font-size: 15px;
color: var(--bright-main);
color: var(--bright-second);
text-align: right;
margin-bottom: 10px;
}
@ -15,7 +15,7 @@ main a:hover {
form {
background: var(--dark-second);
padding: 30px;
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
display: flex;
flex-direction: column;

View File

@ -13,78 +13,78 @@ import (
var PAGE_SIZE = 32
func GetPage(c *fiber.Ctx) (int, int, int) {
page, err := strconv.Atoi(c.Query("p"))
if err != nil || page <= 0 {
page = 1
}
page, err := strconv.Atoi(c.Query("p"))
if err != nil || page <= 0 {
page = 1
}
return page, page*PAGE_SIZE, (page*PAGE_SIZE)-PAGE_SIZE
return page, page * PAGE_SIZE, (page * PAGE_SIZE) - PAGE_SIZE
}
func GETDetails(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" || !strings.HasPrefix(id, "MPSI-") {
return lib.RenderError(c, 404)
}
id := c.Params("id")
if id == "" || !strings.HasPrefix(id, "MPSI-") {
return lib.RenderError(c, 404)
}
v, suc := lib.FindVuln(id)
if !suc {
return lib.RenderError(c, 404)
}
v, suc := lib.FindVuln(id)
if !suc {
return lib.RenderError(c, 404)
}
return c.Render("details", fiber.Map{
"v": v,
})
return c.Render("details", fiber.Map{
"v": v,
})
}
func GETIndex(c *fiber.Ctx) error {
cur, max, min := GetPage(c)
search_qu := c.Query("q")
search_in := c.Query("i")
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())
return lib.RenderError(c, 500)
}
vulns, err := lib.LoadVulns()
if err != nil {
log.Printf("Failed to load vulns: %s", err.Error())
return lib.RenderError(c, 500)
}
results := []lib.Vuln{}
for i := len(vulns)-1; i >= 0; i-- {
if i >= max || i < min {
continue
}
results := []lib.Vuln{}
for i := len(vulns) - 1; i >= 0; i-- {
if i >= max || i < min {
continue
}
switch search_in {
case "desc":
if !lib.ContainsCase(vulns[i].Desc, search_qu){
continue
}
case "id":
if !lib.ContainsCase(vulns[i].ID, search_qu) {
continue
}
case "pkg":
if !lib.ContainsCase(vulns[i].Package, search_qu) {
continue
}
case "status":
if !lib.ContainsCase(vulns[i].Status, search_qu) {
continue
}
}
switch search_in {
case "desc":
if !lib.ContainsCase(vulns[i].Desc, search_qu) {
continue
}
case "id":
if !lib.ContainsCase(vulns[i].ID, search_qu) {
continue
}
case "pkg":
if !lib.ContainsCase(vulns[i].Package, search_qu) {
continue
}
case "status":
if !lib.ContainsCase(vulns[i].Status, search_qu) {
continue
}
}
results = append(results, vulns[i])
results = append(results, vulns[i])
}
}
pages := int64(math.Ceil(float64(len(results))/float64(PAGE_SIZE)))
return c.Render("index", fiber.Map{
"pages": pages,
"current": cur,
"next": cur+1,
"prev": cur-1,
"vulns": results,
"query": search_qu,
"in": search_in,
})
pages := int64(math.Ceil(float64(len(results)) / float64(PAGE_SIZE)))
return c.Render("index", fiber.Map{
"pages": pages,
"current": cur,
"next": cur + 1,
"prev": cur - 1,
"vulns": results,
"query": search_qu,
"in": search_in,
})
}

View File

@ -8,47 +8,47 @@ import (
)
func POSTLogin(c *fiber.Ctx) error {
body := struct{
Username string `form:"username"`
Password string `form:"password"`
}{}
body := struct {
Username string `form:"username"`
Password string `form:"password"`
}{}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
users, err := lib.LoadUsers()
if err != nil {
log.Printf("Failed to load users: %s", err.Error())
return lib.RenderError(c, 500)
}
users, err := lib.LoadUsers()
if err != nil {
log.Printf("Failed to load users: %s", err.Error())
return lib.RenderError(c, 500)
}
for _, u := range users {
if u.Username == u.Username &&
u.Password == lib.GetSHA256([]byte(body.Password)) {
u.Cookie = lib.GetRandom()
c.Cookie(&fiber.Cookie{
Name: "auth",
Value: u.Cookie,
})
err = lib.UpdateUser(u)
if err != nil {
log.Printf("Failed to update user: %s", err.Error())
return lib.RenderError(c, 500)
}
return c.Redirect("/manage")
}
}
for _, u := range users {
if u.Username == u.Username &&
u.Password == lib.GetSHA256([]byte(body.Password)) {
u.Cookie = lib.GetRandom()
c.Cookie(&fiber.Cookie{
Name: "auth",
Value: u.Cookie,
})
err = lib.UpdateUser(u)
if err != nil {
log.Printf("Failed to update user: %s", err.Error())
return lib.RenderError(c, 500)
}
return c.Redirect("/manage")
}
}
c.Status(403)
return c.Render("login", fiber.Map{})
c.Status(403)
return c.Render("login", fiber.Map{})
}
func GETLogin(c *fiber.Ctx) error {
if c.Cookies("auth") != "" {
return c.Redirect("/manage")
}
if c.Cookies("auth") != "" {
return c.Redirect("/manage")
}
return c.Render("login", fiber.Map{})
return c.Render("login", fiber.Map{})
}

View File

@ -8,49 +8,49 @@ import (
)
func MiddleAuth(c *fiber.Ctx) error {
cookie := c.Cookies("auth")
cookie := c.Cookies("auth")
if cookie == "" {
return c.Redirect("/login")
}
if cookie == "" {
return c.Redirect("/login")
}
users, err := lib.LoadUsers()
if err != nil {
log.Printf("Failed to load users: %s", err.Error())
return lib.RenderError(c, 500)
}
users, err := lib.LoadUsers()
if err != nil {
log.Printf("Failed to load users: %s", err.Error())
return lib.RenderError(c, 500)
}
for _, u := range users {
if u.Cookie == "notset" || u.Cookie == "" {
continue
}
for _, u := range users {
if u.Cookie == "notset" || u.Cookie == "" {
continue
}
if cookie == u.Cookie {
return c.Next()
}
}
if cookie == u.Cookie {
return c.Next()
}
}
c.ClearCookie("auth")
return c.Redirect("/login")
c.ClearCookie("auth")
return c.Redirect("/login")
}
func GETManage(c *fiber.Ctx) error {
return c.Render("manage", fiber.Map{})
return c.Render("manage", fiber.Map{})
}
func GETLogout(c *fiber.Ctx) error {
user, err := lib.GetUser(c)
if err != nil {
log.Printf("Failed to load user: %s", err.Error())
return lib.RenderError(c, 500)
}
user, err := lib.GetUser(c)
if err != nil {
log.Printf("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())
return lib.RenderError(c, 500)
}
user.Cookie = "notset"
err = lib.UpdateUser(user)
if err != nil {
log.Printf("Failed to save users: %s", err.Error())
return lib.RenderError(c, 500)
}
return c.Redirect("/login")
return c.Redirect("/login")
}

View File

@ -8,48 +8,48 @@ import (
)
func POSTNew(c *fiber.Ctx) error {
body := struct{
Desc string `form:"desc"`
Source string `form:"source"`
Severity string `form:"severity"`
Package string `form:"package"`
Versions string `form:"versions"`
}{}
body := struct {
Desc string `form:"desc"`
Source string `form:"source"`
Severity string `form:"severity"`
Package string `form:"package"`
Versions string `form:"versions"`
}{}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
user, err := lib.GetUser(c)
if err != nil {
log.Printf("Failed to get the user: %s", err.Error())
return lib.RenderError(c, 500)
}
user, err := lib.GetUser(c)
if err != nil {
log.Printf("Failed to get the user: %s", err.Error())
return lib.RenderError(c, 500)
}
if !lib.ValidSeverity(body.Severity){
return lib.RenderError(c, 400)
}
if !lib.ValidSeverity(body.Severity) {
return lib.RenderError(c, 400)
}
v := lib.Vuln{
ID: lib.GetID(),
Desc: body.Desc,
Source: body.Source,
Severity: body.Severity,
Package: body.Package,
Versions: body.Versions,
Status: "Waiting for review",
Message: "This vulnerability is waiting for a review from the maintainers",
Author: user.Username,
Date: lib.GetFTime(),
Updated: lib.GetFTime(),
}
v := lib.Vuln{
ID: lib.GetID(),
Desc: body.Desc,
Source: body.Source,
Severity: body.Severity,
Package: body.Package,
Versions: body.Versions,
Status: "Waiting for review",
Message: "This vulnerability is waiting for a review from the maintainers",
Author: user.Username,
Date: lib.GetFTime(),
Updated: lib.GetFTime(),
}
err = lib.AddVuln(v)
if err != nil {
log.Printf("Failed to add vuln: %s", err.Error())
return lib.RenderError(c, 500)
}
err = lib.AddVuln(v)
if err != nil {
log.Printf("Failed to add vuln: %s", err.Error())
return lib.RenderError(c, 500)
}
return c.Redirect("/manage")
return c.Redirect("/manage")
}

View File

@ -10,39 +10,39 @@ import (
)
func POSTStatus(c *fiber.Ctx) error {
body := struct{
ID string `form:"id"`
Status string `form:"status"`
Message string `form:"message"`
}{}
body := struct {
ID string `form:"id"`
Status string `form:"status"`
Message string `form:"message"`
}{}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
err := c.BodyParser(&body)
if err != nil {
return lib.RenderError(c, 400)
}
user, err := lib.GetUser(c)
if err != nil {
log.Printf("Failed to get the user: %s", err.Error())
return lib.RenderError(c, 500)
}
user, err := lib.GetUser(c)
if err != nil {
log.Printf("Failed to get the user: %s", err.Error())
return lib.RenderError(c, 500)
}
vuln, suc := lib.FindVuln(body.ID)
if !suc {
return lib.RenderError(c, 404)
}
vuln, suc := lib.FindVuln(body.ID)
if !suc {
return lib.RenderError(c, 404)
}
vuln.Message = body.Message
vuln.Status = body.Status
if vuln.Author != user.Username && !strings.Contains(vuln.Author, ", "+user.Username){
vuln.Author += ", "+user.Username
}
vuln.Message = body.Message
vuln.Status = body.Status
if vuln.Author != user.Username && !strings.Contains(vuln.Author, ", "+user.Username) {
vuln.Author += ", " + user.Username
}
err = lib.UpdateVuln(vuln)
if err != nil {
log.Printf("Failed to update the vuln: %s", err.Error())
return lib.RenderError(c, 500)
}
err = lib.UpdateVuln(vuln)
if err != nil {
log.Printf("Failed to update the vuln: %s", err.Error())
return lib.RenderError(c, 500)
}
return c.Redirect("/manage")
return c.Redirect("/manage")
}