mirror of https://github.com/cyp0633/drcom-go.git
Add web login functionality
This commit is contained in:
parent
e7e300b338
commit
f48aed8a29
|
@ -47,7 +47,7 @@ func login() (tail []byte, salt []byte, err error) {
|
|||
err = ErrorLogin
|
||||
return
|
||||
}
|
||||
util.Logger.Debug("Login result recv", zap.String("packet", hex.EncodeToString(result[:n])))
|
||||
util.Logger.Debug("Login result recv", zap.String("packet", hex.EncodeToString(result[:n])), zap.Int("len", n))
|
||||
if bytes.Equal(result[0:1], []byte{0x04}) { // 登录成功
|
||||
util.Logger.Info("Logged in")
|
||||
tail = result[23:39] // 同时也是 authinfo
|
||||
|
@ -109,9 +109,9 @@ func challenge() (salt []byte, err error) {
|
|||
err = ErrorChallenge
|
||||
return
|
||||
}
|
||||
util.Logger.Debug("Challenge recv", zap.String("packet", hex.EncodeToString(salt[:n])), zap.String("salt", hex.EncodeToString(salt[4:8])))
|
||||
util.Logger.Debug("Challenge recv", zap.String("packet", hex.EncodeToString(salt[:n])), zap.Int("len", n), zap.String("salt", hex.EncodeToString(salt[4:8])))
|
||||
// 长度应为 40 字节
|
||||
if len(salt) != 40 {
|
||||
if len(salt) == 106 {
|
||||
util.Logger.Error("Challenge reply length does not match")
|
||||
err = ErrorChallenge
|
||||
return
|
||||
|
|
|
@ -72,7 +72,7 @@ login:
|
|||
|
||||
// 启动连接测试
|
||||
var ch = make(chan bool, 1)
|
||||
go util.CheckConnection(ch)
|
||||
go util.CheckConnection(ch, 5*time.Second)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
// 清除 socket buffer
|
||||
|
|
|
@ -11,6 +11,7 @@ var CLI struct {
|
|||
Dhcp struct{} `cmd:"" help:"Use DHCP mode"` // DHCP模式
|
||||
DhcpAuto struct{} `cmd:"" help:"Use DHCP mode with auto configuration"` // DHCP自动配置模式
|
||||
Pppoe struct{} `cmd:"" help:"Use PPPoE mode"` // PPPoE模式
|
||||
Web struct{} `cmd:"" help:"Imitate web login"` // 模拟网页登录
|
||||
Conf string `help:"Configuration file path" short:"c" default:"/etc/drcom.conf" type:"path"` // 配置文件目录
|
||||
BindIP string `help:"IP address to bind to" short:"b" default:"0.0.0.0"` // 绑定IP地址
|
||||
Log string `help:"Log ONLY to specified path" short:"l" default:""` // 日志文件目录
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// CheckConnection 检查网络连接,如发现不通,向 ch 中发送信号
|
||||
func CheckConnection(ch chan bool) {
|
||||
func CheckConnection(ch chan bool, interval time.Duration) {
|
||||
// 自定义 DNS
|
||||
resolver := &net.Resolver{
|
||||
PreferGo: true,
|
||||
|
@ -50,7 +50,7 @@ func CheckConnection(ch chan bool) {
|
|||
} else {
|
||||
resp.Body.Close()
|
||||
Logger.Debug("Network connection is OK")
|
||||
time.Sleep(time.Second * 5)
|
||||
time.Sleep(interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// 用于模拟网页登录
|
||||
package web
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/cyp0633/drcom-go/internal/util"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 发送登录请求
|
||||
func doLogin(server_base string) {
|
||||
username := util.Conf.Username
|
||||
password := util.Conf.Password
|
||||
md5Ctx := md5.New()
|
||||
md5Ctx.Write([]byte("2" + password + "12345678"))
|
||||
cipherStr := md5Ctx.Sum(nil)
|
||||
|
||||
form := url.Values{
|
||||
"DDDDD": {username},
|
||||
"upass": {string(cipherStr)},
|
||||
"0MKKey": {"123456"},
|
||||
"R1": {"0"},
|
||||
"R2": {"1"},
|
||||
"para": {"00"},
|
||||
"v6ip": {""},
|
||||
}
|
||||
util.Logger.Debug("Sending login request", zap.String("server", server_base),zap.String("form",form.Encode()))
|
||||
|
||||
response, err := http.PostForm(server_base+"/0.htm", form)
|
||||
if err != nil {
|
||||
util.Logger.Error("Send login request failed", zap.Error(err))
|
||||
}
|
||||
util.Logger.Info("Login seems successful")
|
||||
util.Logger.Debug("Response", zap.Any("response", response.Body))
|
||||
print(response)
|
||||
defer response.Body.Close()
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cyp0633/drcom-go/internal/util"
|
||||
)
|
||||
|
||||
// 连接检查与保活
|
||||
// TODO: 退出时自动注销
|
||||
func Run() {
|
||||
var server string
|
||||
ch := make(chan bool, 1)
|
||||
go util.CheckConnection(ch, 1*time.Minute) // 似乎比较不容易断,可以设长一点
|
||||
for {
|
||||
select {
|
||||
case <-ch:
|
||||
util.Logger.Info("Network disconnected, trying to login")
|
||||
if server == "" {
|
||||
server = getServer()
|
||||
}
|
||||
if server != "" {
|
||||
doLogin(server)
|
||||
}
|
||||
default:
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/cyp0633/drcom-go/internal/util"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 查找登录服务器地址
|
||||
func getServer() (server string) {
|
||||
generate_204 := util.ExtConf.ConnectionTestServer
|
||||
// 将 HTTPS 改为 HTTP
|
||||
if generate_204[:5] == "https" {
|
||||
generate_204 = "http" + generate_204[5:]
|
||||
}
|
||||
// 发 GET,检查是否有登录信息
|
||||
response, err := http.Get(generate_204)
|
||||
if err != nil {
|
||||
util.Logger.Error("Get server failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
defer response.Body.Close()
|
||||
util.Logger.Debug("Find auth server", zap.Any("response", response))
|
||||
switch response.StatusCode {
|
||||
case 204: // 正常访问,会返回 204
|
||||
util.Logger.Warn("204'ed; may be already logged in", zap.Any("response", response))
|
||||
return
|
||||
case 302: // 临时重定向,Location header 即为认证服务器
|
||||
server = response.Header.Get("Location")
|
||||
if server == "" {
|
||||
util.Logger.Error("Server not found", zap.Any("response", response))
|
||||
} else {
|
||||
util.Logger.Info("Auth server found", zap.String("server", server))
|
||||
}
|
||||
case 200: // 劫持了内容,但解析似乎没问题
|
||||
// 截取 location.href="<server>"
|
||||
bodyBytes, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
util.Logger.Error("Read body failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
bodyString := string(bodyBytes)
|
||||
startIndex := strings.Index(bodyString, "location.href=\"")
|
||||
if startIndex != -1 {
|
||||
startIndex += len("location.href=\"")
|
||||
endIndex := strings.Index(bodyString[startIndex:], "\"")
|
||||
if endIndex != -1 {
|
||||
server = bodyString[startIndex : startIndex+endIndex]
|
||||
util.Logger.Info("Auth server found", zap.String("server", server))
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
util.Logger.Error("Find auth server: unexpected response", zap.String("state", response.Status))
|
||||
}
|
||||
return
|
||||
}
|
8
main.go
8
main.go
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/cyp0633/drcom-go/internal/dhcp"
|
||||
dhcpauto "github.com/cyp0633/drcom-go/internal/dhcp/auto"
|
||||
"github.com/cyp0633/drcom-go/internal/util"
|
||||
"github.com/cyp0633/drcom-go/internal/web"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -24,6 +25,13 @@ func main() {
|
|||
util.Daemonize()
|
||||
}
|
||||
dhcp.Run()
|
||||
case "web":
|
||||
util.ParseConf()
|
||||
if util.CLI.Daemon {
|
||||
util.Logger.Info("Daemon mode")
|
||||
util.Daemonize()
|
||||
}
|
||||
web.Run()
|
||||
case "pppoe":
|
||||
util.Logger.Fatal("PPPoE mode not implemented")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue