mirror of
				https://github.com/therootcompany/sclient
				synced 2024-11-16 17:09:00 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "master" and "v1.3.0" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1 @@ | |||||||
| /sclient |  | ||||||
| /cmd/sclient/sclient |  | ||||||
| 
 |  | ||||||
| dist | dist | ||||||
|  | |||||||
| @ -1,37 +0,0 @@ | |||||||
| before: |  | ||||||
|   hooks: |  | ||||||
|     - go mod download |  | ||||||
|     - go generate ./... |  | ||||||
| builds: |  | ||||||
|   - main: ./cmd/sclient/main.go |  | ||||||
|     env: |  | ||||||
|       - CGO_ENABLED=0 |  | ||||||
|     goos: |  | ||||||
|       - linux |  | ||||||
|       - windows |  | ||||||
|       - darwin |  | ||||||
|     goarch: |  | ||||||
|       - 386 |  | ||||||
|       - amd64 |  | ||||||
|       - arm |  | ||||||
|       - arm64 |  | ||||||
|     goarm: |  | ||||||
|       - 6 |  | ||||||
|       - 7 |  | ||||||
| archives: |  | ||||||
|   - replacements: |  | ||||||
|       386: i386 |  | ||||||
|       amd64: x86_64 |  | ||||||
|     format_overrides: |  | ||||||
|       - goos: windows |  | ||||||
|         format: zip |  | ||||||
| checksum: |  | ||||||
|   name_template: 'checksums.txt' |  | ||||||
| snapshot: |  | ||||||
|   name_template: "{{ .Tag }}-next" |  | ||||||
| changelog: |  | ||||||
|   sort: asc |  | ||||||
|   filters: |  | ||||||
|     exclude: |  | ||||||
|       - '^docs:' |  | ||||||
|       - '^test:' |  | ||||||
							
								
								
									
										114
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								README.md
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | |||||||
| # sclient | sclient.go | ||||||
|  | ========== | ||||||
| 
 | 
 | ||||||
| Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. | Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. | ||||||
| 
 | 
 | ||||||
| @ -7,75 +8,81 @@ Also ideal for multiplexing a single port with multiple protocols using SNI. | |||||||
| Unwrap a TLS connection: | Unwrap a TLS connection: | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| sclient whatever.com:443 localhost:3000 | $ sclient whatever.com:443 localhost:3000 | ||||||
| 
 |  | ||||||
| > [listening] whatever.com:443 <= localhost:3000 | > [listening] whatever.com:443 <= localhost:3000 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Connect via Telnet | Connect via Telnet | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| telnet localhost 3000 | $ telnet localhost 3000 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Connect via netcat (nc) | Connect via netcat (nc) | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| nc localhost 3000 | $ nc localhost 3000 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| cURL | cURL | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| curl http://localhost:3000 -H 'Host: whatever.com' | $ curl http://localhost:3000 -H 'Host: whatever.com' | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| A poor man's (or Windows user's) makeshift replacement for `openssl s_client`, `stunnel`, or `socat`. | A poor man's (or Windows user's) makeshift replacement for `openssl s_client`, `stunnel`, or `socat`. | ||||||
| 
 | 
 | ||||||
| # Table of Contents | Install | ||||||
| 
 | ======= | ||||||
