Remove unused code
This commit is contained in:
parent
e4327cd3a8
commit
3a5fa290e2
@ -82,26 +82,6 @@ func ActionServe(c *cli.Context) error {
|
||||
} else {
|
||||
s = pgStore
|
||||
}
|
||||
case "bolt", "BOLT":
|
||||
boltStartTime := time.Now()
|
||||
loggers.rootLogger.Debug("Initializing store.", "store_type", "bolt")
|
||||
boltStore, err := store.NewBBoltStore(cfg.Store.Bolt.DBPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer boltStore.Close()
|
||||
|
||||
loggers.rootLogger.Info("Initialized store.", "store_type", "bolt", "init_time", time.Since(boltStartTime))
|
||||
|
||||
if cfg.Store.EnableCache {
|
||||
loggers.rootLogger.Debug("Initializing store.", "store_type", "cache-bolt")
|
||||
startTime := time.Now()
|
||||
cachingStore := store.NewCachingStore(boltStore)
|
||||
s = cachingStore
|
||||
loggers.rootLogger.Info("Initialized store.", "store_type", "cache-bolt", "init_time", time.Since(startTime))
|
||||
} else {
|
||||
s = boltStore
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Invalid store configured")
|
||||
}
|
||||
|
@ -18,17 +18,12 @@ type StoreConfig struct {
|
||||
Type string `toml:"Type"`
|
||||
EnableCache bool `toml:"EnableCache"`
|
||||
Postgres PostgresStoreConfig `toml:"Postgres"`
|
||||
Bolt BoltStoreConfig `toml:"Bolt"`
|
||||
}
|
||||
|
||||
type PostgresStoreConfig struct {
|
||||
DSN string `toml:"DSN"`
|
||||
}
|
||||
|
||||
type BoltStoreConfig struct {
|
||||
DBPath string `toml:"DBPath"`
|
||||
}
|
||||
|
||||
type HoneypotConfig struct {
|
||||
ListenAddr string `toml:"ListenAddr"`
|
||||
LogLevel string `toml:"LogLevel"`
|
||||
|
@ -75,7 +75,7 @@
|
||||
mkdir -p web/frontend/dist
|
||||
cp -r ${frontend}/* web/frontend/dist
|
||||
'';
|
||||
vendorHash = "sha256-fJnln143V5ajZgEEgVZN2y3dIz9/L9w6ZBLZk/eX61M=";
|
||||
vendorHash = "sha256-RtYKwUx5m8pL6MUinmK7yNFNxybnN+Xs0k6Cv1CITEU=";
|
||||
ldflags = [ "-X git.t-juice.club/torjus/apiary.Build=${rev}" ];
|
||||
tags = [
|
||||
"embed"
|
||||
|
1
go.mod
1
go.mod
@ -15,7 +15,6 @@ require (
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/urfave/cli/v2 v2.27.6
|
||||
go.etcd.io/bbolt v1.4.0
|
||||
golang.org/x/crypto v0.36.0
|
||||
)
|
||||
|
||||
|
4
go.sum
4
go.sum
@ -160,8 +160,6 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
|
||||
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
@ -206,8 +204,6 @@ golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1,11 +0,0 @@
|
||||
package ssh
|
||||
|
||||
type ActionType int
|
||||
|
||||
const (
|
||||
ActionTypeLogPassword ActionType = iota
|
||||
ActionTypeLogPasswordSlow
|
||||
ActionTypeLogCommandAndExit
|
||||
ActionTypeSendGarbage
|
||||
)
|
||||
const ActionTypeDefault ActionType = ActionTypeLogPassword
|
@ -1,235 +0,0 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.t-juice.club/torjus/apiary/models"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
// var _ LoginAttemptStore = &BBoltStore{}
|
||||
|
||||
var bktKeyLogins []byte = []byte("logins")
|
||||
|
||||
type BBoltStore struct {
|
||||
db *bolt.DB
|
||||
}
|
||||
|
||||
func NewBBoltStore(path string) (*BBoltStore, error) {
|
||||
db, err := bolt.Open(path, 0o666, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening database: %w", err)
|
||||
}
|
||||
|
||||
var store BBoltStore
|
||||
store.db = db
|
||||
|
||||
err = db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(bktKeyLogins)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating database bucket: %w", err)
|
||||
}
|
||||
|
||||
return &store, nil
|
||||
}
|
||||
|
||||
func (s *BBoltStore) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
||||
|
||||
func (s *BBoltStore) AddAttempt(l *models.LoginAttempt) error {
|
||||
data, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyLogins)
|
||||
seq, err := bkt.NextSequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := itob(seq)
|
||||
return bkt.Put(key, data)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BBoltStore) All() (<-chan models.LoginAttempt, error) {
|
||||
ch := make(chan models.LoginAttempt)
|
||||
|
||||
go func() {
|
||||
_ = s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyLogins)
|
||||
|
||||
c := bkt.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var l models.LoginAttempt
|
||||
if err := json.Unmarshal(v, &l); err != nil {
|
||||
close(ch)
|
||||
panic(err)
|
||||
}
|
||||
ch <- l
|
||||
}
|
||||
|
||||
close(ch)
|
||||
|
||||
return nil
|
||||
})
|
||||
}()
|
||||
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
func (s *BBoltStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) {
|
||||
if statType == LoginStatsTotals {
|
||||
return s.statTotals()
|
||||
}
|
||||
|
||||
counts := make(map[string]int)
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyLogins)
|
||||
|
||||
c := bkt.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var l models.LoginAttempt
|
||||
if err := json.Unmarshal(v, &l); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch statType {
|
||||
case LoginStatsPasswords:
|
||||
counts[l.Password]++
|
||||
case LoginStatsCountry:
|
||||
counts[l.Country]++
|
||||
case LoginStatsIP:
|
||||
counts[l.RemoteIP.String()]++
|
||||
case LoginStatsUsername:
|
||||
counts[l.Username]++
|
||||
default:
|
||||
return fmt.Errorf("invalid stat type")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating stats: %w", err)
|
||||
}
|
||||
|
||||
if limit < 1 {
|
||||
return toResults(counts), nil
|
||||
}
|
||||
if limit >= len(counts) {
|
||||
return toResults(counts), nil
|
||||
}
|
||||
|
||||
var si StatItems
|
||||
for key := range counts {
|
||||
si = append(si, StatItem{Key: key, Count: counts[key]})
|
||||
}
|
||||
sort.Sort(si)
|
||||
|
||||
output := make(map[string]int)
|
||||
for i := len(si) - 1; i > len(si)-limit-1; i-- {
|
||||
output[si[i].Key] = si[i].Count
|
||||
}
|
||||
|
||||
return toResults(output), nil
|
||||
}
|
||||
|
||||
func (s *BBoltStore) statTotals() ([]StatsResult, error) {
|
||||
passwords := make(map[string]int)
|
||||
usernames := make(map[string]int)
|
||||
ips := make(map[string]int)
|
||||
countries := make(map[string]int)
|
||||
var count int
|
||||
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyLogins)
|
||||
|
||||
c := bkt.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var l models.LoginAttempt
|
||||
if err := json.Unmarshal(v, &l); err != nil {
|
||||
return err
|
||||
}
|
||||
passwords[l.Password] += 1
|
||||
usernames[l.Username] += 1
|
||||
ips[l.RemoteIP.String()] += 1
|
||||
countries[l.Country] += 1
|
||||
count++
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats := []StatsResult{
|
||||
{Name: "UniquePasswords", Count: len(passwords)},
|
||||
{Name: "UniqueUsernames", Count: len(usernames)},
|
||||
{Name: "UniqueIPs", Count: len(ips)},
|
||||
{Name: "UniqueCountries", Count: len(countries)},
|
||||
{Name: "TotalLoginAttempts", Count: count},
|
||||
}
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func (s *BBoltStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
|
||||
var results []models.LoginAttempt
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyLogins)
|
||||
|
||||
c := bkt.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var l models.LoginAttempt
|
||||
if err := json.Unmarshal(v, &l); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch query.QueryType {
|
||||
case AttemptQueryTypeIP:
|
||||
if l.RemoteIP.String() == query.Query {
|
||||
results = append(results, l)
|
||||
}
|
||||
case AttemptQueryTypePassword:
|
||||
if strings.Contains(l.Password, query.Query) {
|
||||
results = append(results, l)
|
||||
}
|
||||
case AttemptQueryTypeUsername:
|
||||
if strings.Contains(l.Username, query.Query) {
|
||||
results = append(results, l)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s *BBoltStore) IsHealthy() error {
|
||||
// TODO: Do actual healthcheck
|
||||
return nil
|
||||
}
|
||||
|
||||
func itob(v uint64) []byte {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, v)
|
||||
return b
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package store_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"git.t-juice.club/torjus/apiary/honeypot/ssh/store"
|
||||
)
|
||||
|
||||
func TestBBoltStore(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
f, err := os.CreateTemp(dir, "apiary-test-bbolt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fname := f.Name()
|
||||
f.Close()
|
||||
s, err := store.NewBBoltStore(fname)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testLoginAttemptStore(s, t)
|
||||
}
|
||||
|
||||
func FuzzBBoltStore(f *testing.F) {
|
||||
dir := f.TempDir()
|
||||
file, err := os.CreateTemp(dir, "apiary-test-bbolt")
|
||||
if err != nil {
|
||||
f.Fatal(err)
|
||||
}
|
||||
fname := file.Name()
|
||||
file.Close()
|
||||
s, err := store.NewBBoltStore(fname)
|
||||
if err != nil {
|
||||
f.Fatal(err)
|
||||
}
|
||||
fuzzLoginAttemptStore(s, f)
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
var ErrInvalidPassword = fmt.Errorf("invalid password")
|
||||
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
PasswordHash []byte `json:"passwordHash"`
|
||||
}
|
||||
|
||||
func (u *User) SetPassword(password string) error {
|
||||
newHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error hashing new password: %w", err)
|
||||
}
|
||||
|
||||
u.PasswordHash = newHash
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *User) VerifyPassword(password string) error {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password))
|
||||
if err != nil {
|
||||
return ErrInvalidPassword
|
||||
}
|
||||
return nil
|
||||
}
|
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
Version = "v0.2.3"
|
||||
Version = "v0.2.4"
|
||||
Build string
|
||||
)
|
||||
|
||||
|
@ -40,7 +40,7 @@ func (s *Server) serveIndex(frontendDir string) http.HandlerFunc {
|
||||
defer f.Close()
|
||||
|
||||
if _, err := io.Copy(w, f); err != nil {
|
||||
s.ServerLogger.Warnw("Error writing frontend to client.", "err", err)
|
||||
s.ServerLogger.Warn("Error writing frontend to client.", "err", err)
|
||||
}
|
||||
}
|
||||
return fn
|
||||
|
Loading…
x
Reference in New Issue
Block a user