Basic auth
This commit is contained in:
parent
9eff9ce803
commit
2eb4f9e4ea
8
httpd.go
8
httpd.go
|
@ -20,6 +20,8 @@ type jsonInput struct {
|
||||||
type jsonInputParams struct {
|
type jsonInputParams struct {
|
||||||
Server string `json:"server"`
|
Server string `json:"server"`
|
||||||
Session int `json:"session"`
|
Session int `json:"session"`
|
||||||
|
User string `json:"user"`
|
||||||
|
Pass string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpServer struct {
|
type HttpServer struct {
|
||||||
|
@ -74,14 +76,16 @@ func (h *HttpServer) ajaxHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, "Invalid request", 500)
|
http.Error(w, "Invalid request", 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.ovpn.Debug(req)
|
h.ovpn.Debug(req.Action)
|
||||||
|
|
||||||
switch req.Action {
|
switch req.Action {
|
||||||
case "get-remotes":
|
case "get-remotes":
|
||||||
jsonStr, err = json.Marshal(h.ovpn)
|
jsonStr, err = json.Marshal(h.ovpn)
|
||||||
case "set-remote":
|
case "set-remote":
|
||||||
err = h.ovpn.SetRemote(req.Params.Server, req.Params.Session)
|
err = h.ovpn.SetRemote(req.Params.Server, req.Params.Session)
|
||||||
jsonStr = []byte("{\"status\": \"ok\"}")
|
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":
|
case "get-sessions":
|
||||||
jsonStr, err = json.Marshal(h.ovpn)
|
jsonStr, err = json.Marshal(h.ovpn)
|
||||||
case "version":
|
case "version":
|
||||||
|
|
40
openvpn.go
40
openvpn.go
|
@ -11,17 +11,24 @@ import (
|
||||||
"github.com/pyke369/golang-support/rcache"
|
"github.com/pyke369/golang-support/rcache"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OpenVpnPassword struct {
|
||||||
|
User string
|
||||||
|
Pass string
|
||||||
|
}
|
||||||
|
|
||||||
type OpenVpnSrv struct {
|
type OpenVpnSrv struct {
|
||||||
Remote string `json:"active-vpn"`
|
Remote string `json:"active-vpn"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
Identifier string `json:"identifier"`
|
Identifier string `json:"identifier"`
|
||||||
chanHold chan bool
|
chanHold chan bool
|
||||||
|
chanPass chan OpenVpnPassword
|
||||||
m sync.RWMutex
|
m sync.RWMutex
|
||||||
ret chan []string
|
ret chan []string
|
||||||
buf *bufio.ReadWriter
|
buf *bufio.ReadWriter
|
||||||
mgt *OpenVpnMgt
|
mgt *OpenVpnMgt
|
||||||
hold bool
|
hold bool
|
||||||
|
authCache *OpenVpnPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *OpenVpnSrv) Lock() {
|
func (v *OpenVpnSrv) Lock() {
|
||||||
|
@ -36,6 +43,7 @@ func NewOpenVpnSrv(conn net.Conn, mgt *OpenVpnMgt) *OpenVpnSrv {
|
||||||
return &OpenVpnSrv{
|
return &OpenVpnSrv{
|
||||||
buf: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)),
|
buf: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)),
|
||||||
chanHold: make(chan bool),
|
chanHold: make(chan bool),
|
||||||
|
chanPass: make(chan OpenVpnPassword),
|
||||||
ret: make(chan []string),
|
ret: make(chan []string),
|
||||||
mgt: mgt,
|
mgt: mgt,
|
||||||
hold: false,
|
hold: false,
|
||||||
|
@ -122,7 +130,6 @@ func (v *OpenVpnSrv) GetEcho() {
|
||||||
v.Provider = match[2]
|
v.Provider = match[2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *OpenVpnSrv) Response(response []string) {
|
func (v *OpenVpnSrv) Response(response []string) {
|
||||||
|
@ -168,6 +175,37 @@ func (v *OpenVpnSrv) SetRemote(server string) error {
|
||||||
return nil
|
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() {
|
func (v *OpenVpnSrv) waitForRelase() {
|
||||||
v.Status = "Hold"
|
v.Status = "Hold"
|
||||||
if v.hold {
|
if v.hold {
|
||||||
|
|
File diff suppressed because one or more lines are too long
19
vpnserver.go
19
vpnserver.go
|
@ -82,6 +82,12 @@ func (s *OpenVpnMgt) GetSession(pid int) (error, *OpenVpnSrv) {
|
||||||
if openvpn, ok := s.VpnServers[pid]; ok {
|
if openvpn, ok := s.VpnServers[pid]; ok {
|
||||||
return nil, openvpn
|
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
|
return errors.New(fmt.Sprintf("unknown session %d", pid)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +102,16 @@ func (s *OpenVpnMgt) Restart(pid int) error {
|
||||||
return nil
|
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 {
|
func (s *OpenVpnMgt) Kill(pid int) error {
|
||||||
// check if the session is valid
|
// check if the session is valid
|
||||||
err, session := s.GetSession(pid)
|
err, session := s.GetSession(pid)
|
||||||
|
@ -143,7 +159,6 @@ func (s *OpenVpnMgt) Remove(openvpn *OpenVpnSrv) {
|
||||||
delete(s.VpnServers, pid)
|
delete(s.VpnServers, pid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the version command on all vpn servers. Kind of useless
|
// 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)
|
remoteMatch := remoteRegexp.FindStringSubmatch(line)
|
||||||
switch {
|
switch {
|
||||||
// command successfull, we can ignore
|
// command successfull, we can ignore
|
||||||
|
case strings.HasPrefix(line, ">PASSWORD:"):
|
||||||
|
go openvpn.NeedPassword(line)
|
||||||
case strings.HasPrefix(line, ">HOLD"):
|
case strings.HasPrefix(line, ">HOLD"):
|
||||||
go openvpn.waitForRelase()
|
go openvpn.waitForRelase()
|
||||||
case len(remoteMatch) > 0:
|
case len(remoteMatch) > 0:
|
||||||
|
|
|
@ -140,6 +140,12 @@ select.interface {
|
||||||
ajax(server, {action: 'set-remote', params: {server: $('#server_'+pid).val() , session: pid}});
|
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) {
|
function refresh(server, data) {
|
||||||
setTimeout(function(){ ajax(server, {"action":"get-remotes"} )}, 3000);
|
setTimeout(function(){ ajax(server, {"action":"get-remotes"} )}, 3000);
|
||||||
if (data["last_change"] == last_change) {
|
if (data["last_change"] == last_change) {
|
||||||
|
@ -176,7 +182,15 @@ select.interface {
|
||||||
} else {
|
} else {
|
||||||
line +='<td>'+infos['active-vpn']+'</td>';
|
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>'+infos['status']+'</td>';
|
||||||
|
}
|
||||||
|
|
||||||
line +='<td><a href="javascript:vpn_restart('+pid+')">Reload</a></td>';
|
line +='<td><a href="javascript:vpn_restart('+pid+')">Reload</a></td>';
|
||||||
line +='<td><a href="javascript:vpn_kill('+pid+')">Kill</a></td>';
|
line +='<td><a href="javascript:vpn_kill('+pid+')">Kill</a></td>';
|
||||||
|
|
Loading…
Reference in New Issue