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

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ func main() {
} else {
//单次登录模式
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)
}
} else { //多网卡
@@ -34,7 +34,7 @@ func main() {
interfaces, _ := util.GetInterfaceAddr()
for _, eth := range interfaces {
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)
}
}

View File

@@ -17,8 +17,6 @@ type Basic struct {
SkipCertVerify bool `json:"skip_cert_verify" yaml:"skip_cert_verify" mapstructure:"skip_cert_verify"`
Timeout uint `json:"timeout" yaml:"timeout" mapstructure:"timeout"`
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 {

View File

@@ -3,11 +3,6 @@ package srunModels
import "github.com/Mmx233/BitSrunLoginGo/v1/transfer"
type LoginInfo struct {
UrlLoginPage string
UrlGetChallengeApi string
UrlLoginApi string
UrlCheckApi string
Ip string
Token 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"
)
func GenerateLoginInfo(https bool, Form *srunTransfer.LoginForm, Meta *srunTransfer.LoginMeta) *srunModels.LoginInfo {
portal := "http"
if https {
portal += "s"
}
portal += "://"
func GenerateLoginInfo(Form *srunTransfer.LoginForm, Meta *srunTransfer.LoginMeta) *srunModels.LoginInfo {
return &srunModels.LoginInfo{
UrlLoginPage: portal + Form.Domain + "/srun_portal_success",
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,
Meta: Meta,
Form: &srunTransfer.LoginForm{
UserName: Form.UserName + "@" + Form.UserType,
PassWord: Form.PassWord,

View File

@@ -3,43 +3,10 @@ package util
import (
"crypto/md5"
"crypto/sha1"
"errors"
"fmt"
"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 编码
func Md5(content string) string {
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"
"github.com/Mmx233/BitSrunLoginGo/util"
"github.com/Mmx233/BitSrunLoginGo/v1/transfer"
"github.com/Mmx233/tool"
"time"
)
func Login(c *srunTransfer.Login) error {
@@ -14,54 +12,61 @@ func Login(c *srunTransfer.Login) error {
util.Log.WriteFile = c.WriteLog
util.Log.OutPut = c.OutPut
G := util.GenerateLoginInfo(c.Https, c.LoginInfo.Form, c.LoginInfo.Meta)
if c.CheckNet {
if c.CheckNetUrl != "" {
util.Checker.SetUrl(c.CheckNetUrl)
}
util.Log.Info("Step0: 检查状态…")
if util.Checker.NetOk(c.Transport) {
util.Log.Info("网络 ok")
return nil
}
G := util.GenerateLoginInfo(c.LoginInfo.Form, c.LoginInfo.Meta)
api := SrunApi{
BaseUrl: func() string {
url := "http"
if c.Https {
url += "s"
}
return url + "://" + c.LoginInfo.Form.Domain + "/"
}(),
Transport: c.Transport,
}
util.Log.Info("Step1: 正在获取客户端ip")
var ok bool
{
util.Log.Debug("GET ", G.UrlLoginPage)
if _, body, e := tool.HTTP.GetString(&tool.GetRequest{
Url: G.UrlLoginPage,
Redirect: true,
Transport: c.Transport,
}); e != nil {
return e
} else if G.Ip, e = util.GetIp(body); e != nil {
util.Log.Info("Step.0: 正在检查状态")
res, e := api.GetUserInfo()
if e != nil {
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.Info("Step2: 正在获取token")
util.Log.Info("Step.2: 正在获取token")
{
util.Log.Debug("GET ", G.UrlGetChallengeApi)
if _, data, e := tool.HTTP.GetString(&tool.GetRequest{
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 {
res, e := api.GetChallenge(G.Form.UserName, G.Ip)
if e != nil {
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.Info("Step3: 执行登录…")
util.Log.Info("Step.3: 执行登录…")
{
info, e := json.Marshal(map[string]string{
"username": G.Form.UserName,
@@ -83,36 +88,27 @@ func Login(c *srunTransfer.Login) error {
chkstr += G.Token + G.EncryptedInfo
G.EncryptedChkstr = util.Sha1(chkstr)
util.Log.Debug("GET ", G.UrlLoginApi)
if _, res, e := tool.HTTP.GetString(&tool.GetRequest{
Url: G.UrlLoginApi,
Query: map[string]interface{}{
"callback": "jQuery112401157665",
"action": "login",
"username": G.Form.UserName,
"password": G.EncryptedMd5,
"ac_id": G.Meta.Acid,
"ip": G.Ip,
"info": G.EncryptedInfo,
"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 {
res, e := api.Login(
G.Form.UserName,
G.EncryptedMd5,
G.Meta.Acid,
G.Ip,
G.EncryptedInfo,
G.EncryptedChkstr,
G.Meta.N,
G.Meta.Type,
)
if e != nil {
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" {
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
//控制台日志打印开关
OutPut bool
//登陆前是否检查网络,只在离线时登录
CheckNet bool
CheckNetUrl string
//登录参数,不可缺省
LoginInfo LoginInfo
Transport *http.Transport