Skip to content

Commit 03f2cab

Browse files
committed
init
0 parents  commit 03f2cab

File tree

5 files changed

+285
-0
lines changed

5 files changed

+285
-0
lines changed

chisel-forward/main.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"flag"
6+
"fmt"
7+
"log"
8+
"os"
9+
10+
"github.com/jpillora/chisel"
11+
)
12+
13+
const help = `
14+
Usage: chisel-forward [--auth str] remote [remote] [remote]
15+
16+
where a remote is in the form:
17+
example.com:3000 (http://0.0.0.0:3000 => http://example.com:3000)
18+
3000:google.com:80 (http://0.0.0.0:3000 => http://google.com:80)
19+
20+
`
21+
22+
func main() {
23+
auth := flag.String("auth", "", "Optional authentication")
24+
flag.Usage = func() {
25+
fmt.Fprintf(os.Stderr, help)
26+
os.Exit(1)
27+
}
28+
flag.Parse()
29+
args := flag.Args()
30+
31+
c := &chisel.Config{
32+
Version: chisel.Version,
33+
Auth: *auth,
34+
}
35+
36+
for _, a := range args {
37+
r, err := chisel.DecodeRemote(a)
38+
if err != nil {
39+
log.Fatalf("Remote decode failed: %s", err)
40+
}
41+
c.Remotes = append(c.Remotes, r)
42+
}
43+
44+
if len(c.Remotes) == 0 {
45+
log.Fatalf("At least one remote is required")
46+
}
47+
48+
fmt.Printf("Forwarding:\n")
49+
for i, r := range c.Remotes {
50+
fmt.Printf(" [#%d] %s:%s -> %s:%s\n", i+1, r.LocalHost, r.LocalPort, r.RemoteHost, r.RemotePort)
51+
}
52+
53+
b, _ := json.Marshal(c)
54+
55+
fmt.Printf("%s", b)
56+
}

chiseld/main.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"log"
7+
"net/http"
8+
"os"
9+
10+
"github.com/jpillora/chisel"
11+
"golang.org/x/net/websocket"
12+
)
13+
14+
func main() {
15+
16+
auth := os.Getenv("AUTH")
17+
18+
handshakeWS := func(h string) (*chisel.Config, error) {
19+
c, err := chisel.DecodeConfig(h)
20+
if err != nil {
21+
return nil, err
22+
}
23+
if chisel.Version != c.Version {
24+
return nil, fmt.Errorf("Version mismatch")
25+
}
26+
if auth != "" {
27+
if auth != c.Auth {
28+
return nil, fmt.Errorf("Authentication failed")
29+
}
30+
}
31+
return c, nil
32+
}
33+
34+
handleWS := websocket.Handler(func(ws *websocket.Conn) {
35+
protos := ws.Config().Protocol
36+
if len(protos) != 1 {
37+
ws.Write([]byte("Handshake invalid"))
38+
ws.Close()
39+
return
40+
}
41+
config, err := handshakeWS(protos[0])
42+
if err != nil {
43+
ws.Write([]byte("Handshake denied: " + err.Error()))
44+
ws.Close()
45+
return
46+
}
47+
fmt.Printf("%+v\n", config)
48+
io.Copy(ws, ws)
49+
})
50+
51+
handleHTTP := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
52+
if r.Header.Get("Upgrade") == "websocket" {
53+
handleWS.ServeHTTP(w, r)
54+
} else {
55+
w.WriteHeader(200)
56+
w.Write([]byte("hello world\n"))
57+
}
58+
})
59+
60+
//get port
61+
port := os.Getenv("PORT")
62+
if port == "" {
63+
port = "8080"
64+
}
65+
//listen
66+
log.Println("listening on " + port)
67+
log.Fatal(http.ListenAndServe(":"+port, handleHTTP))
68+
}

