Skip to content
Permalink
Browse files

Fixed starting background channels

  • Loading branch information...
antoniomika committed Nov 19, 2019
1 parent 5ba74a7 commit 67819d8df6c0880a9ef7de7b4238f1e6c5c071d9
Showing with 64 additions and 22 deletions.
  1. +11 −2 .goreleaser.yml
  2. +1 −1 .vscode/launch.json
  3. BIN __debug_bin
  4. +2 −7 channels.go
  5. +21 −0 handle.go
  6. +11 −8 main.go
  7. +2 −2 requests.go
  8. +16 −2 utils.go
@@ -7,6 +7,9 @@ builds:
- CGO_ENABLED=0
goos:
- linux
- win
- darwin
- windows
goarch:
- amd64
- arm
@@ -21,6 +24,12 @@ changelog:
- Merge branch
archives:
- name_template: '{{ .ProjectName }}-{{ .Version }}.{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
wrap_in_directory: true
format_overrides:
- goos: windows
format: zip
- goos: windows
format: zip
files:
- LICENSE*
- README*
- keys/
- pubkeys/
@@ -9,7 +9,7 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"program": "${workspaceFolder}",
"env": {},
"args": [
"-sish.auth=false",
BIN +16.4 MB __debug_bin
Binary file not shown.
@@ -27,12 +27,7 @@ func handleSession(newChannel ssh.NewChannel, sshConn *SSHConnection, state *Sta
for {
select {
case c := <-sshConn.Messages:
_, err := connection.Write([]byte(c))
if err != nil {
log.Println("Error trying to write message to socket:", err)
}

_, err = connection.Write([]byte{'\r', '\n'})
_, err := connection.Write(append([]byte(c), []byte{'\r', '\n'}...))
if err != nil {
log.Println("Error trying to write message to socket:", err)
}
@@ -79,7 +74,7 @@ func handleSession(newChannel ssh.NewChannel, sshConn *SSHConnection, state *Sta
if strings.HasPrefix(payloadString, proxyProtoPrefix) && *proxyProtoEnabled {
sshConn.ProxyProto = getProxyProtoVersion(strings.TrimPrefix(payloadString, proxyProtoPrefix))
if sshConn.ProxyProto != 0 {
sshConn.Messages <- fmt.Sprintf("Proxy protocol enabled for TCP connections. Using protocol version %d", int(sshConn.ProxyProto))
sendMessage(sshConn, fmt.Sprintf("Proxy protocol enabled for TCP connections. Using protocol version %d", int(sshConn.ProxyProto)))
}
}
default:
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"log"
"time"

"golang.org/x/crypto/ssh"
)
@@ -19,6 +20,7 @@ func handleRequests(reqs <-chan *ssh.Request, sshConn *SSHConnection, state *Sta
func handleRequest(newRequest *ssh.Request, sshConn *SSHConnection, state *State) {
switch req := newRequest.Type; req {
case "tcpip-forward":
go checkSession(newRequest, sshConn, state)
handleRemoteForward(newRequest, sshConn, state)
default:
err := newRequest.Reply(false, nil)
@@ -28,6 +30,24 @@ func handleRequest(newRequest *ssh.Request, sshConn *SSHConnection, state *State
}
}

func checkSession(newRequest *ssh.Request, sshConn *SSHConnection, state *State) {
if sshConn.CleanupHandler {
return
}
sshConn.CleanupHandler = true
select {
case <-sshConn.Session:
return
case <-time.After(2 * time.Second):
err := sshConn.SSHConn.Wait()
if err != nil {
log.Println("Waited for ssh conn without session:", err)
}
sshConn.CleanUp(state)
return
}
}

func handleChannels(chans <-chan ssh.NewChannel, sshConn *SSHConnection, state *State) {
for newChannel := range chans {
if *debug {
@@ -40,6 +60,7 @@ func handleChannels(chans <-chan ssh.NewChannel, sshConn *SSHConnection, state *
func handleChannel(newChannel ssh.NewChannel, sshConn *SSHConnection, state *State) {
switch channel := newChannel.ChannelType(); channel {
case "session":
close(sshConn.Session)
handleSession(newChannel, sshConn, state)
case "direct-tcpip":
handleAlias(newChannel, sshConn, state)
19 main.go
@@ -18,11 +18,13 @@ import (

// SSHConnection handles state for a SSHConnection
type SSHConnection struct {
SSHConn *ssh.ServerConn
Listeners *sync.Map
Close chan bool
Messages chan string
ProxyProto byte
SSHConn *ssh.ServerConn
Listeners *sync.Map
Close chan bool
Messages chan string
ProxyProto byte
Session chan bool
CleanupHandler bool
}

// State handles overall state
@@ -200,7 +202,7 @@ func main() {

if *cleanupUnbound {
go func() {
<-time.NewTimer(5 * time.Second).C
<-time.After(5 * time.Second)
if !clientLoggedIn {
conn.Close()
}
@@ -223,6 +225,7 @@ func main() {
Listeners: &sync.Map{},
Close: make(chan bool),
Messages: make(chan string),
Session: make(chan bool),
}

state.SSHConnections.Store(sshConn.RemoteAddr(), holderConn)
@@ -233,15 +236,15 @@ func main() {
if *cleanupUnbound {
go func() {
select {
case <-time.NewTimer(1 * time.Second).C:
case <-time.After(1 * time.Second):
count := 0
holderConn.Listeners.Range(func(key, value interface{}) bool {
count++
return true
})

if count == 0 {
holderConn.Messages <- "No forwarding requests sent. Closing connection."
sendMessage(holderConn, "No forwarding requests sent. Closing connection.")
time.Sleep(1 * time.Millisecond)
holderConn.CleanUp(state)
}
@@ -144,7 +144,7 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state
}
}

sshConn.Messages <- requestMessages
sendMessage(sshConn, requestMessages)

go func() {
<-sshConn.Close
@@ -168,7 +168,7 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state

newChan, newReqs, err := sshConn.SSHConn.OpenChannel("forwarded-tcpip", ssh.Marshal(resp))
if err != nil {
sshConn.Messages <- err.Error()
sendMessage(sshConn, err.Error())
cl.Close()
continue
}
@@ -302,7 +302,7 @@ func getOpenHost(addr string, state *State, sshConn *SSHConnection) string {
}
reportUnavailable := func(unavailable bool) {
if first && unavailable {
sshConn.Messages <- "This subdomain is unavaible. Assigning a random subdomain."
sendMessage(sshConn, "This subdomain is unavaible. Assigning a random subdomain.")
}
}

@@ -337,7 +337,7 @@ func getOpenAlias(addr string, port string, state *State, sshConn *SSHConnection
}
reportUnavailable := func(unavailable bool) {
if first && unavailable {
sshConn.Messages <- "This alias is unavaible. Assigning a random alias."
sendMessage(sshConn, "This alias is unavaible. Assigning a random alias.")
}
}

@@ -390,3 +390,17 @@ func RandStringBytesMaskImprSrc(n int) string {

return string(b)
}

func sendMessage(sshConn *SSHConnection, message string) {
for i := 0; i < 2; {
select {
case <-sshConn.Close:
return
case sshConn.Messages <- message:
return
default:
time.Sleep(20 * time.Millisecond)
i++
}
}
}

0 comments on commit 67819d8

Please sign in to comment.
You can’t perform that action at this time.