From 47a56f6844bb8cc7e04df62959c5d195b1aeb3e1 Mon Sep 17 00:00:00 2001 From: Antonio Mika Date: Sat, 24 May 2025 17:06:40 -0400 Subject: [PATCH] Update golangci-lint --- .github/workflows/build.yml | 3 +- .golangci.yml | 9 ++++ httpmuxer/httpmuxer.go | 14 +++++- httpmuxer/https.go | 31 +++++++++++-- sshmuxer/channels.go | 14 +++--- sshmuxer/requests.go | 44 +++++++++++++++--- sshmuxer/sshmuxer.go | 29 ++++++++++-- utils/authentication_key_request_test.go | 35 ++++++++++++-- utils/conn.go | 18 ++++++-- utils/console.go | 23 +++++---- utils/state.go | 59 ++++++++++++++++++++---- utils/utils.go | 10 +++- 12 files changed, 235 insertions(+), 54 deletions(-) create mode 100644 .golangci.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9722af5..eb3756d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,10 +34,9 @@ jobs: - name: Checkout repo uses: actions/checkout@v3 - name: Lint the codebase - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v8 with: version: latest - args: -E goimports -E godot - name: Run tests run: | go test -v ./... -cover -race -coverprofile=coverage.out diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..f6b1611 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,9 @@ +version: "2" + +linters: + enable: + - godot + +formatters: + enable: + - goimports diff --git a/httpmuxer/httpmuxer.go b/httpmuxer/httpmuxer.go index e6cd214..d825405 100644 --- a/httpmuxer/httpmuxer.go +++ b/httpmuxer/httpmuxer.go @@ -459,7 +459,12 @@ func Start(state *utils.State) { state.TCPListeners.Store(httpsServer.Addr, tH) } - defer httpsListener.Close() + defer func() { + err := httpsListener.Close() + if err != nil { + log.Println("Error closing https listener:", err) + } + }() log.Fatal(httpsServer.ServeTLS(httpsListener, "", "")) }() @@ -491,7 +496,12 @@ func Start(state *utils.State) { httpListener = l } - defer httpListener.Close() + defer func() { + err := httpListener.Close() + if err != nil { + log.Println("Error closing http listener:", err) + } + }() log.Fatal(httpServer.Serve(httpListener)) } diff --git a/httpmuxer/https.go b/httpmuxer/https.go index 69d107e..e039899 100644 --- a/httpmuxer/https.go +++ b/httpmuxer/https.go @@ -26,7 +26,15 @@ func (pL *proxyListener) Accept() (net.Conn, error) { clientRemote, _, err := net.SplitHostPort(cl.RemoteAddr().String()) if err != nil || pL.State.IPFilter.Blocked(clientRemote) { - cl.Close() + err := cl.Close() + if err != nil { + log.Println("Error closing connection:", err) + } + + if viper.GetBool("debug") { + log.Printf("Blocked connection from %s to %s", cl.RemoteAddr().String(), cl.LocalAddr().String()) + } + return pL.Accept() } @@ -58,14 +66,24 @@ func (pL *proxyListener) Accept() (net.Conn, error) { connectionLocation, err := balancer.NextServer() if err != nil { log.Println("Unable to load connection location:", err) - teeConn.Close() + + err := teeConn.Close() + if err != nil { + log.Println("Error closing teeConn:", err) + } + return pL.Accept() } host, err := base64.StdEncoding.DecodeString(connectionLocation.Host) if err != nil { log.Println("Unable to decode connection location:", err) - teeConn.Close() + + err := teeConn.Close() + if err != nil { + log.Println("Error closing teeConn:", err) + } + return pL.Accept() } @@ -93,7 +111,12 @@ func (pL *proxyListener) Accept() (net.Conn, error) { conn, err := net.Dial("unix", hostAddr) if err != nil { log.Println("Error connecting to tcp balancer:", err) - teeConn.Close() + + err := teeConn.Close() + if err != nil { + log.Println("Error closing teeConn:", err) + } + return pL.Accept() } diff --git a/sshmuxer/channels.go b/sshmuxer/channels.go index f257a49..702f887 100644 --- a/sshmuxer/channels.go +++ b/sshmuxer/channels.go @@ -421,14 +421,14 @@ func getProxyProtoVersion(proxyProtoUserVersion string) byte { proxyProtoUserVersion = viper.GetString("proxy-protocol-version") } - realProtoVersion := 0 - if proxyProtoUserVersion == "1" { - realProtoVersion = 1 - } else if proxyProtoUserVersion == "2" { - realProtoVersion = 2 + switch proxyProtoUserVersion { + case "1": + return 1 + case "2": + return 2 + default: + return 0 } - - return byte(realProtoVersion) } // parseDeadline parses the deadline string provided by the client to a time object. diff --git a/sshmuxer/requests.go b/sshmuxer/requests.go index 93f8f3e..719d146 100644 --- a/sshmuxer/requests.go +++ b/sshmuxer/requests.go @@ -66,7 +66,12 @@ func handleCancelRemoteForward(newRequest *ssh.Request, sshConn *utils.SSHConnec if holder.OriginalAddr == check.Addr && holder.OriginalPort == check.Rport { closed = true - holder.Close() + + err := holder.Close() + if err != nil { + log.Println("Error closing listener:", err) + } + return false } @@ -174,8 +179,16 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *utils.SSHConnection, } return } - tmpfile.Close() - os.Remove(tmpfile.Name()) + + err = tmpfile.Close() + if err != nil { + log.Println("Error closing temporary file:", err) + } + + err = os.Remove(tmpfile.Name()) + if err != nil { + log.Println("Error removing temporary file:", err) + } listenAddr := tmpfile.Name() @@ -205,10 +218,19 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *utils.SSHConnection, deferHandler := func() {} cleanupChanListener := func() { - listenerHolder.Close() + err := listenerHolder.Close() + if err != nil { + log.Println("Error closing listener:", err) + } + state.Listeners.Delete(listenAddr) sshConn.Listeners.Delete(listenAddr) - os.Remove(listenAddr) + + err = os.Remove(listenAddr) + if err != nil { + log.Println("Error removing unix socket:", err) + } + deferHandler() } @@ -334,7 +356,11 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *utils.SSHConnection, }) if balancers == 0 { - tH.Listener.Close() + err := tH.Listener.Close() + if err != nil { + log.Println("Error closing TCPListener:", err) + } + state.Listeners.Delete(tcpAddr) state.TCPListeners.Delete(tcpAddr) } @@ -373,7 +399,11 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *utils.SSHConnection, newChan, newReqs, err := sshConn.SSHConn.OpenChannel("forwarded-tcpip", ssh.Marshal(resp)) if err != nil { sshConn.SendMessage(err.Error(), true) - cl.Close() + + err := cl.Close() + if err != nil { + log.Println("Error closing client connection:", err) + } } if sshConn.ProxyProto != 0 && listenerType == utils.TCPListener { diff --git a/sshmuxer/sshmuxer.go b/sshmuxer/sshmuxer.go index 06eb96e..ed9dad8 100644 --- a/sshmuxer/sshmuxer.go +++ b/sshmuxer/sshmuxer.go @@ -182,7 +182,11 @@ func Start() { state.Listeners.Store(viper.GetString("ssh-address"), listener) defer func() { - listener.Close() + err := listener.Close() + if err != nil { + log.Println("Error closing listener:", err) + } + state.Listeners.Delete(viper.GetString("ssh-address")) }() @@ -205,7 +209,15 @@ func Start() { clientRemote, _, err := net.SplitHostPort(conn.RemoteAddr().String()) if err != nil || state.IPFilter.Blocked(clientRemote) { - conn.Close() + err := conn.Close() + if err != nil { + log.Println("Error closing connection:", err) + } + + if viper.GetBool("debug") { + log.Printf("Blocked connection from %s to %s", conn.RemoteAddr().String(), conn.LocalAddr().String()) + } + return } @@ -220,7 +232,10 @@ func Start() { <-time.After(viper.GetDuration("cleanup-unauthed-timeout")) clientLoggedInMutex.Lock() if !clientLoggedIn { - conn.Close() + err := conn.Close() + if err != nil { + log.Println("Error closing connection:", err) + } } clientLoggedInMutex.Unlock() }() @@ -233,8 +248,12 @@ func Start() { clientLoggedIn = true clientLoggedInMutex.Unlock() if err != nil { - conn.Close() - log.Println(err) + err := conn.Close() + if err != nil { + log.Println("Error closing connection:", err) + } + + log.Println("SSH connection could not be established", err) return } diff --git a/utils/authentication_key_request_test.go b/utils/authentication_key_request_test.go index 0034888..8ccaf84 100644 --- a/utils/authentication_key_request_test.go +++ b/utils/authentication_key_request_test.go @@ -92,7 +92,13 @@ func HandleSSHConn(sshListener net.Listener, successAuth *chan bool) { if err != nil { log.Fatal(err) } - defer conn.Close() + + defer func() { + err := conn.Close() + if err != nil { + log.Print("Error closing connection", err) + } + }() // GetSSHConfig is the method we are testing to validate that it // can use an http request to validate client public key auth @@ -102,7 +108,11 @@ func HandleSSHConn(sshListener net.Listener, successAuth *chan bool) { *successAuth <- false return } - connection.Close() + + err = connection.Close() + if err != nil { + log.Print("Error closing connection", err) + } *successAuth <- true } @@ -117,7 +127,14 @@ func TestAuthenticationKeyRequest(t *testing.T) { if err != nil { log.Fatal(err) } - defer os.RemoveAll(dir) + + defer func() { + err := os.RemoveAll(dir) + if err != nil { + t.Error(err) + } + }() + viper.Set("private-keys-directory", dir) viper.Set("authentication", true) @@ -193,7 +210,12 @@ func TestAuthenticationKeyRequest(t *testing.T) { if err != nil { t.Error(err) } - defer sshListener.Close() + defer func() { + err := sshListener.Close() + if err != nil { + t.Error(err) + } + }() successAuth := make(chan bool) go HandleSSHConn(sshListener, &successAuth) @@ -217,7 +239,10 @@ func TestAuthenticationKeyRequest(t *testing.T) { t.Log("ssh client rejected", err) } else { t.Log("ssh client connected") - client.Close() + err := client.Close() + if err != nil { + t.Error(err) + } } didAuth := <-successAuth diff --git a/utils/conn.go b/utils/conn.go index 7c1af15..4baa8fc 100644 --- a/utils/conn.go +++ b/utils/conn.go @@ -82,7 +82,12 @@ func (s *SSHConnection) ListenerCount() int { func (s *SSHConnection) CleanUp(state *State) { s.Closed.Do(func() { close(s.Close) - s.SSHConn.Close() + + err := s.SSHConn.Close() + if err != nil { + log.Println("Error closing SSH connection:", err) + } + state.SSHConnections.Delete(s.SSHConn.RemoteAddr().String()) log.Println("Closed SSH connection for:", s.SSHConn.RemoteAddr().String(), "user:", s.SSHConn.User()) }) @@ -208,8 +213,15 @@ func (i IdleTimeoutConn) Write(buf []byte) (int, error) { // CopyBoth copies betwen a reader and writer and will cleanup each. func CopyBoth(writer net.Conn, reader io.ReadWriteCloser) { closeBoth := func() { - reader.Close() - writer.Close() + err := reader.Close() + if err != nil { + log.Println("Error closing reader:", err) + } + + err = writer.Close() + if err != nil { + log.Println("Error closing writer:", err) + } } var tcon io.ReadWriter diff --git a/utils/console.go b/utils/console.go index 0ba7bb6..afaea19 100644 --- a/utils/console.go +++ b/utils/console.go @@ -169,7 +169,10 @@ func (c *WebConsole) HandleDisconnectRoute(proxyUrl string, g *gin.Context) { listener, ok := listenerTmp.(*ListenerHolder) if ok { - listener.Close() + err := listener.Close() + if err != nil { + log.Println("Error closing listener:", err) + } } } @@ -194,12 +197,7 @@ func (c *WebConsole) HandleClients(proxyUrl string, g *gin.Context) { routeListeners := map[string]map[string]any{} sshConn.Listeners.Range(func(name string, val net.Listener) bool { - ok := true - if name == "" { - ok = false - } - - if ok { + if name != "" { listeners = append(listeners, name) } @@ -347,7 +345,10 @@ func (c *WebConsole) RemoveRoute(route string) { } for _, client := range clients { - client.Conn.Close() + err := client.Conn.Close() + if err != nil { + log.Println("Error closing websocket connection:", err) + } } c.Clients.Delete(route) @@ -407,7 +408,11 @@ func (c *WebConsole) BroadcastRoute(route string, message []byte) { // Handle is the only place socket reads and writes happen. func (c *WebClient) Handle() { defer func() { - c.Conn.Close() + err := c.Conn.Close() + if err != nil { + log.Println("Error closing websocket connection:", err) + } + c.Console.RemoveClient(c.Route, c) }() diff --git a/utils/state.go b/utils/state.go index e120390..96a8f0f 100644 --- a/utils/state.go +++ b/utils/state.go @@ -92,7 +92,15 @@ func (tH *TCPHolder) Handle(state *State) { clientRemote, _, err := net.SplitHostPort(cl.RemoteAddr().String()) if err != nil || state.IPFilter.Blocked(clientRemote) { - cl.Close() + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + + if viper.GetBool("debug") { + log.Printf("Blocked connection from %s to %s", cl.RemoteAddr().String(), cl.LocalAddr().String()) + } + return } @@ -103,7 +111,12 @@ func (tH *TCPHolder) Handle(state *State) { tlsHello, teeConn, err := PeekTLSHello(cl) if tlsHello == nil { log.Printf("Unable to read TLS hello: %s", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } @@ -112,7 +125,12 @@ func (tH *TCPHolder) Handle(state *State) { _, err = io.ReadFull(teeConn, bufBytes) if err != nil { log.Printf("Unable to read buffered data: %s", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } @@ -131,7 +149,12 @@ func (tH *TCPHolder) Handle(state *State) { if pB == nil { log.Printf("Unable to load connection location: %s not found on TCP listener %s", balancerName, tH.TCPHost) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } } @@ -141,14 +164,24 @@ func (tH *TCPHolder) Handle(state *State) { connectionLocation, err := balancer.NextServer() if err != nil { log.Println("Unable to load connection location:", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } host, err := base64.StdEncoding.DecodeString(connectionLocation.Host) if err != nil { log.Println("Unable to decode connection location:", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } @@ -176,7 +209,12 @@ func (tH *TCPHolder) Handle(state *State) { conn, err := net.Dial("unix", hostAddr) if err != nil { log.Println("Error connecting to tcp balancer:", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } @@ -184,7 +222,12 @@ func (tH *TCPHolder) Handle(state *State) { _, err := conn.Write(bufBytes) if err != nil { log.Println("Unable to write to conn:", err) - cl.Close() + + err := cl.Close() + if err != nil { + log.Printf("Unable to close connection: %s", err) + } + return } } diff --git a/utils/utils.go b/utils/utils.go index bb4b5ee..085c656 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -176,7 +176,10 @@ func GetRandomPortInRange(listenAddr string, portRange string) uint32 { return GetRandomPortInRange(listenAddr, portRange) } - ln.Close() + err = ln.Close() + if err != nil { + log.Println("Error closing listener:", err) + } return bindPort } @@ -742,7 +745,10 @@ func GetOpenPort(addr string, port uint32, state *State, sshConn *SSHConnection, if listenErr != nil { err = listenErr } else { - ln.Close() + err := ln.Close() + if err != nil { + log.Println("Error closing listener:", err) + } } }