diff --git a/main.go b/main.go index 6ed16f2..ea2ffa2 100644 --- a/main.go +++ b/main.go @@ -5,14 +5,14 @@ import ( "log" "log/syslog" "os" + "strings" "github.com/pyke369/golang-support/uconfig" ) -var config *uconfig.UConfig - func main() { var err error + var config *uconfig.UConfig // default configuration file is ./openvpn-dm-mgt-server.conf configFile := flag.String("config", "openvpn-dm-mgt-server.conf", "configuration file") logToSyslog := flag.Bool("syslog", false, "Log to syslog") @@ -47,6 +47,27 @@ func main() { } } + for _, profile := range config.GetPaths("config.profiles") { + profileName := strings.Split(profile, ".")[2] + ldapConf := ldapConfig{ + servers: parseConfigArray(config, profile+".servers"), + baseDN: config.GetString(profile+".baseDN", ""), + bindCn: config.GetString(profile+".bindCn", ""), + bindPw: config.GetString(profile+".bindPw", ""), + searchFilter: config.GetString(profile+".searchFilter", ""), + primaryAttribute: config.GetString(profile+".primaryAttribute", ""), + secondaryAttribute: config.GetString(profile+".secondaryAttribute", ""), + validGroups: parseConfigArray(config, profile+".validGroups"), + otpType: config.GetString(profile+".otp", ""), + certAuth: config.GetString(profile+".cert", "optionnal"), + upgradeFrom: config.GetString(profile+".upgradeFrom", ""), + } + ldapConf.addIPRange(config.GetString(profile+".IPRange", "")) + + server.ldap[profileName] = ldapConf + } + + // time to start the listeners go server.Run() NewHTTPServer( config.GetString("config.httpPort", "127.0.0.01:8080"), diff --git a/openvpn.go b/openvpn.go index f05eac0..7deb5df 100644 --- a/openvpn.go +++ b/openvpn.go @@ -18,6 +18,7 @@ type OpenVpnMgt struct { connected bool m sync.RWMutex ret chan []string + ldap map[string]ldapConfig authCa string vpnlogUrl string mailRelay string @@ -36,6 +37,7 @@ func NewVPNServer(port string) *OpenVpnMgt { return &OpenVpnMgt{ Port: port, ret: make(chan []string), + ldap: make(map[string]ldapConfig), } } @@ -66,6 +68,77 @@ func (s *OpenVpnMgt) Run() { } } +func (s *OpenVpnMgt) TokenPassword(c *vpnSession) bool { + return false +} + +func (s *OpenVpnMgt) Auth(c *vpnSession) (error, bool) { + // an empty password is not good + if c.password == "" { + return nil, false + } + + // check if the password is a valid token validated for TOTP 2FA + tokenPassword := s.TokenPassword(c) + // If this is the case, empty the password to avoid checking it against the + // ldap server + if tokenPassword { + c.password = "" + } + + c.Profile = "" + login := []string{c.Login} + pass := c.password + + for { + n := c.Profile + for k, ldap := range s.ldap { + if ldap.upgradeFrom != c.Profile { + continue + } + log.Printf("try %s with login %s\n", k, login) + + err, userOk, passOk, secondary := ldap.Auth(login, pass) + + // if there is an error, try the other configurations + if err != nil { + log.Println(err) + continue + } + + // we did find a valid User + if userOk { + // the login for the new auth level is given by the current one + login = secondary + + if c.Mail == "" { + c.Mail = secondary[0] + } + + if passOk && c.Profile != "" { + // it's at least the second auth level, and we have a valid + // password on 2 different auth system. It's a dupplicate + // password, let's log it + log.Printf("User %s has a dupplicate password\n", c.Login) + } + + // we have either a positive auth ok a previous valid one + if passOk || c.Profile != "" || tokenPassword { + c.Profile = k + } + } + } + + if n == c.Profile { + break + } + } + + log.Println(c) + log.Println(s.ldap[c.Profile]) + return nil, false +} + func (s *OpenVpnMgt) sendCommand(msg []string) (error, []string) { if !s.connected { return errors.New("No openvpn server present"), nil @@ -115,6 +188,16 @@ func (s *OpenVpnMgt) ClientConnect(line string) { client.ParseEnv(&infos) + err, ok := s.Auth(client) + + if err != nil { + log.Println(err) + } + + if ok { + log.Println("auth ok") + } + // err, msg := s.sendCommand([]string{fmt.Sprintf("client-deny %d %d \"Need OTP\" \"CRV1:R:blabla:eC5oZW5uZXI=:OTP Code \"", client.cID, client.kID)}) // if err != nil { // return diff --git a/vpnsession.go b/vpnsession.go index 46a8dbb..0a2ccd7 100644 --- a/vpnsession.go +++ b/vpnsession.go @@ -106,7 +106,6 @@ func (c *vpnSession) ParseEnv(infos *[]string) { c.dev = p[1] } } - } func (c *vpnSession) String() string {