Browse Source

doc updates

pull/2/head v1.3.1
AJ ONeal 5 years ago
parent
commit
959268bf31
  1. 16
      doc.go
  2. 117
      sclient.go

16
doc.go

@ -1,24 +1,32 @@
/* /*
Package sclient unwraps SSL.
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 be able to take
advantage of the features modern TLS, such as ALPN and SNI
security protocols - like SSH, OpenVPN, and Postgres - to take
advantage of the features of 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.
Try the CLI 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 get git.rootprojects.org/root/sclient.go/cmd/sclient
go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 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
https://telebit.cloud/sclient
Package Basics Package Basics
The general use of
servername := "example.com" servername := "example.com"
sclient := &sclient.Tunnel{ sclient := &sclient.Tunnel{
@ -31,8 +39,6 @@ Package Basics
err := sclient.DialAndListen() err := sclient.DialAndListen()
Pre-built versions for various platforms are also available at
https://telebit.cloud/sclient
*/ */
package sclient package sclient

117
sclient.go

@ -10,6 +10,66 @@ 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
}
// 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, 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)
}
}
// 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
@ -40,15 +100,6 @@ 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 {
@ -109,51 +160,3 @@ func (t *Tunnel) handleConnection(remote string, conn netReadWriteCloser) {
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)
}
}

Loading…
Cancel
Save