| - [Install](#install) |  | ||||||
| - [Usage](#usage) |  | ||||||
| - [Examples](#examples) |  | ||||||
| - [Build from Source](#build-from-source) |  | ||||||
| 
 |  | ||||||
| # Install |  | ||||||
| 
 |  | ||||||
| ### Mac, Linux |  | ||||||
| 
 |  | ||||||
| ```bash |  | ||||||
| curl -sS https://webinstall.dev/sclient | bash |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ```bash |  | ||||||
| curl.exe -A MS https://webinstall.dev/sclient | powershell |  | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| ### Downloads | ### Downloads | ||||||
| 
 | 
 | ||||||
| Check the [Github Releases](https://github.com/therootcompany/sclient/releases) for | * [Windows 10](https://telebit.cloud/sclient/dist/windows/amd64/sclient.exe) | ||||||
|  | * [Mac OS X](https://telebit.cloud/sclient/dist/darwin/amd64/sclient) | ||||||
|  | * [Linux (x64)](https://telebit.cloud/sclient/dist/linux/amd64/sclient) | ||||||
|  | * [Raspberry Pi (armv7)](https://telebit.cloud/sclient/dist/linux/armv7/sclient) | ||||||
|  | * more downloads <https://telebit.cloud/sclient/> | ||||||
| 
 | 
 | ||||||
| - macOS (x64) Apple Silicon [coming soon](https://github.com/golang/go/issues/39782) | ### Build from source | ||||||
| - Linux (x64, i386, arm64, arm6, arm7) |  | ||||||
| - Windows 10 (x64, i386) |  | ||||||
| 
 | 
 | ||||||
| # Usage | For the moment you'll have to install go and compile `sclient` yourself: | ||||||
|  | 
 | ||||||
|  | * <https://golang.org/doc/install#install> | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | git clone https://git.rootprojects.org/root/sclient.go.git | ||||||
|  | pushd sclient.go | ||||||
|  | go build -o dist/sclient cmd/sclient/main.go | ||||||
|  | rsync -av dist/sclient /usr/local/bin/sclient | ||||||
|  | sclient example.com:443 localhost:3000 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Or | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | go get git.rootprojects.org/root/sclient.go/cmd/sclient | ||||||
|  | go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Usage | ||||||
|  | ===== | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| sclient [flags] <remote> <local> | sclient [flags] <remote> <local> | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| - flags | * flags | ||||||
|   - -k, --insecure ignore invalid TLS (SSL/HTTPS) certificates |   * -k, --insecure ignore invalid TLS (SSL/HTTPS) certificates | ||||||
|   - --servername <string> spoof SNI (to disable use IP as <remote> and do not use this option) |   * --servername <string> spoof SNI (to disable use IP as <remote> and do not use this option) | ||||||
| - remote | * remote | ||||||
|   - must have servername (i.e. example.com) |   * must have servername (i.e. example.com) | ||||||
|   - port is optional (default is 443) |   * port is optional (default is 443) | ||||||
| - local | * local | ||||||
|   - address is optional (default is localhost) |   * address is optional (default is localhost) | ||||||
|   - must have port (i.e. 3000) |   * must have port (i.e. 3000) | ||||||
| 
 | 
 | ||||||
| # Examples | Examples | ||||||
|  | ======== | ||||||
| 
 | 
 | ||||||
| Bridge between `telebit.cloud` and local port `3000`. | Bridge between `telebit.cloud` and local port `3000`. | ||||||
| 
 | 
 | ||||||
| @ -120,32 +127,3 @@ sclient --servername "Robert'); DROP TABLE Students;" -k example.com localhost:3 | |||||||
| ```bash | ```bash | ||||||
| sclient --servername "../../../.hidden/private.txt" -k example.com localhost:3000 | sclient --servername "../../../.hidden/private.txt" -k example.com localhost:3000 | ||||||
| ``` | ``` | ||||||
| 
 |  | ||||||
| # Build from source |  | ||||||
| 
 |  | ||||||
| You'll need to install [Go](https://golang.org). |  | ||||||
| See [webinstall.dev/golang](https://webinstall.dev/golang) for install instructions. |  | ||||||
| 
 |  | ||||||
| ```bash |  | ||||||
| curl -sS https://webinstall.dev/golang | bash |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Then you can install and run as per usual. |  | ||||||
| 
 |  | ||||||
| ```bash |  | ||||||
| git clone https://git.rootprojects.org/root/sclient.go.git |  | ||||||
| 
 |  | ||||||
| pushd sclient.go |  | ||||||
|   go build -o dist/sclient cmd/sclient/main.go |  | ||||||
|   sudo rsync -av dist/sclient /usr/local/bin/sclient |  | ||||||
| popd |  | ||||||
| 
 |  | ||||||
| sclient example.com:443 localhost:3000 |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## Install or Run with Go |  | ||||||
| 
 |  | ||||||
| ```bash |  | ||||||
| go get git.rootprojects.org/root/sclient.go/cmd/sclient |  | ||||||
| go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 |  | ||||||
| ``` |  | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								build-all.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								build-all.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | #GOOS=windows GOARCH=amd64 go install | ||||||
|  | go tool dist list | ||||||
|  | 
 | ||||||
|  | gocmd=cmd/sclient/main.go | ||||||
|  | golib="" | ||||||
|  | echo "" | ||||||
|  | 
 | ||||||
|  | echo "" | ||||||
|  | echo "Windows amd64" | ||||||
|  | GOOS=windows GOARCH=amd64 go build -o dist/windows/amd64/sclient.exe $gocmd $golib | ||||||
|  | echo "Windows 386" | ||||||
|  | GOOS=windows GOARCH=386 go build -o dist/windows/386/sclient.exe $gocmd $golib | ||||||
|  | 
 | ||||||
|  | echo "" | ||||||
|  | echo "Darwin (macOS) amd64" | ||||||
|  | GOOS=darwin GOARCH=amd64 go build -o dist/darwin/amd64/sclient $gocmd $golib | ||||||
|  | 
 | ||||||
|  | echo "" | ||||||
|  | echo "Linux amd64" | ||||||
|  | GOOS=linux GOARCH=amd64 go build -o dist/linux/amd64/sclient $gocmd $golib | ||||||
|  | echo "Linux 386" | ||||||
|  | 
 | ||||||
|  | echo "" | ||||||
|  | GOOS=linux GOARCH=386 go build -o dist/linux/386/sclient $gocmd $golib | ||||||
|  | echo "RPi 3 B+ ARMv7" | ||||||
|  | GOOS=linux GOARCH=arm GOARM=7 go build -o dist/linux/armv7/sclient $gocmd $golib | ||||||
|  | echo "RPi Zero ARMv5" | ||||||
|  | GOOS=linux GOARCH=arm GOARM=5 go build -o dist/linux/armv5/sclient $gocmd $golib | ||||||
|  | 
 | ||||||
|  | echo "" | ||||||
|  | echo "" | ||||||
|  | 
 | ||||||
|  | rsync -av ./dist/ root@telebit.cloud:/opt/telebit-relay/lib/extensions/admin/sclient/dist/ | ||||||
| @ -10,49 +10,23 @@ import ( | |||||||
| 	sclient "git.rootprojects.org/root/sclient.go" | 	sclient "git.rootprojects.org/root/sclient.go" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( |  | ||||||
| 	// commit refers to the abbreviated commit hash |  | ||||||
| 	commit = "0000000" |  | ||||||
| 	// version refers to the most recent tag, plus any commits made since then |  | ||||||
| 	version = "v0.0.0-pre0+0000000" |  | ||||||
| 	// GitTimestamp refers to the timestamp of the most recent commit |  | ||||||
| 	date = "0000-00-00T00:00:00+0000" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func ver() string { |  | ||||||
| 	return fmt.Sprintf("sclient %s (%s) %s", version, commit[:7], date) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func usage() { | func usage() { | ||||||
| 	fmt.Fprintf(os.Stderr, "\n%s\n"+ | 	fmt.Fprintf(os.Stderr, "\nusage: sclient <remote> <local>\n"+ | ||||||
| 		"\nusage: sclient <remote> <local>\n"+ |  | ||||||
| 		"\n"+ | 		"\n"+ | ||||||
| 		"   ex: sclient example.com 3000\n"+ | 		"   ex: sclient example.com 3000\n"+ | ||||||
| 		"      (sclient example.com:443 localhost:3000)\n"+ | 		"      (sclient example.com:443 localhost:3000)\n"+ | ||||||
| 		"\n"+ | 		"\n"+ | ||||||
| 		"   ex: sclient example.com:8443 0.0.0.0:4080\n"+ | 		"   ex: sclient example.com:8443 0.0.0.0:4080\n"+ | ||||||
| 		"\n"+ | 		"\n") | ||||||
| 		"   ex: sclient example.com:443 -\n"+ |  | ||||||
| 		"\n", ver()) |  | ||||||
| 	flag.PrintDefaults() | 	flag.PrintDefaults() | ||||||
| 	fmt.Println() | 	fmt.Println() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| 	if len(os.Args) >= 2 { |  | ||||||
| 		if "version" == strings.TrimLeft(os.Args[1], "-") { |  | ||||||
| 			fmt.Printf("%s\n", ver()) |  | ||||||
| 			os.Exit(0) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	flag.Usage = usage | 	flag.Usage = usage | ||||||
| 	insecure := flag.Bool("k", false, "alias for --insecure") | 	insecure := flag.Bool("k", false, "ignore bad TLS/SSL/HTTPS certificates") | ||||||
| 	silent := flag.Bool("s", false, "alias of --silent") |  | ||||||
| 	servername := flag.String("servername", "", "specify a servername different from <remote> (to disable SNI use an IP as <remote> and do use this option)") | 	servername := flag.String("servername", "", "specify a servername different from <remote> (to disable SNI use an IP as <remote> and do use this option)") | ||||||
| 	flag.BoolVar(insecure, "insecure", false, "ignore bad TLS/SSL/HTTPS certificates") | 	flag.BoolVar(insecure, "insecure", false, "ignore bad TLS/SSL/HTTPS certificates") | ||||||
| 	flag.BoolVar(silent, "silent", false, "less verbose output") |  | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| 	remotestr := flag.Arg(0) | 	remotestr := flag.Arg(0) | ||||||
| 	localstr := flag.Arg(1) | 	localstr := flag.Arg(1) | ||||||
| @ -73,7 +47,6 @@ func main() { | |||||||
| 		LocalAddress:       "localhost", | 		LocalAddress:       "localhost", | ||||||
| 		InsecureSkipVerify: *insecure, | 		InsecureSkipVerify: *insecure, | ||||||
| 		ServerName:         *servername, | 		ServerName:         *servername, | ||||||
| 		Silent:             *silent, |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	remote := strings.Split(remotestr, ":") | 	remote := strings.Split(remotestr, ":") | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								doc.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								doc.go
									
									
									
									
									
								
							| @ -1,20 +1,23 @@ | |||||||
| /* | /* | ||||||
| sclient unwraps SSL. | Package sclient unwraps SSL. | ||||||
| 
 | 
 | ||||||
| It makes secure remote connections (such as HTTPS) available locally as plain-text connections - | It makes secure remote connections (such as HTTPS) available locally as plain-text connections - | ||||||
| similar to `stunnel` or `openssl s_client`. | similar to `stunnel` or `openssl s_client`. | ||||||
| 
 | 
 | ||||||
| There are a variety of reasons that you might want to do that, | There are a variety of reasons that you might want to do that, | ||||||
| but we created it specifically to be able to upgrade applications with legacy | but we created it specifically to be able to upgrade applications with legacy | ||||||
| security protocols - like SSH, OpenVPN, and Postgres - to take | security protocols - like SSH, OpenVPN, and Postgres - to be able to take | ||||||
| advantage of the features of modern TLS, such as ALPN and SNI | advantage of the features modern TLS, such as ALPN and SNI | ||||||
| (which makes them routable through almost every type of firewall). | (which makes them routable through almost every type of firewall). | ||||||
| 
 | 
 | ||||||
| See https://telebit.cloud/sclient for more info. | See https://telebit.cloud/sclient for more info. | ||||||
| 
 | 
 | ||||||
| Package Basics | Try the CLI | ||||||
| 
 | 
 | ||||||
| In the simplest case you'll just be setting a ServerName and connection info: | 	go get git.rootprojects.org/root/sclient.go/cmd/sclient | ||||||
|  | 	go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 | ||||||
|  | 
 | ||||||
|  | Package Basics | ||||||
| 
 | 
 | ||||||
| 	servername := "example.com" | 	servername := "example.com" | ||||||
| 
 | 
 | ||||||
| @ -28,14 +31,6 @@ In the simplest case you'll just be setting a ServerName and connection info: | |||||||
| 
 | 
 | ||||||
| 	err := sclient.DialAndListen() | 	err := sclient.DialAndListen() | ||||||
| 
 | 
 | ||||||
| Try the CLI |  | ||||||
| 
 |  | ||||||
| If you'd like to better understand what sclient does, you can try it out with `go run`: |  | ||||||
| 
 |  | ||||||
| 	go get git.rootprojects.org/root/sclient.go/cmd/sclient |  | ||||||
| 	go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 |  | ||||||
| 	curl http://localhost:3000 -H "Host: example.com" |  | ||||||
| 
 |  | ||||||
| Pre-built versions for various platforms are also available at | Pre-built versions for various platforms are also available at | ||||||
| https://telebit.cloud/sclient | https://telebit.cloud/sclient | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										136
									
								
								sclient.go
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								sclient.go
									
									
									
									
									
								
							| @ -10,69 +10,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Tunnel specifies which remote encrypted connection to make available as a plain connection locally. |  | ||||||
| type Tunnel struct { |  | ||||||
| 	RemoteAddress      string |  | ||||||
| 	RemotePort         int |  | ||||||
| 	LocalAddress       string |  | ||||||
| 	LocalPort          int |  | ||||||
| 	InsecureSkipVerify bool |  | ||||||
| 	ServerName         string |  | ||||||
| 	Silent             bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // DialAndListen will create a test TLS connection to the remote address and then |  | ||||||
| // begin listening locally. Each local connection will result in a separate remote connection. |  | ||||||
| func (t *Tunnel) DialAndListen() error { |  | ||||||
| 	remote := t.RemoteAddress + ":" + strconv.Itoa(t.RemotePort) |  | ||||||
| 	conn, err := tls.Dial("tcp", remote, |  | ||||||
| 		&tls.Config{ |  | ||||||
| 			ServerName:         t.ServerName, |  | ||||||
| 			InsecureSkipVerify: t.InsecureSkipVerify, |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Fprintf(os.Stderr, "[warn] '%s' may not be accepting connections: %s\n", remote, err) |  | ||||||
| 	} else { |  | ||||||
| 		conn.Close() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// use stdin/stdout |  | ||||||
| 	if "-" == t.LocalAddress || "|" == t.LocalAddress { |  | ||||||
| 		var name string |  | ||||||
| 		network := "stdio" |  | ||||||
| 		if "|" == t.LocalAddress { |  | ||||||
| 			name = "pipe" |  | ||||||
| 		} else { |  | ||||||
| 			name = "stdin" |  | ||||||
| 		} |  | ||||||
| 		conn := &stdnet{os.Stdin, os.Stdout, &stdaddr{net.UnixAddr{Name: name, Net: network}}} |  | ||||||
| 		t.handleConnection(remote, conn) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// use net.Conn |  | ||||||
| 	local := t.LocalAddress + ":" + strconv.Itoa(t.LocalPort) |  | ||||||
| 	ln, err := net.Listen("tcp", local) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !t.Silent { |  | ||||||
| 		fmt.Fprintf(os.Stdout, "[listening] %s:%d <= %s:%d\n", |  | ||||||
| 			t.RemoteAddress, t.RemotePort, t.LocalAddress, t.LocalPort) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for { |  | ||||||
| 		conn, err := ln.Accept() |  | ||||||
| 		if nil != err { |  | ||||||
| 			fmt.Fprintf(os.Stderr, "[error] %s\n", err) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		go t.handleConnection(remote, conn) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // I wonder if I can get this to exactly mirror UnixAddr without passing it in | // I wonder if I can get this to exactly mirror UnixAddr without passing it in | ||||||
| type stdaddr struct { | type stdaddr struct { | ||||||
| 	net.UnixAddr | 	net.UnixAddr | ||||||
| @ -103,6 +40,15 @@ type netReadWriteCloser interface { | |||||||
| 	RemoteAddr() net.Addr | 	RemoteAddr() net.Addr | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type Tunnel struct { | ||||||
|  | 	RemoteAddress      string | ||||||
|  | 	RemotePort         int | ||||||
|  | 	LocalAddress       string | ||||||
|  | 	LocalPort          int | ||||||
|  | 	InsecureSkipVerify bool | ||||||
|  | 	ServerName         string | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func pipe(r netReadWriteCloser, w netReadWriteCloser, t string) { | func pipe(r netReadWriteCloser, w netReadWriteCloser, t string) { | ||||||
| 	buffer := make([]byte, 2048) | 	buffer := make([]byte, 2048) | ||||||
| 	for { | 	for { | ||||||
| @ -113,7 +59,7 @@ func pipe(r netReadWriteCloser, w netReadWriteCloser, t string) { | |||||||
| 		if nil != err { | 		if nil != err { | ||||||
| 			//fmt.Fprintf(os.Stdout, "[debug] (%s:%d) error reading %s\n", t, count, err) | 			//fmt.Fprintf(os.Stdout, "[debug] (%s:%d) error reading %s\n", t, count, err) | ||||||
| 			if io.EOF != err { | 			if io.EOF != err { | ||||||
| 				fmt.Fprintf(os.Stderr, "[read error] (%s:%d) %s\n", t, count, err) | 				fmt.Fprintf(os.Stderr, "[read error] (%s:%s) %s\n", t, count, err) | ||||||
| 			} | 			} | ||||||
| 			r.Close() | 			r.Close() | ||||||
| 			//w.Close() | 			//w.Close() | ||||||
| @ -152,16 +98,62 @@ func (t *Tunnel) handleConnection(remote string, conn netReadWriteCloser) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !t.Silent { | 	if "stdio" == conn.RemoteAddr().Network() { | ||||||
| 		if "stdio" == conn.RemoteAddr().Network() { | 		fmt.Fprintf(os.Stdout, "(connected to %s:%d and reading from %s)\n", | ||||||
| 			fmt.Fprintf(os.Stdout, "(connected to %s:%d and reading from %s)\n", | 			t.RemoteAddress, t.RemotePort, conn.RemoteAddr().String()) | ||||||
| 				t.RemoteAddress, t.RemotePort, conn.RemoteAddr().String()) | 	} else { | ||||||
| 		} else { | 		fmt.Fprintf(os.Stdout, "[connect] %s => %s:%d\n", | ||||||
| 			fmt.Fprintf(os.Stdout, "[connect] %s => %s:%d\n", | 			strings.Replace(conn.RemoteAddr().String(), "[::1]:", "localhost:", 1), t.RemoteAddress, t.RemotePort) | ||||||
| 				strings.Replace(conn.RemoteAddr().String(), "[::1]:", "localhost:", 1), t.RemoteAddress, t.RemotePort) |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	go pipe(conn, sclient, "local") | 	go pipe(conn, sclient, "local") | ||||||
| 	pipe(sclient, conn, "remote") | 	pipe(sclient, conn, "remote") | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (t *Tunnel) DialAndListen() error { | ||||||
|  | 	remote := t.RemoteAddress + ":" + strconv.Itoa(t.RemotePort) | ||||||
|  | 	conn, err := tls.Dial("tcp", remote, | ||||||
|  | 		&tls.Config{ | ||||||
|  | 			ServerName:         t.ServerName, | ||||||
|  | 			InsecureSkipVerify: t.InsecureSkipVerify, | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Fprintf(os.Stderr, "[warn] '%s' may not be accepting connections: %s\n", remote, err) | ||||||
|  | 	} else { | ||||||
|  | 		conn.Close() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// use stdin/stdout | ||||||
|  | 	if "-" == t.LocalAddress || "|" == t.LocalAddress { | ||||||
|  | 		var name string | ||||||
|  | 		network := "stdio" | ||||||
|  | 		if "|" == t.LocalAddress { | ||||||
|  | 			name = "pipe" | ||||||
|  | 		} else { | ||||||
|  | 			name = "stdin" | ||||||
|  | 		} | ||||||
|  | 		conn := &stdnet{os.Stdin, os.Stdout, &stdaddr{net.UnixAddr{name, network}}} | ||||||
|  | 		t.handleConnection(remote, conn) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// use net.Conn | ||||||
|  | 	local := t.LocalAddress + ":" + strconv.Itoa(t.LocalPort) | ||||||
|  | 	ln, err := net.Listen("tcp", local) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fmt.Fprintf(os.Stdout, "[listening] %s:%d <= %s:%d\n", | ||||||
|  | 		t.RemoteAddress, t.RemotePort, t.LocalAddress, t.LocalPort) | ||||||
|  | 
 | ||||||
|  | 	for { | ||||||
|  | 		conn, err := ln.Accept() | ||||||
|  | 		if nil != err { | ||||||
|  | 			fmt.Fprintf(os.Stderr, "[error] %s\n", err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		go t.handleConnection(remote, conn) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,11 +0,0 @@ | |||||||
| # I like my yoda conditions ST1017 |  | ||||||
| checks = ["all", "-ST1017", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-ST1023"] |  | ||||||
| initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", |  | ||||||
| 	"EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", |  | ||||||
| 	"IP", "JSON", "QPS", "RAM", "RPC", "SLA", |  | ||||||
| 	"SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", |  | ||||||
| 	"UDP", "UI", "GID", "UID", "UUID", "URI", |  | ||||||
| 	"URL", "UTF8", "VM", "XML", "XMPP", "XSRF", |  | ||||||
| 	"XSS", "SIP", "RTP", "AMQP", "DB", "TS"] |  | ||||||
| dot_import_whitelist = [] |  | ||||||
| http_status_code_whitelist = ["200", "400", "404", "500"] |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user