package main import ( "encoding/base64" "encoding/json" "os" "regexp" "strconv" "strings" "time" ) type vpnSession struct { Time time.Time `json:"time"` Login string `json:"username"` Operation string `json:"operation"` Status string `json:"status"` Profile string `json:"profile"` TwoFA bool `json:"2fa_auth"` IP string `json:"client_ip"` PrivIP string `json:"private_ip"` AsNumber string `json:"as_number"` AsName string `json:"as_name"` NewAS bool `json:"as_new"` PwnedPasswd bool `json:"pwned_passwd"` Hostname string `json:"hostname"` TooMuchPwn bool `json:"too_much_pwn"` Mail string `json:"-"` cID int `json:"-"` kID int `json:"-"` port int `json:"-"` dev string `json:"-"` password string `json:"-"` otpCode string `json:"-"` localIP string `json:"-"` } func NewVPNSession(operation string) *vpnSession { v := vpnSession{ Time: time.Now().Round(time.Second), Status: "system failure", Operation: operation, } v.Hostname, _ = os.Hostname() return &v } func (c *vpnSession) b64Login() string { return base64.StdEncoding.EncodeToString([]byte(c.Login)) } func (c *vpnSession) ParseSessionId(line string) error { var err error client_id := strings.Split(strings.Replace(line, ">CLIENT:CONNECT,", "", 1), ",") if c.cID, err = strconv.Atoi(client_id[0]); err != nil { return err } if c.kID, err = strconv.Atoi(client_id[1]); err != nil { return err } return nil } func (c *vpnSession) ParseEnv(infos *[]string) error { var err error r := regexp.MustCompile("[^a-zA-Z0-9./_@-]") for _, line := range *infos { p := strings.Split(strings.Replace(line, ">CLIENT:ENV,", "", 1), "=") switch p[0] { case "trusted_port": if c.port, err = strconv.Atoi(r.ReplaceAllString(p[1], "")); err != nil { return err } case "untrusted_port": if c.port, err = strconv.Atoi(r.ReplaceAllString(p[1], "")); err != nil { return err } case "trusted_ip": c.IP = r.ReplaceAllString(p[1], "") case "untrusted_ip": c.IP = r.ReplaceAllString(p[1], "") case "ifconfig_local": c.localIP = r.ReplaceAllString(p[1], "") case "password": switch { case strings.HasPrefix(p[1], "CRV1"): split := strings.Split(p[1], ":") if len(split) != 5 { break } c.password = split[2] c.otpCode = split[4] case strings.HasPrefix(p[1], "SCRV1"): split := strings.Split(p[1], ":") if len(split) != 3 { break } data, err := base64.StdEncoding.DecodeString(split[1]) if err != nil { break } c.password = string(data) data, err = base64.StdEncoding.DecodeString(split[2]) if err != nil { break } c.otpCode = string(data) default: c.password = p[1] c.otpCode = "***" } case "username": c.Login = r.ReplaceAllString(p[1], "") case "dev": c.dev = r.ReplaceAllString(p[1], "") } } return nil } func (c *vpnSession) String() string { if res, err := json.MarshalIndent(c, " ", " "); err == nil { return string(res) } return "" }