mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Run go fmt
This commit is contained in:
parent
be91ff62ef
commit
c285f0990f
114
api.go
114
api.go
@ -1,59 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
//"strings"
|
||||
"net/http"
|
||||
"io"
|
||||
"encoding/json"
|
||||
//"fmt"
|
||||
//"strings"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Api struct {
|
||||
config *BoringProxyConfig
|
||||
auth *Auth
|
||||
tunMan *TunnelManager
|
||||
mux *http.ServeMux
|
||||
config *BoringProxyConfig
|
||||
auth *Auth
|
||||
tunMan *TunnelManager
|
||||
mux *http.ServeMux
|
||||
}
|
||||
|
||||
type CreateTunnelResponse struct {
|
||||
ServerAddress string `json:"server_address"`
|
||||
ServerPort int `json:"server_port"`
|
||||
ServerPublicKey string `json:"server_public_key"`
|
||||
TunnelPort int `json:"tunnel_port"`
|
||||
TunnelPrivateKey string `json:"tunnel_private_key"`
|
||||
ServerAddress string `json:"server_address"`
|
||||
ServerPort int `json:"server_port"`
|
||||
ServerPublicKey string `json:"server_public_key"`
|
||||
TunnelPort int `json:"tunnel_port"`
|
||||
TunnelPrivateKey string `json:"tunnel_private_key"`
|
||||
}
|
||||
|
||||
|
||||
func NewApi(config *BoringProxyConfig, auth *Auth, tunMan *TunnelManager) *Api {
|
||||
|
||||
api := &Api{config, auth, tunMan, nil}
|
||||
api := &Api{config, auth, tunMan, nil}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/tunnels", http.StripPrefix("/tunnels", http.HandlerFunc(api.handleTunnels)))
|
||||
mux.Handle("/tunnels", http.StripPrefix("/tunnels", http.HandlerFunc(api.handleTunnels)))
|
||||
|
||||
api.mux = mux
|
||||
api.mux = mux
|
||||
|
||||
return api
|
||||
return api
|
||||
}
|
||||
|
||||
|
||||
func (a *Api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
a.mux.ServeHTTP(w, r)
|
||||
a.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (a *Api) handleTunnels(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "POST":
|
||||
a.validateSession(http.HandlerFunc(a.handleCreateTunnel)).ServeHTTP(w, r)
|
||||
default:
|
||||
switch r.Method {
|
||||
case "POST":
|
||||
a.validateSession(http.HandlerFunc(a.handleCreateTunnel)).ServeHTTP(w, r)
|
||||
default:
|
||||
w.WriteHeader(405)
|
||||
w.Write([]byte("Invalid method for /tunnels"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Api) handleCreateTunnel(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
query := r.URL.Query()
|
||||
|
||||
if len(query["domain"]) != 1 {
|
||||
w.WriteHeader(400)
|
||||
@ -62,47 +60,47 @@ func (a *Api) handleCreateTunnel(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
domain := query["domain"][0]
|
||||
|
||||
port, privKey, err := a.tunMan.CreateTunnel(domain)
|
||||
if err != nil {
|
||||
port, privKey, err := a.tunMan.CreateTunnel(domain)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
io.WriteString(w, err.Error())
|
||||
io.WriteString(w, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
response := &CreateTunnelResponse{
|
||||
ServerAddress: a.config.AdminDomain,
|
||||
ServerPort: 22,
|
||||
ServerPublicKey: "",
|
||||
TunnelPort: port,
|
||||
TunnelPrivateKey: privKey,
|
||||
}
|
||||
response := &CreateTunnelResponse{
|
||||
ServerAddress: a.config.AdminDomain,
|
||||
ServerPort: 22,
|
||||
ServerPublicKey: "",
|
||||
TunnelPort: port,
|
||||
TunnelPrivateKey: privKey,
|
||||
}
|
||||
|
||||
responseJson, err := json.MarshalIndent(response, "", " ")
|
||||
if err != nil {
|
||||
responseJson, err := json.MarshalIndent(response, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error encoding response")
|
||||
io.WriteString(w, "Error encoding response")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
w.Write(responseJson)
|
||||
w.Write(responseJson)
|
||||
}
|
||||
|
||||
func (a *Api) validateSession(h http.Handler) http.Handler {
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token, err := extractToken("access_token", r)
|
||||
if err != nil {
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("No token provided"))
|
||||
return
|
||||
}
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token, err := extractToken("access_token", r)
|
||||
if err != nil {
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("No token provided"))
|
||||
return
|
||||
}
|
||||
|
||||
if !a.auth.Authorized(token) {
|
||||
w.WriteHeader(403)
|
||||
w.Write([]byte("Not authorized"))
|
||||
return
|
||||
}
|
||||
if !a.auth.Authorized(token) {
|
||||
w.WriteHeader(403)
|
||||
w.Write([]byte("Not authorized"))
|
||||
return
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
16
auth.go
16
auth.go
@ -20,7 +20,7 @@ type Auth struct {
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Email string
|
||||
Email string
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
@ -109,16 +109,16 @@ func (a *Auth) Verify(key string) (string, error) {
|
||||
|
||||
delete(a.pendingRequests, key)
|
||||
|
||||
token, err := genRandomKey()
|
||||
if err != nil {
|
||||
return "", errors.New("Error generating key")
|
||||
}
|
||||
token, err := genRandomKey()
|
||||
if err != nil {
|
||||
return "", errors.New("Error generating key")
|
||||
}
|
||||
|
||||
a.sessions[token] = &Session{Id: request.Email}
|
||||
a.sessions[token] = &Session{Id: request.Email}
|
||||
|
||||
saveJson(a.sessions, "sessions.json")
|
||||
saveJson(a.sessions, "sessions.json")
|
||||
|
||||
return token, nil
|
||||
return token, nil
|
||||
}
|
||||
|
||||
const chars string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
139
boringproxy.go
139
boringproxy.go
@ -4,16 +4,16 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.rice"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"html/template"
|
||||
"strconv"
|
||||
"sync"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
type BoringProxyConfig struct {
|
||||
@ -70,10 +70,10 @@ func NewBoringProxy() *BoringProxy {
|
||||
p := &BoringProxy{config, auth, tunMan, adminListener, certConfig}
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
p.handleAdminRequest(w, r)
|
||||
})
|
||||
p.handleAdminRequest(w, r)
|
||||
})
|
||||
|
||||
api := NewApi(config, auth, tunMan)
|
||||
api := NewApi(config, auth, tunMan)
|
||||
http.Handle("/api/", http.StripPrefix("/api", api))
|
||||
|
||||
go http.Serve(adminListener, nil)
|
||||
@ -106,26 +106,26 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
|
||||
case "/login":
|
||||
p.handleLogin(w, r)
|
||||
case "/":
|
||||
box, err := rice.FindBox("webui")
|
||||
if err != nil {
|
||||
box, err := rice.FindBox("webui")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error opening webui")
|
||||
io.WriteString(w, "Error opening webui")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
token, err := extractToken("access_token", r)
|
||||
if err != nil {
|
||||
|
||||
loginTemplate, err := box.String("login.tmpl")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error reading login.tmpl")
|
||||
return
|
||||
}
|
||||
loginTemplate, err := box.String("login.tmpl")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error reading login.tmpl")
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(401)
|
||||
io.WriteString(w, loginTemplate)
|
||||
io.WriteString(w, loginTemplate)
|
||||
return
|
||||
}
|
||||
|
||||
@ -135,26 +135,24 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
indexTemplate, err := box.String("index.tmpl")
|
||||
if err != nil {
|
||||
indexTemplate, err := box.String("index.tmpl")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error reading index.tmpl")
|
||||
io.WriteString(w, "Error reading index.tmpl")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
tmpl, err := template.New("test").Parse(indexTemplate)
|
||||
if err != nil {
|
||||
tmpl, err := template.New("test").Parse(indexTemplate)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
log.Println(err)
|
||||
io.WriteString(w, "Error compiling index.tmpl")
|
||||
log.Println(err)
|
||||
io.WriteString(w, "Error compiling index.tmpl")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
tmpl.Execute(w, p.tunMan.tunnels)
|
||||
|
||||
tmpl.Execute(w, p.tunMan.tunnels)
|
||||
|
||||
//io.WriteString(w, indexTemplate)
|
||||
//io.WriteString(w, indexTemplate)
|
||||
|
||||
case "/tunnels":
|
||||
|
||||
@ -174,7 +172,7 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
|
||||
p.handleTunnels(w, r)
|
||||
|
||||
case "/delete-tunnel":
|
||||
token, err := extractToken("access_token", r)
|
||||
token, err := extractToken("access_token", r)
|
||||
if err != nil {
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("No token provided"))
|
||||
@ -187,7 +185,7 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
r.ParseForm()
|
||||
|
||||
if len(r.Form["host"]) != 1 {
|
||||
w.WriteHeader(400)
|
||||
@ -198,7 +196,7 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
p.tunMan.DeleteTunnel(host)
|
||||
|
||||
http.Redirect(w, r, "/", 307)
|
||||
http.Redirect(w, r, "/", 307)
|
||||
default:
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Invalid endpoint"))
|
||||
@ -234,49 +232,48 @@ func (p *BoringProxy) handleTunnels(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (p *BoringProxy) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
query := r.URL.Query()
|
||||
key, exists := query["key"]
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
query := r.URL.Query()
|
||||
key, exists := query["key"]
|
||||
|
||||
if !exists {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "Must provide key for verification")
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "Must provide key for verification")
|
||||
return
|
||||
}
|
||||
|
||||
token, err := p.auth.Verify(key[0])
|
||||
token, err := p.auth.Verify(key[0])
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "Invalid key")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "Invalid key")
|
||||
return
|
||||
}
|
||||
|
||||
cookie := &http.Cookie{Name: "access_token", Value: token, Secure: true, HttpOnly: true}
|
||||
http.SetCookie(w, cookie)
|
||||
cookie := &http.Cookie{Name: "access_token", Value: token, Secure: true, HttpOnly: true}
|
||||
http.SetCookie(w, cookie)
|
||||
|
||||
http.Redirect(w, r, "/", 307)
|
||||
http.Redirect(w, r, "/", 307)
|
||||
|
||||
case "POST":
|
||||
|
||||
case "POST":
|
||||
r.ParseForm()
|
||||
|
||||
r.ParseForm()
|
||||
toEmail, ok := r.Form["email"]
|
||||
|
||||
toEmail, ok := r.Form["email"]
|
||||
if !ok {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Email required for login"))
|
||||
return
|
||||
}
|
||||
|
||||
if !ok {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Email required for login"))
|
||||
return
|
||||
}
|
||||
// run in goroutine because it can take some time to send the
|
||||
// email
|
||||
go p.auth.Login(toEmail[0], p.config)
|
||||
|
||||
// run in goroutine because it can take some time to send the
|
||||
// email
|
||||
go p.auth.Login(toEmail[0], p.config)
|
||||
|
||||
io.WriteString(w, "Check your email to finish logging in")
|
||||
default:
|
||||
io.WriteString(w, "Check your email to finish logging in")
|
||||
default:
|
||||
w.WriteHeader(405)
|
||||
w.Write([]byte("Invalid method for login"))
|
||||
}
|
||||
@ -284,7 +281,7 @@ func (p *BoringProxy) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (p *BoringProxy) handleCreateTunnel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
r.ParseForm()
|
||||
r.ParseForm()
|
||||
|
||||
if len(r.Form["host"]) != 1 {
|
||||
w.WriteHeader(400)
|
||||
@ -307,13 +304,13 @@ func (p *BoringProxy) handleCreateTunnel(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
err = p.tunMan.SetTunnel(host, port)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
io.WriteString(w, "Failed to get cert. Ensure your domain is valid")
|
||||
io.WriteString(w, "Failed to get cert. Ensure your domain is valid")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/", 303)
|
||||
http.Redirect(w, r, "/", 303)
|
||||
}
|
||||
|
||||
func (p *BoringProxy) handleConnection(clientConn net.Conn) {
|
||||
|
55
client.go
55
client.go
@ -1,64 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
||||
type BoringProxyClient struct {
|
||||
}
|
||||
|
||||
func NewBoringProxyClient() *BoringProxyClient {
|
||||
return &BoringProxyClient{}
|
||||
return &BoringProxyClient{}
|
||||
}
|
||||
|
||||
func (c *BoringProxyClient) Run() {
|
||||
log.Println("Run client")
|
||||
log.Println("Run client")
|
||||
|
||||
//var hostKey ssh.PublicKey
|
||||
//var hostKey ssh.PublicKey
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
config := &ssh.ClientConfig{
|
||||
User: "user",
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password("yolo"),
|
||||
ssh.Password("yolo"),
|
||||
},
|
||||
//HostKeyCallback: ssh.FixedHostKey(hostKey),
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
client, err := ssh.Dial("tcp", "boringproxy.io:2022", config)
|
||||
client, err := ssh.Dial("tcp", "boringproxy.io:2022", config)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to dial: ", err)
|
||||
}
|
||||
|
||||
tunnelRequests := client.HandleChannelOpen("boringproxy-tunnel")
|
||||
tunnelRequests := client.HandleChannelOpen("boringproxy-tunnel")
|
||||
|
||||
for req := range tunnelRequests {
|
||||
go handleTunnelRequest(req)
|
||||
}
|
||||
for req := range tunnelRequests {
|
||||
go handleTunnelRequest(req)
|
||||
}
|
||||
}
|
||||
|
||||
func handleTunnelRequest(req ssh.NewChannel) error {
|
||||
|
||||
tun, reqs, err := req.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tun, reqs, err := req.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go ssh.DiscardRequests(reqs)
|
||||
go ssh.DiscardRequests(reqs)
|
||||
|
||||
port := req.ExtraData()
|
||||
port := req.ExtraData()
|
||||
|
||||
fmt.Println(port)
|
||||
fmt.Println(port)
|
||||
|
||||
data, err := ioutil.ReadAll(tun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := ioutil.ReadAll(tun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(data))
|
||||
return nil
|
||||
fmt.Println(string(data))
|
||||
return nil
|
||||
}
|
||||
|
38
main.go
38
main.go
@ -1,31 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Invalid arguments")
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Invalid arguments")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
command := os.Args[1]
|
||||
command := os.Args[1]
|
||||
|
||||
switch command {
|
||||
case "server":
|
||||
log.Println("Starting up")
|
||||
proxy := NewBoringProxy()
|
||||
proxy.Run()
|
||||
switch command {
|
||||
case "server":
|
||||
log.Println("Starting up")
|
||||
proxy := NewBoringProxy()
|
||||
proxy.Run()
|
||||
|
||||
case "client":
|
||||
client := NewBoringProxyClient()
|
||||
client.Run()
|
||||
default:
|
||||
fmt.Println("Invalid command " + command)
|
||||
os.Exit(1)
|
||||
}
|
||||
case "client":
|
||||
client := NewBoringProxyClient()
|
||||
client.Run()
|
||||
default:
|
||||
fmt.Println("Invalid command " + command)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"io/ioutil"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
|
||||
type SshServer struct {
|
||||
config *ssh.ServerConfig
|
||||
listener net.Listener
|
||||
config *ssh.ServerConfig
|
||||
listener net.Listener
|
||||
}
|
||||
|
||||
|
||||
func NewSshServer() *SshServer {
|
||||
config := &ssh.ServerConfig{}
|
||||
config := &ssh.ServerConfig{}
|
||||
|
||||
privateBytes, err := ioutil.ReadFile("id_rsa_boringproxy")
|
||||
privateBytes, err := ioutil.ReadFile("id_rsa_boringproxy")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load private key: ", err)
|
||||
}
|
||||
@ -30,66 +28,66 @@ func NewSshServer() *SshServer {
|
||||
|
||||
config.AddHostKey(private)
|
||||
|
||||
listener, err := net.Listen("tcp", "0.0.0.0:2022")
|
||||
listener, err := net.Listen("tcp", "0.0.0.0:2022")
|
||||
if err != nil {
|
||||
log.Fatal("failed to listen for connection: ", err)
|
||||
}
|
||||
|
||||
server := &SshServer{config, listener}
|
||||
server := &SshServer{config, listener}
|
||||
|
||||
go server.acceptAll()
|
||||
go server.acceptAll()
|
||||
|
||||
return server
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *SshServer) acceptAll() {
|
||||
for {
|
||||
nConn, err := s.listener.Accept()
|
||||
if err != nil {
|
||||
log.Print("failed to accept incoming connection: ", err)
|
||||
continue
|
||||
}
|
||||
for {
|
||||
nConn, err := s.listener.Accept()
|
||||
if err != nil {
|
||||
log.Print("failed to accept incoming connection: ", err)
|
||||
continue
|
||||
}
|
||||
|
||||
go s.handleServerConn(nConn)
|
||||
}
|
||||
go s.handleServerConn(nConn)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SshServer) handleServerConn(nConn net.Conn) {
|
||||
|
||||
var password string
|
||||
var password string
|
||||
|
||||
s.config.PasswordCallback = func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
||||
password = string(pass)
|
||||
if c.User() == "user" && string(pass) == "yolo" {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("password rejected for %q", c.User())
|
||||
}
|
||||
|
||||
conn, chans, reqs, err := ssh.NewServerConn(nConn, s.config)
|
||||
if err != nil {
|
||||
log.Print("failed to handshake: ", err)
|
||||
return
|
||||
s.config.PasswordCallback = func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
||||
password = string(pass)
|
||||
if c.User() == "user" && string(pass) == "yolo" {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("password rejected for %q", c.User())
|
||||
}
|
||||
|
||||
fmt.Println(password)
|
||||
conn, chans, reqs, err := ssh.NewServerConn(nConn, s.config)
|
||||
if err != nil {
|
||||
log.Print("failed to handshake: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(password)
|
||||
|
||||
go ssh.DiscardRequests(reqs)
|
||||
|
||||
go func() {
|
||||
for newChannel := range chans {
|
||||
newChannel.Reject(ssh.ResourceShortage, "too bad")
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for newChannel := range chans {
|
||||
newChannel.Reject(ssh.ResourceShortage, "too bad")
|
||||
}
|
||||
}()
|
||||
|
||||
ch, cReqs, err := conn.OpenChannel("boringproxy-tunnel", []byte{25, 25})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
}
|
||||
ch, cReqs, err := conn.OpenChannel("boringproxy-tunnel", []byte{25, 25})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
go ssh.DiscardRequests(cReqs)
|
||||
go ssh.DiscardRequests(cReqs)
|
||||
|
||||
ch.Write([]byte("Hi there"))
|
||||
ch.Close()
|
||||
ch.Write([]byte("Hi there"))
|
||||
ch.Close()
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"crypto/rsa"
|
||||
"crypto/rand"
|
||||
"encoding/pem"
|
||||
"crypto/x509"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type Tunnel struct {
|
||||
@ -27,7 +27,7 @@ func NewTunnels() Tunnels {
|
||||
}
|
||||
|
||||
type TunnelManager struct {
|
||||
nextPort int
|
||||
nextPort int
|
||||
tunnels Tunnels
|
||||
mutex *sync.Mutex
|
||||
certConfig *certmagic.Config
|
||||
@ -57,7 +57,7 @@ func NewTunnelManager(certConfig *certmagic.Config) *TunnelManager {
|
||||
}
|
||||
}
|
||||
|
||||
nextPort := 9001
|
||||
nextPort := 9001
|
||||
|
||||
mutex := &sync.Mutex{}
|
||||
return &TunnelManager{nextPort, tunnels, mutex, certConfig}
|
||||
@ -67,7 +67,7 @@ func (m *TunnelManager) SetTunnel(host string, port int) error {
|
||||
err := m.certConfig.ManageSync([]string{host})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return errors.New("Failed to get cert")
|
||||
return errors.New("Failed to get cert")
|
||||
}
|
||||
|
||||
tunnel := &Tunnel{port}
|
||||
@ -76,36 +76,36 @@ func (m *TunnelManager) SetTunnel(host string, port int) error {
|
||||
saveJson(m.tunnels, "tunnels.json")
|
||||
m.mutex.Unlock()
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TunnelManager) CreateTunnel(domain string) (int, string, error) {
|
||||
err := m.certConfig.ManageSync([]string{domain})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return 0, "", errors.New("Failed to get cert")
|
||||
return 0, "", errors.New("Failed to get cert")
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
_, exists := m.tunnels[domain]
|
||||
if exists {
|
||||
return 0, "", errors.New("Tunnel exists for domain " + domain)
|
||||
}
|
||||
_, exists := m.tunnels[domain]
|
||||
if exists {
|
||||
return 0, "", errors.New("Tunnel exists for domain " + domain)
|
||||
}
|
||||
|
||||
port := m.nextPort
|
||||
m.nextPort += 1
|
||||
port := m.nextPort
|
||||
m.nextPort += 1
|
||||
tunnel := &Tunnel{port}
|
||||
m.tunnels[domain] = tunnel
|
||||
saveJson(m.tunnels, "tunnels.json")
|
||||
|
||||
privKey, err := m.addToAuthorizedKeys(port)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
privKey, err := m.addToAuthorizedKeys(port)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
return port, privKey, nil
|
||||
return port, privKey, nil
|
||||
}
|
||||
|
||||
func (m *TunnelManager) DeleteTunnel(host string) {
|
||||
@ -129,29 +129,29 @@ func (m *TunnelManager) GetPort(serverName string) (int, error) {
|
||||
|
||||
func (m *TunnelManager) addToAuthorizedKeys(port int) (string, error) {
|
||||
|
||||
akBytes, err := ioutil.ReadFile("/home/anders/.ssh/authorized_keys")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
akBytes, err := ioutil.ReadFile("/home/anders/.ssh/authorized_keys")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
akStr := string(akBytes)
|
||||
akStr := string(akBytes)
|
||||
|
||||
pubKey, privKey, err := MakeSSHKeyPair()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pubKey, privKey, err := MakeSSHKeyPair()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
options := fmt.Sprintf(`command="echo This key permits tunnels only",permitopen="fakehost:1",permitlisten="localhost:%d"`, port)
|
||||
options := fmt.Sprintf(`command="echo This key permits tunnels only",permitopen="fakehost:1",permitlisten="localhost:%d"`, port)
|
||||
|
||||
pubKeyNoNewline := pubKey[:len(pubKey) - 1]
|
||||
newAk := fmt.Sprintf("%s%s %s %s%d\n", akStr, options, pubKeyNoNewline, "boringproxy-", port)
|
||||
pubKeyNoNewline := pubKey[:len(pubKey)-1]
|
||||
newAk := fmt.Sprintf("%s%s %s %s%d\n", akStr, options, pubKeyNoNewline, "boringproxy-", port)
|
||||
|
||||
err = ioutil.WriteFile("/home/anders/.ssh/authorized_keys", []byte(newAk), 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = ioutil.WriteFile("/home/anders/.ssh/authorized_keys", []byte(newAk), 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return privKey, nil
|
||||
return privKey, nil
|
||||
}
|
||||
|
||||
// Adapted from https://stackoverflow.com/a/34347463/943814
|
||||
@ -159,27 +159,27 @@ func (m *TunnelManager) addToAuthorizedKeys(port int) (string, error) {
|
||||
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
|
||||
// Private Key generated is PEM encoded
|
||||
func MakeSSHKeyPair() (string, string, error) {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// generate and write private key as PEM
|
||||
var privKeyBuf strings.Builder
|
||||
// generate and write private key as PEM
|
||||
var privKeyBuf strings.Builder
|
||||
|
||||
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
|
||||
if err := pem.Encode(&privKeyBuf, privateKeyPEM); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
|
||||
if err := pem.Encode(&privKeyBuf, privateKeyPEM); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// generate and write public key
|
||||
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
// generate and write public key
|
||||
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
var pubKeyBuf strings.Builder
|
||||
pubKeyBuf.Write(ssh.MarshalAuthorizedKey(pub))
|
||||
var pubKeyBuf strings.Builder
|
||||
pubKeyBuf.Write(ssh.MarshalAuthorizedKey(pub))
|
||||
|
||||
return pubKeyBuf.String(), privKeyBuf.String(), nil
|
||||
return pubKeyBuf.String(), privKeyBuf.String(), nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user