OTP support
This commit is contained in:
		
							parent
							
								
									07b37e9bc4
								
							
						
					
					
						commit
						e9f6a04864
					
				| @ -7,16 +7,16 @@ type DailymotionVPN struct { | ||||
| 
 | ||||
| func (s *DailymotionVPN) ServerList() (error, *map[string]string) { | ||||
| 	VPNNames := map[string]string{ | ||||
| 		"Paris 1":          "gate-01.dc3.dailmotion.com", | ||||
| 		"New-York 1":       "gate-01.nyc.dailmotion.com", | ||||
| 		"Silicon Valley 1": "gate-01.sv6.dailmotion.com", | ||||
| 		"Singapore 1":      "gate-01.sg1.dailmotion.com", | ||||
| 		"Tokyo 1":          "gate-01.ty4.dailmotion.com", | ||||
| 		"Paris 2":          "gate-01.dc3.dailmotion.com", | ||||
| 		"New-York 2":       "gate-01.nyc.dailmotion.com", | ||||
| 		"Silicon Valley 2": "gate-01.sv6.dailmotion.com", | ||||
| 		"Singapore 2":      "gate-01.sg1.dailmotion.com", | ||||
| 		"Tokyo 2":          "gate-01.ty4.dailmotion.com", | ||||
| 		"Paris 1":          "gate-01.dc3.dailymotion.com", | ||||
| 		"New-York 1":       "gate-01.nyc.dailymotion.com", | ||||
| 		"Silicon Valley 1": "gate-01.sv6.dailymotion.com", | ||||
| 		"Singapore 1":      "gate-01.sg1.dailymotion.com", | ||||
| 		"Tokyo 1":          "gate-01.ty4.dailymotion.com", | ||||
| 		"Paris 2":          "gate-02.dc3.dailymotion.com", | ||||
| 		"New-York 2":       "gate-02.nyc.dailymotion.com", | ||||
| 		"Silicon Valley 2": "gate-02.sv6.dailymotion.com", | ||||
| 		"Singapore 2":      "gate-02.sg1.dailymotion.com", | ||||
| 		"Tokyo 2":          "gate-02.ty4.dailymotion.com", | ||||
| 		"default":          "vpn.dailymotion.com", | ||||
| 	} | ||||
| 	return nil, &VPNNames | ||||
|  | ||||
							
								
								
									
										3
									
								
								httpd.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								httpd.go
									
									
									
									
									
								
							| @ -22,6 +22,7 @@ type jsonInputParams struct { | ||||
| 	Session int    `json:"session"` | ||||
| 	User    string `json:"user"` | ||||
| 	Pass    string `json:"password"` | ||||
| 	OTP     string `json:"otp"` | ||||
| } | ||||
| 
 | ||||
| type HttpServer struct { | ||||
| @ -84,7 +85,7 @@ func (h *HttpServer) ajaxHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 		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) | ||||
| 		err = h.ovpn.AuthUserPass(req.Params.Session, req.Params.User, req.Params.Pass, req.Params.OTP) | ||||
| 		jsonStr = []byte("{\"status\": \"ok\"}") | ||||
| 	case "get-sessions": | ||||
| 		jsonStr, err = json.Marshal(h.ovpn) | ||||
|  | ||||
							
								
								
									
										93
									
								
								openvpn.go
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								openvpn.go
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| @ -14,6 +15,7 @@ import ( | ||||
| type OpenVpnPassword struct { | ||||
| 	User string | ||||
| 	Pass string | ||||
| 	OTP  string | ||||
| } | ||||
| 
 | ||||
| type OpenVpnSrv struct { | ||||
| @ -21,6 +23,7 @@ type OpenVpnSrv struct { | ||||
| 	Status     string `json:"status"` | ||||
| 	Provider   string `json:"provider"` | ||||
| 	Identifier string `json:"identifier"` | ||||
| 	Message    string `json:"message"` | ||||
| 	chanHold   chan bool | ||||
| 	chanPass   chan OpenVpnPassword | ||||
| 	m          sync.RWMutex | ||||
| @ -28,6 +31,7 @@ type OpenVpnSrv struct { | ||||
| 	buf        *bufio.ReadWriter | ||||
| 	mgt        *OpenVpnMgt | ||||
| 	hold       bool | ||||
| 	authWait   bool | ||||
| 	authCache  *OpenVpnPassword | ||||
| } | ||||
| 
 | ||||
| @ -47,12 +51,21 @@ func NewOpenVpnSrv(conn net.Conn, mgt *OpenVpnMgt) *OpenVpnSrv { | ||||
| 		ret:        make(chan []string), | ||||
| 		mgt:        mgt, | ||||
| 		hold:       false, | ||||
| 		authWait:   false, | ||||
| 		Status:     "Starting", | ||||
| 		Identifier: "Unknown", | ||||
| 		Provider:   "Unknown", | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) B64OTP() string { | ||||
| 	return base64.StdEncoding.EncodeToString([]byte(v.authCache.OTP)) | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) B64Pass() string { | ||||
| 	return base64.StdEncoding.EncodeToString([]byte(v.authCache.Pass)) | ||||
| } | ||||
| 
 | ||||
| // send a command to the server. Set the channel to receive the response | ||||
| func (v *OpenVpnSrv) sendCommand(msg []string) (error, []string) { | ||||
| 	v.Lock() | ||||
| @ -149,7 +162,9 @@ func (v *OpenVpnSrv) GetLine() (string, error) { | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) ValidRemote(server, port, proto string) { | ||||
| 	if !v.authWait { | ||||
| 		v.Status = "Connected" | ||||
| 	} | ||||
| 	if v.Remote != "" { | ||||
| 		v.sendCommand([]string{fmt.Sprintf("remote MOD %s %s %s", v.Remote, port, proto)}) | ||||
| 		return | ||||
| @ -182,12 +197,31 @@ func (v *OpenVpnSrv) SetRemote(server string) error { | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) NeedPassword(line string) { | ||||
| 	if v.authWait { | ||||
| 		return | ||||
| 	} | ||||
| 	v.authWait = true | ||||
| 	v.mgt.Debug(line) | ||||
| 	v.Status = "Need Password" | ||||
| 	switch line { | ||||
| 	case ">PASSWORD:Need 'Auth' username/password": | ||||
| 	v.Message = "" | ||||
| 	backup := v.authCache | ||||
| 
 | ||||
| 	OtpPassRegexp := rcache.Get("^>PASSWORD:Need 'Auth' username/password SC:([01]),(.*)$") | ||||
| 	OtpPassMatch := OtpPassRegexp.FindStringSubmatch(line) | ||||
| 
 | ||||
| 	CRV1Regexep := rcache.Get(">PASSWORD:Verification Failed: 'Auth' \\['CRV1:([R,E]*):(.*):(.*):(.*)'\\]") | ||||
| 	CRV1Match := CRV1Regexep.FindStringSubmatch(line) | ||||
| 	switch { | ||||
| 	case len(CRV1Match) > 1: | ||||
| 		v.Status = "Need OTP" | ||||
| 		v.Message = CRV1Match[4] | ||||
| 		v.authCache = nil | ||||
| 	case len(OtpPassMatch) > 1: | ||||
| 		v.Status = "Need Password and OTP" | ||||
| 		v.Message = OtpPassMatch[2] | ||||
| 	case line == ">PASSWORD:Need 'Auth' username/password": | ||||
| 		v.Status = "Need Password" | ||||
| 	case ">PASSWORD:Verification Failed: 'Auth'": | ||||
| 	case line == ">PASSWORD:Verification Failed: 'Auth'": | ||||
| 		v.authCache = nil | ||||
| 		v.Status = "Auth Failed" | ||||
| 		return | ||||
| @ -196,20 +230,55 @@ func (v *OpenVpnSrv) NeedPassword(line string) { | ||||
| 		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)}) | ||||
| 	var cmd []string | ||||
| 	switch { | ||||
| 	case len(CRV1Match) > 1: | ||||
| 		cmd = []string{ | ||||
| 			fmt.Sprintf("username \"Auth\" %s", B64decode(CRV1Match[3])), | ||||
| 			fmt.Sprintf("password \"Auth\" CRV1::%s::%s", CRV1Match[2], v.authCache.OTP), | ||||
| 		} | ||||
| 		// restore auth backup | ||||
| 		v.authCache = backup | ||||
| 
 | ||||
| 	case len(OtpPassMatch) > 1: | ||||
| 		cmd = []string{ | ||||
| 			fmt.Sprintf("username \"Auth\" %s", v.authCache.User), | ||||
| 			fmt.Sprintf("password \"Auth\" SCRV1:%s:%s", v.B64Pass(), v.B64OTP()), | ||||
| 		} | ||||
| 	case line == ">PASSWORD:Need 'Auth' username/password": | ||||
| 		cmd = []string{ | ||||
| 			fmt.Sprintf("username \"Auth\" %s", v.authCache.User), | ||||
| 			fmt.Sprintf("password \"Auth\" %s", v.authCache.Pass), | ||||
| 		} | ||||
| 	} | ||||
| 	for _, c := range cmd { | ||||
| 		v.sendCommand([]string{c}) | ||||
| 	} | ||||
| 	v.authWait = false | ||||
| 	v.Message = "" | ||||
| 	v.Status = "Connected" | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) AuthUserPass(user, pass string) { | ||||
| 	auth := OpenVpnPassword{user, pass} | ||||
| func (v *OpenVpnSrv) AuthUserPass(user, pass, otp string) { | ||||
| 	auth := OpenVpnPassword{user, pass, otp} | ||||
| 	if v.authCache == nil { | ||||
| 		v.authCache = &auth | ||||
| 	if v.Status == "Need Password" { | ||||
| 		v.Status = "Authenticate" | ||||
| 		v.chanPass <- auth | ||||
| 	} | ||||
| 	switch v.Status { | ||||
| 	case "Need Password and OTP": | ||||
| 		v.authCache.User = user | ||||
| 		v.authCache.Pass = pass | ||||
| 		v.authCache.OTP = otp | ||||
| 	case "Need OTP": | ||||
| 		v.authCache.OTP = otp | ||||
| 	case "Need Password": | ||||
| 		v.authCache.User = user | ||||
| 		v.authCache.Pass = pass | ||||
| 	default: | ||||
| 		return | ||||
| 	} | ||||
| 	v.chanPass <- auth | ||||
| 	v.Status = "Check Password" | ||||
| } | ||||
| 
 | ||||
| func (v *OpenVpnSrv) waitForRelase() { | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										9
									
								
								utils.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								utils.go
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"math/big" | ||||
| 	"net" | ||||
| 	"sort" | ||||
| @ -8,6 +9,14 @@ import ( | ||||
| 	"github.com/pyke369/golang-support/uconfig" | ||||
| ) | ||||
| 
 | ||||
| func B64decode(s string) string { | ||||
| 	data, err := base64.StdEncoding.DecodeString(s) | ||||
| 	if err != nil { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return string(data) | ||||
| } | ||||
| 
 | ||||
| // check if there is a member of "search" in "list". sort list to be more | ||||
| // efficiant. adapt with sorting "search" too | ||||
| func inArray(search, list []string) bool { | ||||
|  | ||||
| @ -102,13 +102,13 @@ func (s *OpenVpnMgt) Restart(pid int) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (s *OpenVpnMgt) AuthUserPass(pid int, user, pass string) error { | ||||
| func (s *OpenVpnMgt) AuthUserPass(pid int, user, pass, otp string) error { | ||||
| 	// check if the session is valid | ||||
| 	err, session := s.GetSession(pid) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	session.AuthUserPass(user, pass) | ||||
| 	session.AuthUserPass(user, pass, otp) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -142,7 +142,9 @@ select.interface { | ||||
|     function auth(pid) { | ||||
|         ajax({action: "auth-user-pass", params:{session: pid, | ||||
|             user:$('#auth_'+pid+'>input.user').val(),  | ||||
|             password:$('#auth_'+pid+'>input.pass').val()}}); | ||||
|             password:$('#auth_'+pid+'>input.pass').val(), | ||||
|             otp:$('#auth_'+pid+'>input.otp').val() | ||||
|         }}); | ||||
|     } | ||||
| 
 | ||||
|     function refresh(data) { | ||||
| @ -201,11 +203,16 @@ select.interface { | ||||
|                     line += '</td>\n'; | ||||
|                     line += '</tr>\n'; | ||||
| 
 | ||||
|                     if(infos['status']=="Need Password") { | ||||
|                     if(infos['status'].startsWith("Need")) { | ||||
|                         line +='<tr><td colspan="4">'; | ||||
|                         line +='<form id="auth_'+pid+'" action="#" onsubmit="auth('+pid+') ; return false"  >'; | ||||
|                         if (infos['status'].includes("Password")) { | ||||
|                           line +='<input class="user" placeholder="Enter login" size="15">'; | ||||
|                           line +='<input type="password" placeholder="Password" size="15" class="pass">'; | ||||
|                         } | ||||
|                         if (infos['status'].includes("OTP")) { | ||||
|                           line +='<input class="otp" placeholder="'+infos["message"]+'" size="15">'; | ||||
|                         } | ||||
|                         line +='<input type="submit" value="G0">'; | ||||
|                         line +='</form>'; | ||||
|                         line +='</td></tr>\n'; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user