diff --git a/.gitignore b/.gitignore index 62c8935..b905fba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -.idea/ \ No newline at end of file +.idea/ +Mmx +Config.json \ No newline at end of file diff --git a/Modles/config.go b/Modles/config.go new file mode 100644 index 0000000..1ce15a8 --- /dev/null +++ b/Modles/config.go @@ -0,0 +1,6 @@ +package Modles + +type Config struct { + From LoginForm + Meta LoginMeta +} diff --git a/Modles/login.go b/Modles/login.go new file mode 100644 index 0000000..4ee5dda --- /dev/null +++ b/Modles/login.go @@ -0,0 +1,31 @@ +package Modles + +type LoginForm struct { + Domain string `json:"domain"` + UserName string `json:"username"` + PassWord string `json:"password"` +} + +type LoginMeta struct { + N string `json:"n"` + VType string `json:"v_type"` + Acid string `json:"acid"` + Enc string `json:"enc"` +} + +type LoginInfo struct { + UrlLoginPage string + UrlGetChallengeApi string + UrlLoginApi string + + Ip string + Token string + EncryptedInfo string + Md5 string + EncryptedMd5 string + EncryptedChkstr string + LoginResult string + + Form *LoginForm + Meta *LoginMeta +} diff --git a/README.md b/README.md index a9f2010..1626fca 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # BitSrunLoginGo + NCU移动深澜校园网登录脚本Go语言版 在main函数中填入账号密码和登录地址ip即可 diff --git a/Util/XBase64.go b/Util/XBase64.go index e0220f6..f41049f 100644 --- a/Util/XBase64.go +++ b/Util/XBase64.go @@ -5,7 +5,7 @@ import ( "os" ) -func getbyte(a byte)int{ +func getbyte(a byte) int { x := int(a) if x > 255 { fmt.Println("INVALID_CHARACTER_ERR: DOM Exception 5") @@ -14,30 +14,30 @@ func getbyte(a byte)int{ return x } -func Base64(s []byte)string{ +func Base64(s []byte) string { const ALPHA = "LVoJPiCN2R8G90yg+hmFHuacZ1OWMnrsSTXkYpUq/3dlbfKwv6xztjI7DeBE45QA" const PADCHAR = "=" - i:=0 - b10:=0 + i := 0 + b10 := 0 var x []byte - imax:=len(s)-len(s)%3 - if len(s)==0{ + imax := len(s) - len(s)%3 + if len(s) == 0 { return "" } - for i:=0;i>18)]) - x=append(x,ALPHA[((b10 >> 12) & 63)]) - x=append(x,ALPHA[((b10 >> 6) & 63)]) - x=append(x,ALPHA[(b10 & 63)]) + for i := 0; i < imax; i += 3 { + b10 = (getbyte(s[i]) << 16) | (getbyte(s[i+1]) << 8) | (getbyte(s[i+2])) + x = append(x, ALPHA[(b10>>18)]) + x = append(x, ALPHA[((b10>>12)&63)]) + x = append(x, ALPHA[((b10>>6)&63)]) + x = append(x, ALPHA[(b10&63)]) } - i=imax - if len(s)-imax==1{ - b10=getbyte(s[i])<<16 - x=append(x,ALPHA[(b10 >> 18)],ALPHA[((b10 >> 12) & 63)],PADCHAR[0],PADCHAR[0]) - }else if len(s)-imax ==2{ - b10=(getbyte(s[i])<<16)|(getbyte(s[i+1])<<8) - x=append(x,ALPHA[(b10 >> 18)],ALPHA[((b10 >> 12) & 63)],ALPHA[((b10 >> 6) & 63)],PADCHAR[0]) + i = imax + if len(s)-imax == 1 { + b10 = getbyte(s[i]) << 16 + x = append(x, ALPHA[(b10>>18)], ALPHA[((b10>>12)&63)], PADCHAR[0], PADCHAR[0]) + } else if len(s)-imax == 2 { + b10 = (getbyte(s[i]) << 16) | (getbyte(s[i+1]) << 8) + x = append(x, ALPHA[(b10>>18)], ALPHA[((b10>>12)&63)], ALPHA[((b10>>6)&63)], PADCHAR[0]) } return string(x) -} \ No newline at end of file +} diff --git a/Util/Xencode.go b/Util/XEncode.go similarity index 94% rename from Util/Xencode.go rename to Util/XEncode.go index 9e63c27..2ec94ec 100644 --- a/Util/Xencode.go +++ b/Util/XEncode.go @@ -38,7 +38,7 @@ func lenCode(msg []uint32, key bool) []byte { } var t []byte for i := range msg { - t = append(t, byte(msg[i]&0xff),byte(msg[i]>>8&0xff),byte(msg[i]>>16&0xff),byte(msg[i]>>24&0xff)) + t = append(t, byte(msg[i]&0xff), byte(msg[i]>>8&0xff), byte(msg[i]>>16&0xff), byte(msg[i]>>24&0xff)) } if key { return t[0:ll] diff --git a/Util/checker.go b/Util/checker.go new file mode 100644 index 0000000..63155e4 --- /dev/null +++ b/Util/checker.go @@ -0,0 +1,20 @@ +package Util + +import ( + "fmt" + "net" +) + +type checker struct{} + +var Checker checker + +func (checker) NetOk() bool { + if ip, err := net.LookupIP("www.msftconnecttest.com"); err != nil { + fmt.Println("a") + return false + } else if len(ip) == 0 || ip[0].String() != "13.107.4.52" { + return false + } + return true +} diff --git a/Util/config.go b/Util/config.go new file mode 100644 index 0000000..beb8fcc --- /dev/null +++ b/Util/config.go @@ -0,0 +1,62 @@ +package Util + +import ( + "Mmx/Modles" + "fmt" + "os" +) + +type config struct { + Path string +} + +var Config = config{ + Path: "Config.json", +} + +func (*config) Generate(Form *Modles.LoginForm, Meta *Modles.LoginMeta) *Modles.LoginInfo { + return &Modles.LoginInfo{ + UrlLoginPage: "http://" + Form.Domain + "/srun_portal_success", + UrlGetChallengeApi: "http://" + Form.Domain + "/cgi-bin/get_challenge", + UrlLoginApi: "http://" + Form.Domain + "/cgi-bin/srun_portal", + Meta: Meta, + Form: &Modles.LoginForm{ + UserName: Form.UserName + "@cmcc", + PassWord: Form.PassWord, + }, + } +} + +func (a *config) Init() *Modles.LoginInfo { + if !File.Exists(a.Path) { + if err := File.Write(a.Path, &Modles.Config{ //默认值 + From: Modles.LoginForm{ + Domain: "www.msftconnecttest.com", + UserName: "", + PassWord: "", + }, + Meta: Modles.LoginMeta{ + N: "200", + VType: "1", + Acid: "5", + Enc: "srun_bx1", + }, + }); err != nil { + fmt.Println("Create 'Config.json' error:\n", err.Error()) + os.Exit(3) + } + fmt.Println("Please edit 'Config.json' and try again.") + os.Exit(1) + } + + var c Modles.Config + if err := File.Read(a.Path, &c); err != nil { + fmt.Println("Read config failed:\n", err.Error()) + os.Exit(3) + } + + return a.Generate( + &c.From, + &c.Meta, + ) +} diff --git a/Util/file.go b/Util/file.go new file mode 100644 index 0000000..c2e642e --- /dev/null +++ b/Util/file.go @@ -0,0 +1,39 @@ +package Util + +import ( + "encoding/json" + "io/ioutil" + "os" +) + +type file struct { +} + +var File file + +func (*file) Exists(path string) bool { + _, err := os.Stat(path) + if err != nil { + if os.IsExist(err) { + return true + } + return false + } + return true +} + +func (*file) Read(path string, receiver interface{}) error { + file, err := ioutil.ReadFile(path) + if err != nil { + return err + } + return json.Unmarshal(file, receiver) +} + +func (*file) Write(path string, receiver interface{}) error { + data, err := json.MarshalIndent(receiver, "", " ") + if err != nil { + return err + } + return ioutil.WriteFile(path, data, 777) +} diff --git a/Util/util.go b/Util/util.go index 52d0736..0b267b2 100644 --- a/Util/util.go +++ b/Util/util.go @@ -26,11 +26,11 @@ func GetIp(body string) (string, error) { } func GetToken(body string) (string, error) { - return Search("\"challenge\":\"(.*?)\"",body) + return Search("\"challenge\":\"(.*?)\"", body) } -func GetResult(body string)(string,error){ - return Search("\"error\":\"(.+?)\"",body) +func GetResult(body string) (string, error) { + return Search("\"error\":\"(.+?)\"", body) } func Md5(content string) string { @@ -39,9 +39,9 @@ func Md5(content string) string { return fmt.Sprintf("%x", w.Sum(nil)) //w.Sum(nil)将w的hash转成[]byte格式 } -func Sha1(content string)string{ +func Sha1(content string) string { h := sha1.New() h.Write([]byte(content)) bs := h.Sum(nil) return fmt.Sprintf("%x\n", bs) -} \ No newline at end of file +} diff --git a/main.go b/main.go index ab54a12..592ae3f 100644 --- a/main.go +++ b/main.go @@ -5,63 +5,23 @@ import ( "Mmx/Util" "encoding/json" "fmt" - "os" ) -type LoginForm struct { - UserName string - PassWord string -} - -type LoginInfo struct { - UrlLoginPage string - UrlGetChallengeApi string - UrlLoginApi string - N string - VType string - Acid string - Enc string - - Ip string - Token string - EncryptedInfo string - Md5 string - EncryptedMd5 string - EncryptedChkstr string - LoginResult string - Form *LoginForm -} - -func Generate(Domain string, Username string, Password string) *LoginInfo { - return &LoginInfo{ - UrlLoginPage: "http://" + Domain + "/srun_portal_success?ac_id=5&theme=basic1", - UrlGetChallengeApi: "http://" + Domain + "/cgi-bin/get_challenge", - UrlLoginApi: "http://" + Domain + "/cgi-bin/srun_portal", - N: "200", - VType: "1", - Acid: "5", - Enc: "srun_bx1", - Form: &LoginForm{ - UserName: Username + "@cmcc", - PassWord: Password, - }, - } -} - func ErrHandler(err error) { if err != nil { - defer os.Exit(3) - fmt.Println("Error") + fmt.Println("Error occurred") panic(err) } } func main() { - G := Generate( - "", //登录地址域名或ip - "", //账号 - "", //密码 - ) + if Util.Checker.NetOk() { + fmt.Println("There's no need to login") + return + } + + G := Util.Config.Init() + fmt.Println("Step1: Get local ip returned from srun server.") { body, err := Request.Get(G.UrlLoginPage, nil) @@ -86,42 +46,42 @@ func main() { "username": G.Form.UserName, "password": G.Form.PassWord, "ip": G.Ip, - "acid": G.Acid, - "enc_ver": G.Enc, + "acid": G.Meta.Acid, + "enc_ver": G.Meta.Enc, }) ErrHandler(err) G.EncryptedInfo = "{SRBX1}" + Util.Base64(Util.XEncode(string(info), G.Token)) - G.Md5=Util.Md5(G.Token) - G.EncryptedMd5 = "{MD5}"+G.Md5 + G.Md5 = Util.Md5(G.Token) + G.EncryptedMd5 = "{MD5}" + G.Md5 var chkstr string chkstr = G.Token + G.Form.UserName chkstr += G.Token + G.Md5 - chkstr += G.Token + G.Acid + chkstr += G.Token + G.Meta.Acid chkstr += G.Token + G.Ip - chkstr += G.Token + G.N - chkstr += G.Token + G.VType - chkstr += G.Token+ G.EncryptedInfo - G.EncryptedChkstr=Util.Sha1(chkstr) + chkstr += G.Token + G.Meta.N + chkstr += G.Token + G.Meta.VType + chkstr += G.Token + G.EncryptedInfo + G.EncryptedChkstr = Util.Sha1(chkstr) - res,err:=Request.Get(G.UrlLoginApi, map[string]string{ - "callback": "jQuery1124011576657442209481_1602812074032", - "action":"login", - "username": G.Form.UserName, - "password": G.EncryptedMd5, - "ac_id": G.Acid, - "ip": G.Ip, - "info": G.EncryptedInfo, - "chksum": G.EncryptedChkstr, - "n": G.N, - "type": G.VType, - "os": "Windows 10", - "name": "windows", + res, err := Request.Get(G.UrlLoginApi, map[string]string{ + "callback": "jQuery1124011576657442209481_1602812074032", + "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.VType, + "os": "Windows 10", + "name": "windows", "double_stack": "0", - "_": "1602812428675", + "_": "1602812428675", }) ErrHandler(err) - G.LoginResult,err=Util.GetResult(res) + G.LoginResult, err = Util.GetResult(res) ErrHandler(err) } fmt.Println("The loggin result is: " + G.LoginResult)