1
0
mirror of https://github.com/fumiama/go-nd-portal.git synced 2026-06-20 01:20:41 +08:00

refactor: auto get client ip from challenge response (#5)

* refactor: auto get client ip from challenge response
Since `outip()` was not working properly on devices getting local IP addresses behind a router, we should refactor this.
After analyzing the auth process, it is shown that  the challenge response includes key `client_ip` which is the real public IP address with key `ip` not specified in request.
- removed `outip()`
- added rsp key `ClientIP` to get client ip from challenge rsp

* style: trim code

* style: fix spelling issues

* refactor: create `portal_test.go` to handle portal tests separately

* feature: add `ResolveLocalClientIP()` and its test case

* optimize: resolve ClientIP locally when cant be get from challenge response
This commit is contained in:
chasey-dev
2025-09-01 22:33:57 +08:00
committed by GitHub
parent 32fdf3ae90
commit f2459dd8d9
5 changed files with 85 additions and 67 deletions

View File

@@ -4,7 +4,6 @@ package cmd
import (
"flag"
"fmt"
"net"
"net/netip"
"os"
"runtime"
@@ -17,15 +16,6 @@ import (
"github.com/fumiama/go-nd-portal/portal"
)
func outip() (net.IP, error) {
conn, err := net.Dial("udp", "8.8.8.8:53")
if err != nil {
return nil, err
}
_ = conn.Close()
return conn.LocalAddr().(*net.UDPAddr).IP.To4(), nil
}
func line() int {
_, _, fileLine, ok := runtime.Caller(1)
if ok {
@@ -38,14 +28,7 @@ const query = "query"
// Main cmd program
func Main() {
ip, err := outip()
ipf := ""
if err != nil {
ipf = query
} else {
ipf = ip.String()
}
ips := flag.String("ip", ipf, "public IP")
ip := flag.String("ip", "", "client IP, auto get from login host when empty")
n := flag.String("n", query, "username")
p := flag.String("p", query, "password")
h := flag.Bool("h", false, "display this help")
@@ -64,26 +47,18 @@ func Main() {
} else if *w {
logrus.SetLevel(logrus.WarnLevel)
}
if *ips == query {
fmt.Printf("ip: ")
_, err = fmt.Scanln(ips)
if *ip != "" {
// just validate IP here,
// dont convert to net.IP because we need only its string later
_, err := netip.ParseAddr(*ip)
if err != nil {
logrus.Errorln(err)
os.Exit(line())
}
}
if *ips != ip.String() {
ipaddr, err := netip.ParseAddr(*ips)
if err != nil {
logrus.Errorln(err)
os.Exit(line())
}
a4 := ipaddr.As4()
copy(ip, a4[:])
}
if *n == query {
fmt.Printf("username: ")
_, err = fmt.Scanln(n)
_, err := fmt.Scanln(n)
if err != nil {
logrus.Errorln(err)
os.Exit(line())
@@ -112,7 +87,7 @@ func Main() {
// p: password
// ip : public ip
// *t : login type
ptl, err := portal.NewPortal(*n, *p, *s, ip, portal.LoginType(*t))
ptl, err := portal.NewPortal(*n, *p, *s, *ip, portal.LoginType(*t))
if err != nil {
logrus.Errorln(err)
os.Exit(line())