package auth import ( "fmt" "net" "proxy-server/server/app" "proxy-server/server/fwd/core" "strconv" "time" "errors" ) type Protocol string const ( Socks5 = Protocol("socks5") Http = Protocol("http") ) func Protect(conn net.Conn, proto Protocol, username, password *string) (*core.AuthContext, error) { // 获取用户地址 remoteAddr := conn.RemoteAddr().String() remoteHost, _, err := net.SplitHostPort(remoteAddr) if err != nil { return nil, fmt.Errorf("无法获取连接信息: %w", err) } // 获取服务端口 localAddr := conn.LocalAddr().String() _, _localPort, err := net.SplitHostPort(localAddr) localPort, err := strconv.ParseUint(_localPort, 10, 16) if err != nil { return nil, fmt.Errorf("noAuth 认证失败: %w", err) } // 查找权限配置 var permit, ok = app.Permits[uint16(localPort)] if !ok { return nil, errors.New("没有权限") } // 检查是否过期 if permit.Expire.Before(time.Now()) { return nil, errors.New("权限已过期") } // 检查 IP 是否可用 if len(permit.Whitelists) > 0 { var found = false for _, allowedHost := range permit.Whitelists { var allowed = net.ParseIP(allowedHost) var remote = net.ParseIP(remoteHost) if remote.Equal(allowed) { found = true break } } if !found { return nil, errors.New("不在白名单内") } } if username != nil && password != nil { if *username != permit.Username || *password != permit.Password { return nil, errors.New("用户名或密码错误") } } return &core.AuthContext{ Timeout: time.Since(permit.Expire).Seconds(), Payload: core.Payload{ ID: app.Assigns[uint16(localPort)], }, }, nil }