mirror of
https://github.com/fumiama/go-nd-portal.git
synced 2026-07-01 16:40:25 +08:00
init
This commit is contained in:
103
portal.go
Normal file
103
portal.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package gondportal
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrIllegalIPv4 = errors.New("illegal ipv4")
|
||||
ErrUnexpectedChallengeResponse = errors.New("unexpected challenge response")
|
||||
)
|
||||
|
||||
type Portal struct {
|
||||
nam string
|
||||
pwd string
|
||||
ip net.IP
|
||||
}
|
||||
|
||||
func NewPortal(name, password string, ipv4 net.IP) (*Portal, error) {
|
||||
if len(ipv4) != 4 {
|
||||
return nil, ErrIllegalIPv4
|
||||
}
|
||||
return &Portal{
|
||||
nam: name,
|
||||
pwd: password,
|
||||
ip: ipv4,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Portal) GetChallenge() (string, error) {
|
||||
data, err := web.RequestDataWith(
|
||||
web.NewDefaultClient(),
|
||||
fmt.Sprintf(PortalGetChallenge, "gondportal", p.nam, p.ip, time.Now().UnixMilli()),
|
||||
"GET", "", PortalHeaderUA,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(data) < 12 {
|
||||
return "", ErrUnexpectedChallengeResponse
|
||||
}
|
||||
type rsp struct {
|
||||
Challenge string `json:"challenge"`
|
||||
Ecode int `json:"ecode"`
|
||||
Msg string `json:"error_msg"`
|
||||
}
|
||||
var r rsp
|
||||
err = json.Unmarshal(data[11:len(data)-1], &r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if r.Ecode != 0 {
|
||||
return "", errors.New(r.Msg)
|
||||
}
|
||||
return r.Challenge, nil
|
||||
}
|
||||
|
||||
func (p *Portal) PasswordHMd5(challenge string) string {
|
||||
var buf [16]byte
|
||||
h := hmac.New(md5.New, StringToBytes(challenge))
|
||||
_, _ = h.Write(StringToBytes(p.pwd))
|
||||
return hex.EncodeToString(h.Sum(buf[:0]))
|
||||
}
|
||||
|
||||
func (p *Portal) Login(challenge string) error {
|
||||
info := EncodeUserInfo(p.String(), challenge)
|
||||
hmd5 := p.PasswordHMd5(challenge)
|
||||
data, err := web.RequestDataWith(
|
||||
web.NewDefaultClient(),
|
||||
fmt.Sprintf(PortalLogin, "gondportal", p.nam, hmd5, p.ip, p.CheckSum(challenge, hmd5, info), info, time.Now().UnixMilli()),
|
||||
"GET", "", PortalHeaderUA,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < 12 {
|
||||
return ErrUnexpectedChallengeResponse
|
||||
}
|
||||
type rsp struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var r rsp
|
||||
err = json.Unmarshal(data[11:len(data)-1], &r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.Error == "ok" {
|
||||
return nil
|
||||
}
|
||||
return errors.New(r.Error)
|
||||
}
|
||||
|
||||
func (p *Portal) String() string {
|
||||
return fmt.Sprintf(PortalUserInfo, p.nam, p.pwd, p.ip)
|
||||
}
|
||||
Reference in New Issue
Block a user