feat: 变更解析方式,打包Srun请求包

This commit is contained in:
Mmx233
2022-03-11 17:47:13 +08:00
parent 371e774cc1
commit 0613dc6311
13 changed files with 165 additions and 188 deletions

View File

@@ -2,7 +2,6 @@ package controllers
import ( import (
"github.com/Mmx233/BitSrunLoginGo/global" "github.com/Mmx233/BitSrunLoginGo/global"
srunModels "github.com/Mmx233/BitSrunLoginGo/models"
"github.com/Mmx233/BitSrunLoginGo/util" "github.com/Mmx233/BitSrunLoginGo/util"
"os" "os"
"os/exec" "os/exec"
@@ -13,7 +12,6 @@ import (
func Guardian(output bool) { func Guardian(output bool) {
util.Log.OutPut = output util.Log.OutPut = output
GuardianDuration := time.Duration(global.Config.Settings.Guardian.Duration) * time.Second GuardianDuration := time.Duration(global.Config.Settings.Guardian.Duration) * time.Second
util.Checker.SetUrl(global.Config.Settings.Basic.NetCheckUrl)
if global.Config.Settings.Daemon.Enable { if global.Config.Settings.Daemon.Enable {
go Daemon.DaemonChan() go Daemon.DaemonChan()
@@ -31,31 +29,16 @@ func Guardian(output bool) {
_ = recover() _ = recover()
}() }()
if global.Config.Settings.Basic.Interfaces == "" { //单网卡 if global.Config.Settings.Basic.Interfaces == "" { //单网卡
if !util.Checker.NetOk(global.Transports(nil)) { e := Login(output, nil)
util.Log.Info("检测到掉线, trying to login") if e != nil {
e := Login(output, true, nil) util.Log.Warn("登陆失败: ", e)
if e != nil {
util.Log.Warn("登陆失败: ", e)
}
} else {
if global.Config.Settings.Debug.Enable {
util.Log.Debug("Network ok")
}
} }
} else { //多网卡 } else { //多网卡
interfaces, e := util.GetInterfaceAddr() interfaces, e := util.GetInterfaceAddr()
if e == nil { if e == nil {
var down []srunModels.Eth
for _, eth := range interfaces { for _, eth := range interfaces {
if !util.Checker.NetOk(global.Transports(eth.Addr)) {
util.Log.Info("检测到掉线网口 ", eth.Name)
down = append(down, eth)
}
}
for _, eth := range down {
util.Log.Info(eth.Name) util.Log.Info(eth.Name)
e := Login(output, true, eth.Addr) e := Login(output, eth.Addr)
if e != nil { if e != nil {
util.Log.Warn("网口 ", eth.Name+" 登录失败: ", e) util.Log.Warn("网口 ", eth.Name+" 登录失败: ", e)
} }

View File

@@ -8,14 +8,12 @@ import (
) )
// Login 登录逻辑 // Login 登录逻辑
func Login(output bool, skipCheck bool, localAddr net.Addr) error { func Login(output bool, localAddr net.Addr) error {
return BitSrun.Login(&srunTransfer.Login{ return BitSrun.Login(&srunTransfer.Login{
Https: global.Config.Settings.Basic.Https, Https: global.Config.Settings.Basic.Https,
Debug: global.Config.Settings.Debug.Enable, Debug: global.Config.Settings.Debug.Enable,
WriteLog: global.Config.Settings.Debug.WriteLog, WriteLog: global.Config.Settings.Debug.WriteLog,
OutPut: output, OutPut: output,
CheckNet: !skipCheck,
CheckNetUrl: global.Config.Settings.Basic.NetCheckUrl,
LoginInfo: srunTransfer.LoginInfo{ LoginInfo: srunTransfer.LoginInfo{
Form: &global.Config.Form, Form: &global.Config.Form,
Meta: &global.Config.Meta, Meta: &global.Config.Meta,

View File

@@ -28,8 +28,7 @@ func readConfig() error {
}) })
viper.SetDefault("settings", srunModels.Settings{ viper.SetDefault("settings", srunModels.Settings{
Basic: srunModels.Basic{ Basic: srunModels.Basic{
Timeout: 5, Timeout: 5,
NetCheckUrl: "https://www.baidu.com/",
}, },
Daemon: srunModels.Daemon{ Daemon: srunModels.Daemon{
Path: ".autoLogin", Path: ".autoLogin",

View File

@@ -26,7 +26,7 @@ func main() {
} else { } else {
//单次登录模式 //单次登录模式
if global.Config.Settings.Basic.Interfaces == "" { //单网卡 if global.Config.Settings.Basic.Interfaces == "" { //单网卡
if err := controllers.Login(true, global.Config.Settings.Basic.SkipNetCheck, nil); err != nil { if err := controllers.Login(true, nil); err != nil {
util.Log.Fatal("运行出错,状态异常: ", err) util.Log.Fatal("运行出错,状态异常: ", err)
} }
} else { //多网卡 } else { //多网卡
@@ -34,7 +34,7 @@ func main() {
interfaces, _ := util.GetInterfaceAddr() interfaces, _ := util.GetInterfaceAddr()
for _, eth := range interfaces { for _, eth := range interfaces {
util.Log.Info("网卡: ", eth.Name) util.Log.Info("网卡: ", eth.Name)
if err := controllers.Login(true, global.Config.Settings.Basic.SkipNetCheck, eth.Addr); err != nil { if err := controllers.Login(true, eth.Addr); err != nil {
util.Log.Warn("运行出错,状态异常: ", err) util.Log.Warn("运行出错,状态异常: ", err)
} }
} }

View File

@@ -17,8 +17,6 @@ type Basic struct {
SkipCertVerify bool `json:"skip_cert_verify" yaml:"skip_cert_verify" mapstructure:"skip_cert_verify"` SkipCertVerify bool `json:"skip_cert_verify" yaml:"skip_cert_verify" mapstructure:"skip_cert_verify"`
Timeout uint `json:"timeout" yaml:"timeout" mapstructure:"timeout"` Timeout uint `json:"timeout" yaml:"timeout" mapstructure:"timeout"`
Interfaces string `json:"interfaces" yaml:"interfaces" mapstructure:"interfaces"` Interfaces string `json:"interfaces" yaml:"interfaces" mapstructure:"interfaces"`
SkipNetCheck bool `json:"skip_net_check" yaml:"skip_net_check" mapstructure:"skip_net_check"`
NetCheckUrl string `json:"net_check_url" yaml:"net_check_url" mapstructure:"net_check_url"`
} }
type Settings struct { type Settings struct {

View File

@@ -3,11 +3,6 @@ package srunModels
import "github.com/Mmx233/BitSrunLoginGo/v1/transfer" import "github.com/Mmx233/BitSrunLoginGo/v1/transfer"
type LoginInfo struct { type LoginInfo struct {
UrlLoginPage string
UrlGetChallengeApi string
UrlLoginApi string
UrlCheckApi string
Ip string Ip string
Token string Token string
EncryptedInfo string EncryptedInfo string

View File

@@ -1,39 +0,0 @@
package util
import (
"github.com/Mmx233/tool"
"net/http"
)
type checker struct {
url string
set bool
}
var Checker = checker{
url: "https://www.baidu.com/",
}
func (a *checker) SetUrl(url string) {
if a.set {
return
}
a.url = url
a.set = true
}
// NetOk 网络状况检查
func (a *checker) NetOk(transport *http.Transport) bool {
Log.Debug("GET ", a.url)
res, e := tool.HTTP.GetReader(&tool.GetRequest{
Url: a.url,
Redirect: false,
Transport: transport,
})
if e != nil {
Log.Debug(e)
return false
}
_ = res.Body.Close()
return res.Header.Get("Location") == ""
}

View File

@@ -5,18 +5,9 @@ import (
"github.com/Mmx233/BitSrunLoginGo/v1/transfer" "github.com/Mmx233/BitSrunLoginGo/v1/transfer"
) )
func GenerateLoginInfo(https bool, Form *srunTransfer.LoginForm, Meta *srunTransfer.LoginMeta) *srunModels.LoginInfo { func GenerateLoginInfo(Form *srunTransfer.LoginForm, Meta *srunTransfer.LoginMeta) *srunModels.LoginInfo {
portal := "http"
if https {
portal += "s"
}
portal += "://"
return &srunModels.LoginInfo{ return &srunModels.LoginInfo{
UrlLoginPage: portal + Form.Domain + "/srun_portal_success", Meta: Meta,
UrlGetChallengeApi: portal + Form.Domain + "/cgi-bin/get_challenge",
UrlLoginApi: portal + Form.Domain + "/cgi-bin/srun_portal",
UrlCheckApi: portal + Form.Domain + "/cgi-bin/rad_user_info",
Meta: Meta,
Form: &srunTransfer.LoginForm{ Form: &srunTransfer.LoginForm{
UserName: Form.UserName + "@" + Form.UserType, UserName: Form.UserName + "@" + Form.UserType,
PassWord: Form.PassWord, PassWord: Form.PassWord,

View File

@@ -3,43 +3,10 @@ package util
import ( import (
"crypto/md5" "crypto/md5"
"crypto/sha1" "crypto/sha1"
"errors"
"fmt" "fmt"
"io" "io"
"regexp"
) )
func Search(reg string, content string) (string, error) {
r := regexp.MustCompile(reg)
if r == nil {
return "", errors.New("解析正则表达式失败")
}
if s := r.FindStringSubmatch(content); len(s) < 2 {
return "", errors.New("无匹配")
} else {
return s[1], nil
}
}
// GetIp 从响应获取本机分配到的IP
func GetIp(body string) (string, error) {
//判断原正则是否有匹配,如果无就使用新正则尝试
if ip, e := Search("id=\"user_ip\" value=\"(.*?)\"", body); e == nil {
return ip, nil
}
return Search("ip : \"(.*?)\"", body)
}
// GetToken 从响应获取token
func GetToken(body string) (string, error) {
return Search("\"challenge\":\"(.*?)\"", body)
}
// GetResult 从响应获取登录结果
func GetResult(body string) (string, error) {
return Search("\"error\":\"(.+?)\"", body)
}
// Md5 编码 // Md5 编码
func Md5(content string) string { func Md5(content string) string {
w := md5.New() w := md5.New()

7
v1/errors.go Normal file
View File

@@ -0,0 +1,7 @@
package BitSrun
import "errors"
var (
ErrResultCannotFound = errors.New("result cannot found from response")
)

View File

@@ -5,8 +5,6 @@ import (
"errors" "errors"
"github.com/Mmx233/BitSrunLoginGo/util" "github.com/Mmx233/BitSrunLoginGo/util"
"github.com/Mmx233/BitSrunLoginGo/v1/transfer" "github.com/Mmx233/BitSrunLoginGo/v1/transfer"
"github.com/Mmx233/tool"
"time"
) )
func Login(c *srunTransfer.Login) error { func Login(c *srunTransfer.Login) error {
@@ -14,54 +12,61 @@ func Login(c *srunTransfer.Login) error {
util.Log.WriteFile = c.WriteLog util.Log.WriteFile = c.WriteLog
util.Log.OutPut = c.OutPut util.Log.OutPut = c.OutPut
G := util.GenerateLoginInfo(c.Https, c.LoginInfo.Form, c.LoginInfo.Meta) G := util.GenerateLoginInfo(c.LoginInfo.Form, c.LoginInfo.Meta)
if c.CheckNet { api := SrunApi{
if c.CheckNetUrl != "" { BaseUrl: func() string {
util.Checker.SetUrl(c.CheckNetUrl) url := "http"
} if c.Https {
util.Log.Info("Step0: 检查状态…") url += "s"
if util.Checker.NetOk(c.Transport) { }
util.Log.Info("网络 ok") return url + "://" + c.LoginInfo.Form.Domain + "/"
return nil }(),
} Transport: c.Transport,
} }
util.Log.Info("Step1: 正在获取客户端ip") var ok bool
{ {
util.Log.Debug("GET ", G.UrlLoginPage) util.Log.Info("Step.0: 正在检查状态")
if _, body, e := tool.HTTP.GetString(&tool.GetRequest{ res, e := api.GetUserInfo()
Url: G.UrlLoginPage, if e != nil {
Redirect: true,
Transport: c.Transport,
}); e != nil {
return e
} else if G.Ip, e = util.GetIp(body); e != nil {
return e return e
} }
err := res["error"].(string)
if err == "ok" {
util.Log.Info("--已登录--")
return nil
}
util.Log.Info("Step.1: 正在获取客户端ip")
var ip interface{}
ip, ok = res["client_ip"]
if !ok {
ip, ok = res["online_ip"]
if !ok {
return ErrResultCannotFound
}
}
G.Ip = ip.(string)
util.Log.Debug("ip: ", G.Ip) util.Log.Debug("ip: ", G.Ip)
} }
util.Log.Info("Step2: 正在获取token") util.Log.Info("Step.2: 正在获取token")
{ {
util.Log.Debug("GET ", G.UrlGetChallengeApi) res, e := api.GetChallenge(G.Form.UserName, G.Ip)
if _, data, e := tool.HTTP.GetString(&tool.GetRequest{ if e != nil {
Url: G.UrlGetChallengeApi,
Query: map[string]interface{}{
"callback": "jsonp1583251661367",
"username": G.Form.UserName,
"ip": G.Ip,
},
Redirect: true,
Transport: c.Transport,
}); e != nil {
return e
} else if G.Token, e = util.GetToken(data); e != nil {
return e return e
} }
var token interface{}
token, ok = res["challenge"]
if !ok {
return ErrResultCannotFound
}
G.Token = token.(string)
util.Log.Debug("token: ", G.Token) util.Log.Debug("token: ", G.Token)
} }
util.Log.Info("Step3: 执行登录…") util.Log.Info("Step.3: 执行登录…")
{ {
info, e := json.Marshal(map[string]string{ info, e := json.Marshal(map[string]string{
"username": G.Form.UserName, "username": G.Form.UserName,
@@ -83,36 +88,27 @@ func Login(c *srunTransfer.Login) error {
chkstr += G.Token + G.EncryptedInfo chkstr += G.Token + G.EncryptedInfo
G.EncryptedChkstr = util.Sha1(chkstr) G.EncryptedChkstr = util.Sha1(chkstr)
util.Log.Debug("GET ", G.UrlLoginApi) res, e := api.Login(
if _, res, e := tool.HTTP.GetString(&tool.GetRequest{ G.Form.UserName,
Url: G.UrlLoginApi, G.EncryptedMd5,
Query: map[string]interface{}{ G.Meta.Acid,
"callback": "jQuery112401157665", G.Ip,
"action": "login", G.EncryptedInfo,
"username": G.Form.UserName, G.EncryptedChkstr,
"password": G.EncryptedMd5, G.Meta.N,
"ac_id": G.Meta.Acid, G.Meta.Type,
"ip": G.Ip, )
"info": G.EncryptedInfo, if e != nil {
"chksum": G.EncryptedChkstr,
"n": G.Meta.N,
"type": G.Meta.Type,
"os": "Windows 10",
"name": "windows",
"double_stack": 0,
"_": time.Now().UnixNano(),
},
Redirect: true,
Transport: c.Transport,
}); e != nil {
return e return e
} else if G.LoginResult, e = util.GetResult(res); e != nil {
return e
} else {
util.Log.Info("登录结果: " + G.LoginResult)
util.Log.Debug(res)
} }
var result interface{}
result, ok = res["error"]
if !ok {
return ErrResultCannotFound
}
G.LoginResult = result.(string)
util.Log.Info("登录结果: " + G.LoginResult)
if G.LoginResult != "ok" { if G.LoginResult != "ok" {
return errors.New(G.LoginResult) return errors.New(G.LoginResult)
} }

85
v1/steps.go Normal file
View File

@@ -0,0 +1,85 @@
package BitSrun
import (
"encoding/json"
"fmt"
"github.com/Mmx233/BitSrunLoginGo/util"
"github.com/Mmx233/tool"
"net/http"
"strings"
"time"
)
type SrunApi struct {
BaseUrl string
Transport *http.Transport
}
func (a *SrunApi) request(path string, query map[string]interface{}) (map[string]interface{}, error) {
util.Log.Debug("HTTP GET ", a.BaseUrl+path)
timestamp := fmt.Sprint(time.Now().UnixNano())
callback := "jQuery" + timestamp
if query == nil {
query = make(map[string]interface{}, 2)
}
query["callback"] = callback
query["_"] = timestamp
_, res, e := tool.HTTP.GetString(&tool.GetRequest{
Url: a.BaseUrl + path,
Query: query,
Redirect: true,
Transport: a.Transport,
})
if e != nil {
util.Log.Debug(e)
return nil, e
}
util.Log.Debug(res)
res = strings.TrimPrefix(res, callback+"(")
res = strings.TrimSuffix(res, ")")
var r map[string]interface{}
return r, json.Unmarshal([]byte(res), &r)
}
func (a *SrunApi) GetUserInfo() (map[string]interface{}, error) {
return a.request("cgi-bin/rad_user_info", nil)
}
func (a *SrunApi) Login(
Username,
Password,
AcID,
Ip,
Info,
ChkSum,
N,
Type string,
) (map[string]interface{}, error) {
return a.request(
"cgi-bin/srun_portal",
map[string]interface{}{
"action": "login",
"username": Username,
"password": Password,
"ac_id": AcID,
"ip": Ip,
"info": Info,
"chksum": ChkSum,
"n": N,
"type": Type,
"os": "Windows 10",
"name": "windows",
"double_stack": 0,
})
}
func (a *SrunApi) GetChallenge(username, ip string) (map[string]interface{}, error) {
return a.request(
"cgi-bin/get_challenge",
map[string]interface{}{
"username": username,
"ip": ip,
})
}

View File

@@ -30,9 +30,6 @@ type Login struct {
WriteLog bool WriteLog bool
//控制台日志打印开关 //控制台日志打印开关
OutPut bool OutPut bool
//登陆前是否检查网络,只在离线时登录
CheckNet bool
CheckNetUrl string
//登录参数,不可缺省 //登录参数,不可缺省
LoginInfo LoginInfo LoginInfo LoginInfo
Transport *http.Transport Transport *http.Transport