udp listener cleanup, add early port listen checks

This commit is contained in:
Jaime Pillora
2020-07-23 01:26:47 +10:00
parent 33fa2010ab
commit e3abdc607e
6 changed files with 54 additions and 16 deletions
+4
View File
@@ -106,6 +106,10 @@ func NewClient(c *Config) (*Client, error) {
}
hasStdio = true
}
//confirm non-reverse tunnel is available
if !r.Reverse && !r.CanListen() {
return nil, fmt.Errorf("Remote %s cannot listen", r.String())
}
client.computed.Remotes = append(client.computed.Remotes, r)
}
//set default log level
+15 -11
View File
@@ -109,24 +109,28 @@ func (s *Server) handleWebsocket(w http.ResponseWriter, req *http.Request) {
l.Infof("Client version (%s) differs from server version (%s)",
v, chshare.BuildVersion)
}
//confirm reverse tunnels are allowed
//validate remotes
for _, r := range c.Remotes {
if r.Reverse && !s.config.Reverse {
l.Debugf("Denied reverse port forwarding request, please enable --reverse")
failed(s.Errorf("Reverse port forwaring not enabled on server"))
return
}
}
//if user is provided, ensure they have
//access to the desired remotes
if user != nil {
for _, r := range c.Remotes {
//if user is provided, ensure they have
//access to the desired remotes
if user != nil {
addr := r.UserAddr()
if !user.HasAccess(addr) {
failed(s.Errorf("access to '%s' denied", addr))
return
}
}
//confirm reverse tunnels are allowed
if r.Reverse && !s.config.Reverse {
l.Debugf("Denied reverse port forwarding request, please enable --reverse")
failed(s.Errorf("Reverse port forwaring not enabled on server"))
return
}
//confirm reverse tunnel is available
if r.Reverse && !r.CanListen() {
failed(s.Errorf("Remote %s cannot listen", r.String()))
return
}
}
//successfuly validated config!
r.Reply(true, nil)
+28
View File
@@ -2,6 +2,7 @@ package settings
import (
"errors"
"net"
"net/url"
"regexp"
"strconv"
@@ -223,6 +224,33 @@ func (r Remote) UserAddr() string {
return r.RemoteHost + ":" + r.RemotePort
}
//CanListen checks if the port can be listened on
func (r Remote) CanListen() bool {
switch r.LocalProto {
case "tcp":
//valid
conn, err := net.Listen("tcp", r.Local())
if err == nil {
conn.Close()
return true
}
return false
case "udp":
addr, err := net.ResolveUDPAddr("udp", r.Local())
if err != nil {
return false
}
conn, err := net.ListenUDP(r.LocalProto, addr)
if err == nil {
conn.Close()
return true
}
return false
}
//invalid
return false
}
type Remotes []*Remote
//Filter out forward reversed/non-reversed remotes
+3 -3
View File
@@ -52,14 +52,14 @@ func (p *Proxy) listen() error {
if err != nil {
return p.Errorf("tcp: %s", err)
}
p.Debugf("Listening")
p.Infof("Listening")
p.tcp = l
} else if p.remote.LocalProto == "udp" {
l, err := listenUDP(p.Logger, p.sshTun, p.remote)
if err != nil {
return err
}
p.Debugf("Listening")
p.Infof("Listening")
p.udp = l
} else {
return p.Errorf("unknown local proto")
@@ -70,7 +70,6 @@ func (p *Proxy) listen() error {
//Run enables the proxy and blocks while its active,
//close the proxy by cancelling the context.
func (p *Proxy) Run(ctx context.Context) error {
defer p.Debugf("Closed")
if p.remote.Stdio {
return p.runStdio(ctx)
} else if p.remote.LocalProto == "tcp" {
@@ -82,6 +81,7 @@ func (p *Proxy) Run(ctx context.Context) error {
}
func (p *Proxy) runStdio(ctx context.Context) error {
defer p.Infof("Closed")
for {
p.pipeRemote(ctx, cio.Stdio)
select {
+3 -1
View File
@@ -13,6 +13,7 @@ import (
"github.com/jpillora/chisel/share/cio"
"github.com/jpillora/chisel/share/settings"
"github.com/jpillora/sizestr"
"golang.org/x/crypto/ssh"
"golang.org/x/sync/errgroup"
)
@@ -59,6 +60,7 @@ type udpListener struct {
}
func (u *udpListener) run(ctx context.Context) error {
defer u.inbound.Close()
//udp doesnt accept connections,
//udp simply forwards packets
//and therefore only needs to listen
@@ -73,7 +75,7 @@ func (u *udpListener) run(ctx context.Context) error {
u.Debugf("listen: %s", err)
return err
}
u.Debugf("sent %d, received %d", u.sent, u.recv)
u.Debugf("Close (sent %s received %s)", sizestr.ToString(u.sent), sizestr.ToString(u.recv))
return nil
}
+1 -1
View File
@@ -119,7 +119,7 @@ func post(url, body string) (string, error) {
}
func availablePort() string {
l, err := net.Listen("tcp4", "127.0.0.1:0")
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
log.Panic(err)
}