Adds persistent storage using modernc.org/sqlite (pure Go). Login attempts are deduplicated by (username, password, ip) with counts. Sessions and session logs are tracked with UUID IDs. Includes embedded SQL migrations, configurable retention with background pruning, and an in-memory store for tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
64 lines
1.8 KiB
Go
64 lines
1.8 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// LoginAttempt represents a deduplicated login attempt.
|
|
type LoginAttempt struct {
|
|
ID int64
|
|
Username string
|
|
Password string
|
|
IP string
|
|
Count int
|
|
FirstSeen time.Time
|
|
LastSeen time.Time
|
|
}
|
|
|
|
// Session represents an authenticated SSH session.
|
|
type Session struct {
|
|
ID string
|
|
IP string
|
|
Username string
|
|
ShellName string
|
|
ConnectedAt time.Time
|
|
DisconnectedAt *time.Time
|
|
HumanScore *float64
|
|
}
|
|
|
|
// SessionLog represents a single log entry for a session.
|
|
type SessionLog struct {
|
|
ID int64
|
|
SessionID string
|
|
Timestamp time.Time
|
|
Input string
|
|
Output string
|
|
}
|
|
|
|
// Store is the interface for persistent storage of honeypot data.
|
|
type Store interface {
|
|
// RecordLoginAttempt upserts a login attempt, incrementing the count
|
|
// for existing (username, password, ip) combinations.
|
|
RecordLoginAttempt(ctx context.Context, username, password, ip string) error
|
|
|
|
// CreateSession creates a new session record and returns its UUID.
|
|
CreateSession(ctx context.Context, ip, username, shellName string) (string, error)
|
|
|
|
// EndSession sets the disconnected_at timestamp for a session.
|
|
EndSession(ctx context.Context, sessionID string, disconnectedAt time.Time) error
|
|
|
|
// UpdateHumanScore sets the human detection score for a session.
|
|
UpdateHumanScore(ctx context.Context, sessionID string, score float64) error
|
|
|
|
// AppendSessionLog adds a log entry to a session.
|
|
AppendSessionLog(ctx context.Context, sessionID, input, output string) error
|
|
|
|
// DeleteRecordsBefore removes all records older than the given cutoff
|
|
// and returns the total number of deleted rows.
|
|
DeleteRecordsBefore(ctx context.Context, cutoff time.Time) (int64, error)
|
|
|
|
// Close releases any resources held by the store.
|
|
Close() error
|
|
}
|