mirror of
https://github.com/lyc8503/EasierConnect.git
synced 2025-12-24 12:57:54 +08:00
Compare commits
10 Commits
TestBuild9
...
TestBuild1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ff2625dd1 | ||
|
|
81319fde97 | ||
|
|
ff60f05a31 | ||
|
|
7a1dc42607 | ||
|
|
4a365b628b | ||
|
|
a3121efaf2 | ||
|
|
4097d0ae7a | ||
|
|
1696b74763 | ||
|
|
fd0217e446 | ||
|
|
a7fa8c3656 |
@@ -56,6 +56,19 @@ func (client *EasyConnectClient) AuthSMSCode(code string) ([]byte, error) {
|
||||
return client.LoginByTwfId(twfId)
|
||||
}
|
||||
|
||||
func (client *EasyConnectClient) AuthTOTP(code string) ([]byte, error) {
|
||||
if client.twfId == "" {
|
||||
return nil, errors.New("TOTP Auth not required")
|
||||
}
|
||||
|
||||
twfId, err := TOTPAuth(client.server, client.username, client.password, client.twfId, code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.LoginByTwfId(twfId)
|
||||
}
|
||||
|
||||
func (client *EasyConnectClient) LoginByTwfId(twfId string) ([]byte, error) {
|
||||
agentToken, err := ECAgentToken(client.server, twfId)
|
||||
if err != nil {
|
||||
|
||||
@@ -168,7 +168,7 @@ func BlockTXStream(server string, token *[48]byte, ipRev *[4]byte, ep *EasyConne
|
||||
errCh := make(chan error)
|
||||
|
||||
ep.OnRecv = func(buf []byte) {
|
||||
n, err = conn.Write(buf)
|
||||
var n, err = conn.Write(buf)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
|
||||
@@ -20,7 +20,8 @@ import (
|
||||
utls "github.com/refraction-networking/utls"
|
||||
)
|
||||
|
||||
var ERR_NEXT_AUTH_SMS = errors.New("SMS Code required.")
|
||||
var ERR_NEXT_AUTH_SMS = errors.New("SMS Code required")
|
||||
var ERR_NEXT_AUTH_TOTP = errors.New("Current user's TOTP bound")
|
||||
|
||||
func WebLogin(server string, username string, password string) (string, error) {
|
||||
server = "https://" + server
|
||||
@@ -50,7 +51,14 @@ func WebLogin(server string, username string, password string) (string, error) {
|
||||
rsaKey := string(regexp.MustCompile(`<RSA_ENCRYPT_KEY>(.*)</RSA_ENCRYPT_KEY>`).FindSubmatch(buf[:n])[1])
|
||||
log.Printf("RSA Key: %s", rsaKey)
|
||||
|
||||
rsaExp := string(regexp.MustCompile(`<RSA_ENCRYPT_EXP>(.*)</RSA_ENCRYPT_EXP>`).FindSubmatch(buf[:n])[1])
|
||||
rsaExpMatch := regexp.MustCompile(`<RSA_ENCRYPT_EXP>(.*)</RSA_ENCRYPT_EXP>`).FindSubmatch(buf[:n])
|
||||
rsaExp := ""
|
||||
if rsaExpMatch != nil {
|
||||
rsaExp = string(rsaExpMatch[1])
|
||||
} else {
|
||||
log.Printf("Warning: No RSA_ENCRYPT_EXP, using default.")
|
||||
rsaExp = "65537"
|
||||
}
|
||||
log.Printf("RSA Exp: %s", rsaExp)
|
||||
|
||||
csrfMatch := regexp.MustCompile(`<CSRF_RAND_CODE>(.*)</CSRF_RAND_CODE>`).FindSubmatch(buf[:n])
|
||||
@@ -104,7 +112,7 @@ func WebLogin(server string, username string, password string) (string, error) {
|
||||
// log.Printf("First stage login response: %s", string(buf[:n]))
|
||||
|
||||
// SMS Code Process
|
||||
if strings.Contains(string(buf[:n]), "<NextService>auth/sms</NextService>") {
|
||||
if strings.Contains(string(buf[:n]), "<NextService>auth/sms</NextService>") || strings.Contains(string(buf[:n]), "<NextAuth>2</NextAuth>") {
|
||||
log.Print("SMS code required.")
|
||||
|
||||
addr = server + "/por/login_sms.csp?apiversion=1"
|
||||
@@ -121,7 +129,7 @@ func WebLogin(server string, username string, password string) (string, error) {
|
||||
n, _ := resp.Body.Read(buf)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if !strings.Contains(string(buf[:n]), "验证码已发送到您的手机") {
|
||||
if !strings.Contains(string(buf[:n]), "验证码已发送到您的手机") && !strings.Contains(string(buf[:n]), "<USER_PHONE>") {
|
||||
debug.PrintStack()
|
||||
return "", errors.New("unexpected sms resp: " + string(buf[:n]))
|
||||
}
|
||||
@@ -131,6 +139,12 @@ func WebLogin(server string, username string, password string) (string, error) {
|
||||
return twfId, ERR_NEXT_AUTH_SMS
|
||||
}
|
||||
|
||||
// TOTP Authnication Process (Edited by JHong)
|
||||
if strings.Contains(string(buf[:n]), "<NextService>auth/token</NextService>") || strings.Contains(string(buf[:n]), "<NextServiceSubType>totp</NextServiceSubType>") {
|
||||
log.Print("TOTP Authnication required.")
|
||||
return twfId, ERR_NEXT_AUTH_TOTP
|
||||
}
|
||||
|
||||
if strings.Contains(string(buf[:n]), "<NextAuth>-1</NextAuth>") || !strings.Contains(string(buf[:n]), "<NextAuth>") {
|
||||
log.Print("No NextAuth found.")
|
||||
} else {
|
||||
@@ -191,6 +205,44 @@ func AuthSms(server string, username string, password string, twfId string, smsC
|
||||
return twfId, nil
|
||||
}
|
||||
|
||||
// JHong Implementing.......
|
||||
func TOTPAuth(server string, username string, password string, twfId string, TOTPCode string) (string, error) {
|
||||
c := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}}
|
||||
|
||||
buf := make([]byte, 40960)
|
||||
|
||||
addr := "https://" + server + "/por/login_token.csp"
|
||||
log.Printf("TOTP token Request: " + addr)
|
||||
form := url.Values{
|
||||
"svpn_inputtoken": {TOTPCode},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", addr, strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Cookie", "TWFID="+twfId)
|
||||
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
debug.PrintStack()
|
||||
return "", err
|
||||
}
|
||||
|
||||
n, _ := resp.Body.Read(buf)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if !strings.Contains(string(buf[:n]), "suc") {
|
||||
debug.PrintStack()
|
||||
return "", errors.New("TOTP token verification FAILED: " + string(buf[:n]))
|
||||
}
|
||||
|
||||
twfId = string(regexp.MustCompile(`<TwfID>(.*)</TwfID>`).FindSubmatch(buf[:n])[1])
|
||||
log.Print("TOTP verification SUCCESS")
|
||||
|
||||
return twfId, nil
|
||||
}
|
||||
|
||||
func ECAgentToken(server string, twfId string) (string, error) {
|
||||
dialConn, err := net.Dial("tcp", server)
|
||||
defer dialConn.Close()
|
||||
|
||||
11
main.go
11
main.go
@@ -5,12 +5,13 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// CLI args
|
||||
host, port, username, password, socksBind, twfId := "", 0, "", "", "", ""
|
||||
flag.StringVar(&host, "server", "", "EasyConnect server address (e.g. vpn.nju.edu.cn)")
|
||||
flag.StringVar(&host, "server", "", "EasyConnect server address (e.g. vpn.nju.edu.cn, sslvpn.sysu.edu.cn)")
|
||||
flag.StringVar(&username, "username", "", "Your username")
|
||||
flag.StringVar(&password, "password", "", "Your password")
|
||||
flag.StringVar(&socksBind, "socks-bind", ":1080", "The addr socks5 server listens on (e.g. 0.0.0.0:1080)")
|
||||
@@ -42,6 +43,12 @@ func main() {
|
||||
fmt.Scan(&smsCode)
|
||||
|
||||
ip, err = client.AuthSMSCode(smsCode)
|
||||
} else if err == core.ERR_NEXT_AUTH_TOTP {
|
||||
fmt.Print(">>>Please enter your TOTP Auth code<<<:")
|
||||
TOTPCode := ""
|
||||
fmt.Scan(&TOTPCode)
|
||||
|
||||
ip, err = client.AuthTOTP(TOTPCode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +58,6 @@ func main() {
|
||||
log.Printf("Login success, your IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
|
||||
|
||||
client.ServeSocks5(socksBind, debugDump)
|
||||
|
||||
runtime.KeepAlive(client)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user