manage auth-retry

This commit is contained in:
Xavier Henner
2019-07-11 08:14:38 +02:00
parent 7418a70afc
commit 1c02c700fa
4 changed files with 130 additions and 36 deletions

View File

@@ -11,11 +11,13 @@ import (
"strconv"
"strings"
"sync"
hibp "github.com/mattevans/pwned-passwords"
)
// Server represents the server
type OpenVpnMgt struct {
Port string
port string
buf map[string]*bufio.ReadWriter
m sync.RWMutex
ret chan []string
@@ -30,24 +32,28 @@ type OpenVpnMgt struct {
newAsTemplate string
cacheDir string
syslog bool
ipRouteScript string
otpMasterSecrets []string
hibpClient *hibp.Client
debug bool
}
// NewServer returns a pointer to a new server
func NewVPNServer(port string) *OpenVpnMgt {
return &OpenVpnMgt{
Port: port,
ret: make(chan []string),
ldap: make(map[string]ldapConfig),
buf: make(map[string]*bufio.ReadWriter),
clients: make(map[string]map[int]*vpnSession),
port: port,
ret: make(chan []string),
ldap: make(map[string]ldapConfig),
buf: make(map[string]*bufio.ReadWriter),
clients: make(map[string]map[int]*vpnSession),
hibpClient: hibp.NewClient(),
}
}
// Run starts a the server
func (s *OpenVpnMgt) Run() {
// Resolve the passed port into an address
addrs, err := net.ResolveTCPAddr("tcp", s.Port)
addrs, err := net.ResolveTCPAddr("tcp", s.port)
if err != nil {
log.Println(err)
os.Exit(1)
@@ -71,12 +77,25 @@ func (s *OpenVpnMgt) Run() {
}
}
func (s *OpenVpnMgt) CheckPwn(c *vpnSession) error {
c.LogPrintln("checking pwn password")
pwned, err := s.hibpClient.Pwned.Compromised(c.password)
if err != nil {
return err
}
c.PwnedPasswd = pwned
return nil
}
// send a command to the server. Set the channel to receive the response
func (s *OpenVpnMgt) sendCommand(msg []string, remote string) (error, []string) {
if len(s.buf) == 0 {
return errors.New("No openvpn server present"), nil
}
for _, line := range msg {
if s.debug {
log.Println(line)
}
if _, err := s.buf[remote].WriteString(line + "\r\n"); err != nil {
return err, nil
}
@@ -88,6 +107,13 @@ func (s *OpenVpnMgt) sendCommand(msg []string, remote string) (error, []string)
// wait for the response
ret := <-s.ret
if s.debug {
for _, line := range ret {
log.Println(line)
}
}
return nil, ret
}
@@ -136,7 +162,7 @@ func (s *OpenVpnMgt) ClientValidated(line, remote string) {
c.Status = "success"
infos := <-s.ret
if err := c.ParseEnv(&infos); err != nil {
if err := c.ParseEnv(s, &infos); err != nil {
log.Println(err)
}
@@ -159,7 +185,8 @@ func (s *OpenVpnMgt) ClientDisconnect(line, remote string) {
}
// Don't log the initial auth failure due to absence of OTP code
if c.Status != "Need OTP Code" {
// And don't log the auth failure during re auth
if c.Operation != "re auth" && c.Status != "Need OTP Code" {
s.Log(c)
}
@@ -168,12 +195,12 @@ func (s *OpenVpnMgt) ClientDisconnect(line, remote string) {
// called at the initial connexion
func (s *OpenVpnMgt) ClientConnect(line, remote string) {
c := NewVPNSession("log in")
c := NewVPNSession()
c.vpnserver = remote
c.ParseSessionId(line)
s.clients[remote][c.cID] = c
infos := <-s.ret
if err := c.ParseEnv(&infos); err != nil {
if err := c.ParseEnv(s, &infos); err != nil {
log.Println(err)
return
}
@@ -181,6 +208,27 @@ func (s *OpenVpnMgt) ClientConnect(line, remote string) {
c.Auth(s)
}
func (s *OpenVpnMgt) ClientReAuth(line, remote string) {
err, c := s.getClient(line, remote)
if err != nil {
log.Println(err, line)
return
}
c.ParseSessionId(line)
infos := <-s.ret
if err := c.ParseEnv(s, &infos); err != nil {
log.Println(err)
return
}
// reset some values
c.Profile = ""
c.Status = "system failure"
c.Operation = "re auth"
c.Auth(s)
}
// find a client among all registered sessions
func (s *OpenVpnMgt) getClient(line, remote string) (error, *vpnSession) {
re := regexp.MustCompile("^[^0-9]*,([0-9]+)[^0-9]*")
@@ -201,6 +249,25 @@ func (s *OpenVpnMgt) getClient(line, remote string) (error, *vpnSession) {
return errors.New("unknown vpn client"), nil
}
// update counters
func (s *OpenVpnMgt) updateCounters(line, remote string) {
p := strings.Split(strings.Replace(line, ":", ",", 1), ",")
err, c := s.getClient(p[0]+","+p[1], remote)
if err != nil {
log.Println(err, line)
return
}
if c.BwWrite, err = strconv.Atoi(p[2]); err != nil {
c.LogPrintln(err)
return
}
if c.BwRead, err = strconv.Atoi(p[3]); err != nil {
c.LogPrintln(err)
return
}
return
}
// main loop for a given openvpn server
func (s *OpenVpnMgt) handleConn(conn net.Conn) {
remote := conn.RemoteAddr().String()
@@ -282,7 +349,7 @@ func (s *OpenVpnMgt) handleConn(conn net.Conn) {
// trafic stats
case strings.HasPrefix(line, ">BYTECOUNT_CLI"):
//TODO use that
go s.updateCounters(line, remote)
// new bloc for a disconnect event.
// We start the receiving handler, which will wait for the Channel message
@@ -297,8 +364,14 @@ func (s *OpenVpnMgt) handleConn(conn net.Conn) {
case strings.HasPrefix(line, ">CLIENT:CONNECT"):
go s.ClientConnect(line, remote)
case strings.HasPrefix(line, ">CLIENT:REAUTH"):
go s.ClientReAuth(line, remote)
default:
response = append(response, line)
}
if s.debug && strings.Index(line, "password") == -1 {
log.Print(line)
}
}
}