feat: 变更解析方式,打包Srun请求包
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
4
main.go
4
main.go
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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") == ""
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
33
util/util.go
33
util/util.go
@@ -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
7
v1/errors.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package BitSrun
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrResultCannotFound = errors.New("result cannot found from response")
|
||||
)
|
||||
122
v1/login.go
122
v1/login.go
@@ -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
85
v1/steps.go
Normal 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,
|
||||
})
|
||||
}
|
||||
@@ -30,9 +30,6 @@ type Login struct {
|
||||
WriteLog bool
|
||||
//控制台日志打印开关
|
||||
OutPut bool
|
||||
//登陆前是否检查网络,只在离线时登录
|
||||
CheckNet bool
|
||||
CheckNetUrl string
|
||||
//登录参数,不可缺省
|
||||
LoginInfo LoginInfo
|
||||
Transport *http.Transport
|
||||
|
||||
Reference in New Issue
Block a user