Skip to content

This commit implements Feature Request #59 #166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chclient

import (
"context"
"errors"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -73,12 +74,18 @@ func NewClient(config *Config) (*Client, error) {
//swap to websockets scheme
u.Scheme = strings.Replace(u.Scheme, "http", "ws", 1)
shared := &chshare.Config{}
stdioCnt := 0
createSocksServer := false
for _, s := range config.Remotes {
r, err := chshare.DecodeRemote(s)
if err != nil {
return nil, fmt.Errorf("Failed to decode remote '%s': %s", s, err)
}
if r.Stdio {
stdioCnt++
}
if stdioCnt > 1 {
return nil, errors.New("Only one stdio is allowed")
if r.Socks && r.Reverse {
createSocksServer = true
}
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ var clientHelp = `
socks
5000:socks
R:2222:localhost:22
stdio:example.com:22
R:socks
R:5000:socks

Expand All @@ -270,6 +271,13 @@ var clientHelp = `
default socks port (1080) and terminate the connection at the
client's internal SOCKS5 proxy.

When stdio is used as local-host, the tunnel will connect standard
input/output of this program with the remote. This is useful when
combined with ssh ProxyCommand. You can use
ssh -o ProxyCommand='chisel client chiselserver stdio:%h:%p' \
[email protected]
to connect to an SSH server through the tunnel.

Options:

--fingerprint, A *strongly recommended* fingerprint string
Expand Down
2 changes: 1 addition & 1 deletion share/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func NewLogger(prefix string) *Logger {
func NewLoggerFlag(prefix string, flag int) *Logger {
l := &Logger{
prefix: prefix,
logger: log.New(os.Stdout, "", flag),
logger: log.New(os.Stderr, "", flag),
Info: false,
Debug: false,
}
Expand Down
22 changes: 18 additions & 4 deletions share/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,25 @@ func NewTCPProxy(logger *Logger, ssh GetSSHConn, index int, remote *Remote) *TCP
}

func (p *TCPProxy) Start(ctx context.Context) error {
l, err := net.Listen("tcp4", p.remote.LocalHost+":"+p.remote.LocalPort)
if err != nil {
return fmt.Errorf("%s: %s", p.Logger.Prefix(), err)
if p.remote.Stdio {
go func() {
for {
p.accept(Stdio)
select {
case <-ctx.Done():
return
default:
// the connection is not ready yet
}
}
}()
} else {
l, err := net.Listen("tcp4", p.remote.LocalHost+":"+p.remote.LocalPort)
if err != nil {
return fmt.Errorf("%s: %s", p.Logger.Prefix(), err)
}
go p.listen(ctx, l)
}
go p.listen(ctx, l)
return nil
}

Expand Down
24 changes: 22 additions & 2 deletions share/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ import (
// 192.168.0.1:3000:google.com:80 ->
// local 192.168.0.1:3000
// remote google.com:80
// 127.0.0.1:1080:socks
// local 127.0.0.1:1080
// remote socks
// stdio:example.com:22
// local stdio
// remote example.com:22

type Remote struct {
LocalHost, LocalPort, RemoteHost, RemotePort string
Socks, Reverse bool
Socks, Reverse, Stdio bool
}

const revPrefix = "R:"
Expand All @@ -46,6 +52,10 @@ func DecodeRemote(s string) (*Remote, error) {
r.Socks = true
continue
}
if i == 0 && p == "stdio" {
r.Stdio = true
continue
}
if isPort(p) {
if !r.Socks && r.RemotePort == "" {
r.RemotePort = p
Expand Down Expand Up @@ -80,6 +90,9 @@ func DecodeRemote(s string) (*Remote, error) {
if !r.Socks && r.RemoteHost == "" {
r.RemoteHost = "0.0.0.0"
}
if r.Stdio && r.Reverse {
return nil, errors.New("stdio cannot be used with reverse tunnel")
}
return r, nil
}

Expand All @@ -106,7 +119,14 @@ func (r *Remote) String() string {
if r.Reverse {
tag = revPrefix
}
return tag + r.LocalHost + ":" + r.LocalPort + "=>" + r.Remote()
return tag + r.Local() + "=>" + r.Remote()
}

func (r *Remote) Local() string {
if r.Stdio {
return "stdio"
}
return r.LocalHost + ":" + r.LocalPort
}

func (r *Remote) Remote() string {
Expand Down
23 changes: 23 additions & 0 deletions share/stdio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package chshare

import (
"os"
)


type stdio struct {}

var Stdio = &stdio{}

func (t *stdio) Read(b []byte) (n int, err error) {
return os.Stdin.Read(b)
}

func (t *stdio) Write(b []byte) (n int, err error) {
return os.Stdout.Write(b)
}

// We do not close stdio
func (t *stdio) Close() error {
return nil
}