Basic auth

This commit is contained in:
Xavier Henner 2019-08-17 00:16:57 +02:00
parent 9eff9ce803
commit 2eb4f9e4ea
5 changed files with 78 additions and 5 deletions

View File

@ -20,6 +20,8 @@ type jsonInput struct {
type jsonInputParams struct {
Server string `json:"server"`
Session int `json:"session"`
User string `json:"user"`
Pass string `json:"password"`
}
type HttpServer struct {
@ -74,14 +76,16 @@ func (h *HttpServer) ajaxHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Invalid request", 500)
return
}
h.ovpn.Debug(req)
h.ovpn.Debug(req.Action)
switch req.Action {
case "get-remotes":
jsonStr, err = json.Marshal(h.ovpn)
case "set-remote":
err = h.ovpn.SetRemote(req.Params.Server, req.Params.Session)
jsonStr = []byte("{\"status\": \"ok\"}")
case "auth-user-pass":
err = h.ovpn.AuthUserPass(req.Params.Session, req.Params.User, req.Params.Pass)
jsonStr = []byte("{\"status\": \"ok\"}")
case "get-sessions":
jsonStr, err = json.Marshal(h.ovpn)
case "version":

View File

@ -11,17 +11,24 @@ import (
"github.com/pyke369/golang-support/rcache"
)
type OpenVpnPassword struct {
User string
Pass string
}
type OpenVpnSrv struct {
Remote string `json:"active-vpn"`
Status string `json:"status"`
Provider string `json:"provider"`
Identifier string `json:"identifier"`
chanHold chan bool
chanPass chan OpenVpnPassword
m sync.RWMutex
ret chan []string
buf *bufio.ReadWriter
mgt *OpenVpnMgt
hold bool
authCache *OpenVpnPassword
}
func (v *OpenVpnSrv) Lock() {
@ -36,6 +43,7 @@ func NewOpenVpnSrv(conn net.Conn, mgt *OpenVpnMgt) *OpenVpnSrv {
return &OpenVpnSrv{
buf: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)),
chanHold: make(chan bool),
chanPass: make(chan OpenVpnPassword),
ret: make(chan []string),
mgt: mgt,
hold: false,
@ -122,7 +130,6 @@ func (v *OpenVpnSrv) GetEcho() {
v.Provider = match[2]
}
}
}
func (v *OpenVpnSrv) Response(response []string) {
@ -168,6 +175,37 @@ func (v *OpenVpnSrv) SetRemote(server string) error {
return nil
}
func (v *OpenVpnSrv) NeedPassword(line string) {
v.mgt.Debug(line)
v.Status = "Need Password"
switch line {
case ">PASSWORD:Need 'Auth' username/password":
v.Status = "Need Password"
case ">PASSWORD:Verification Failed: 'Auth'":
v.authCache = nil
v.Status = "Auth Failed"
return
}
if v.authCache == nil {
ident := <-v.chanPass
v.authCache = &ident
}
switch line {
case ">PASSWORD:Need 'Auth' username/password":
v.sendCommand([]string{fmt.Sprintf("username \"Auth\" %s", v.authCache.User)})
v.sendCommand([]string{fmt.Sprintf("password \"Auth\" %s", v.authCache.Pass)})
}
}
func (v *OpenVpnSrv) AuthUserPass(user, pass string) {
auth := OpenVpnPassword{user, pass}
v.authCache = &auth
if v.Status == "Need Password" {
v.Status = "Authenticate"
v.chanPass <- auth
}
}
func (v *OpenVpnSrv) waitForRelase() {
v.Status = "Hold"
if v.hold {

File diff suppressed because one or more lines are too long

View File

@ -82,6 +82,12 @@ func (s *OpenVpnMgt) GetSession(pid int) (error, *OpenVpnSrv) {
if openvpn, ok := s.VpnServers[pid]; ok {
return nil, openvpn
}
// if there is only 1 session, ignore the pid parameter
if len(s.VpnServers) == 1 {
for _, openvpn := range s.VpnServers {
return nil, openvpn
}
}
return errors.New(fmt.Sprintf("unknown session %d", pid)), nil
}
@ -96,6 +102,16 @@ func (s *OpenVpnMgt) Restart(pid int) error {
return nil
}
func (s *OpenVpnMgt) AuthUserPass(pid int, user, pass string) error {
// check if the session is valid
err, session := s.GetSession(pid)
if err != nil {
return err
}
session.AuthUserPass(user, pass)
return nil
}
func (s *OpenVpnMgt) Kill(pid int) error {
// check if the session is valid
err, session := s.GetSession(pid)
@ -143,7 +159,6 @@ func (s *OpenVpnMgt) Remove(openvpn *OpenVpnSrv) {
delete(s.VpnServers, pid)
}
}
}
// send the version command on all vpn servers. Kind of useless
@ -229,6 +244,8 @@ func (s *OpenVpnMgt) handleConn(conn net.Conn) {
remoteMatch := remoteRegexp.FindStringSubmatch(line)
switch {
// command successfull, we can ignore
case strings.HasPrefix(line, ">PASSWORD:"):
go openvpn.NeedPassword(line)
case strings.HasPrefix(line, ">HOLD"):
go openvpn.waitForRelase()
case len(remoteMatch) > 0:

View File

@ -140,6 +140,12 @@ select.interface {
ajax(server, {action: 'set-remote', params: {server: $('#server_'+pid).val() , session: pid}});
}
function auth(pid) {
ajax(server, {action: "auth-user-pass", params:{session: pid,
user:$('#auth_'+pid+'>input.user').val(),
password:$('#auth_'+pid+'>input.pass').val()}});
}
function refresh(server, data) {
setTimeout(function(){ ajax(server, {"action":"get-remotes"} )}, 3000);
if (data["last_change"] == last_change) {
@ -176,7 +182,15 @@ select.interface {
} else {
line +='<td>'+infos['active-vpn']+'</td>';
}
if(infos['status']=="Need Password") {
line +='<td><form id="auth_'+pid+'" action="#" onsubmit="auth('+pid+') ; return false" >';
line +='<input class="user" placeholder="Enter login" size="8">';
line +='<input type="password" placeholder="Password" size="8" class="pass">';
line +='<input type="submit" value="G0">';
line +='</form></td>';
} else {
line +='<td>'+infos['status']+'</td>';
}
line +='<td><a href="javascript:vpn_restart('+pid+')">Reload</a></td>';
line +='<td><a href="javascript:vpn_kill('+pid+')">Kill</a></td>';