config.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package chisel
2+
3+
import (
4+
"encoding/hex"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
)
9+
10+
type Config struct {
11+
Version string
12+
Auth string
13+
Remotes []*Remote
14+
}
15+
16+
const pre = "chisel-"
17+
18+
func DecodeConfig(s string) (*Config, error) {
19+
if !strings.HasPrefix(s, pre) {
20+
return nil, fmt.Errorf("Invalid config")
21+
}
22+
s = strings.TrimPrefix(s, pre)
23+
b, err := hex.DecodeString(s)
24+
if err != nil {
25+
return nil, fmt.Errorf("Invalid hex config")
26+
}
27+
c := &Config{}
28+
err = json.Unmarshal(b, c)
29+
if err != nil {
30+
return nil, fmt.Errorf("Invalid JSON config")
31+
}
32+
return c, nil
33+
}
34+
35+
func EncodeConfig(c *Config) (string, error) {
36+
b, err := json.Marshal(c)
37+
if err != nil {
38+
return "", err
39+
}
40+
return pre + hex.EncodeToString(b), nil
41+
}

remote.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package chisel
2+
3+
import (
4+
"errors"
5+
"net/url"
6+
"regexp"
7+
"strings"
8+
)
9+
10+
// short-hand conversions
11+
// foobar.com:3000 ->
12+
// local 127.0.0.1:3000
13+
// remote foobar.com:3000
14+
// 3000:google.com:80 ->
15+
// local 127.0.0.1:3000
16+
// remote google.com:80
17+
// 192.168.0.1:3000:google.com:80 ->
18+
// local 192.168.0.1:3000
19+
// remote google.com:80
20+
21+
type Remote struct {
22+
LocalHost, LocalPort, RemoteHost, RemotePort string
23+
}
24+
25+
func DecodeRemote(s string) (*Remote, error) {
26+
parts := strings.Split(s, ":")
27+
28+
if len(parts) <= 0 || len(parts) >= 5 {
29+
return nil, errors.New("Invalid remote")
30+
}
31+
32+
r := &Remote{}
33+
34+
//TODO fix up hacky decode
35+
for i := len(parts) - 1; i >= 0; i-- {
36+
p := parts[i]
37+
38+
if isPort(p) {
39+
if r.LocalPort == "" {
40+
r.LocalPort = p
41+
r.RemotePort = p
42+
} else {
43+
r.RemotePort = p
44+
}
45+
continue
46+
}
47+
48+
if r.RemotePort == "" && r.LocalPort == "" {
49+
return nil, errors.New("Missing ports")
50+
}
51+
52+
if !isHTTP.MatchString(p) {
53+
p = "http://" + p
54+
}
55+
56+
if !isHost(p) {
57+
return nil, errors.New("Invalid host")
58+
}
59+
60+
if r.RemoteHost == "" {
61+
r.RemoteHost = p
62+
} else {
63+
r.LocalHost = p
64+
}
65+
}
66+
if r.LocalHost == "" {
67+
r.LocalHost = "http://0.0.0.0"
68+
}
69+
if r.RemoteHost == "" {
70+
return nil, errors.New("Missing remote host")
71+
}
72+
return r, nil
73+
}
74+
75+
var isPortRegExp = regexp.MustCompile(`^\d+$`)
76+
77+
func isPort(s string) bool {
78+
if !isPortRegExp.MatchString(s) {
79+
return false
80+
}
81+
return true
82+
}
83+
84+
var isHTTP = regexp.MustCompile(`^http?:\/\/`)
85+
86+
func isHost(s string) bool {
87+
_, err := url.Parse(s)
88+
if err != nil {
89+
return false
90+
}
91+
return true
92+
}
93+
94+
// func EncodeRemote(r *Remote) (string, error) {
95+
// s := ""
96+
// n := 0
97+
// if r.RemotePort != "" {
98+
// s = r.RemotePort
99+
// n++
100+
// }
101+
// if r.RemoteHost != "" {
102+
// s = r.RemoteHost + ":" + s
103+
// n++
104+
// }
105+
// if r.LocalPort != "" {
106+
// s = r.LocalPort + ":" + s
107+
// n++
108+
// }
109+
// if r.LocalHost != "" {
110+
// s = r.LocalHost + ":" + s
111+
// n++
112+
// }
113+
// if n == 0 {
114+
// return "", errors.New("Invalid remote")
115+
// }
116+
// return s, nil
117+
// }

version.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package chisel
2+
3+
const Version = "1"

0 commit comments

Comments
 (0)