fix nil pointer, add more debugging

This commit is contained in:
AJ ONeal 2020-07-06 09:56:29 +00:00
parent 01177518e0
commit 678d7b5e11
6 changed files with 70 additions and 23 deletions

View File

@ -139,7 +139,7 @@ func routeAll() chi.Router {
ctx := r.Context() ctx := r.Context()
claims, ok := ctx.Value(MWKey("claims")).(*MgmtClaims) claims, ok := ctx.Value(MWKey("claims")).(*MgmtClaims)
if !ok { if !ok {
msg := `{"error":"failure to ping: 1"}` msg := `{"error":"failure to ping: 3"}`
fmt.Println("touch no claims", claims) fmt.Println("touch no claims", claims)
http.Error(w, msg+"\n", http.StatusBadRequest) http.Error(w, msg+"\n", http.StatusBadRequest)
return return

View File

@ -21,7 +21,20 @@ var httpsrv *http.Server
func init() { func init() {
r := chi.NewRouter() r := chi.NewRouter()
r.HandleFunc("/ws", upgradeWebsocket) r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("[debug] should be handled by API or websocket upgrade")
next.ServeHTTP(w, r)
})
})
r.Mount("/ws", http.HandlerFunc(upgradeWebsocket))
r.HandleFunc("/api/ping", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("[debug] hit /api/ping and replying\n")
w.Header().Set("Content-Type", "application/json")
w.Write(apiPingContent)
}))
r.Route("/api", func(r chi.Router) { r.Route("/api", func(r chi.Router) {
// TODO token needs a globally unique subject // TODO token needs a globally unique subject
@ -40,6 +53,7 @@ func init() {
if "*" != grants.Subject { if "*" != grants.Subject {
log.Println("only admins allowed", err) log.Println("only admins allowed", err)
w.Write(apiNotAuthorizedContent) w.Write(apiNotAuthorizedContent)
return
} }
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
@ -59,6 +73,7 @@ func init() {
} }
} }
var apiPingContent = []byte("{ \"success\": true, \"error\": \"\" }\n")
var apiNotFoundContent = []byte("{ \"error\": \"not found\" }\n") var apiNotFoundContent = []byte("{ \"error\": \"not found\" }\n")
var apiNotAuthorizedContent = []byte("{ \"error\": \"not authorized\" }\n") var apiNotAuthorizedContent = []byte("{ \"error\": \"not authorized\" }\n")
@ -146,6 +161,7 @@ func upgradeWebsocket(w http.ResponseWriter, r *http.Request) {
ReadBufferSize: 1024, ReadBufferSize: 1024,
WriteBufferSize: 1024, WriteBufferSize: 1024,
} }
fmt.Println("[debug] grants", grants)
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
log.Println("WebSocket upgrade failed", err) log.Println("WebSocket upgrade failed", err)

View File

@ -12,6 +12,7 @@ func NewAuthorizer(authURL string) telebit.Authorizer {
return func(r *http.Request) (*telebit.Grants, error) { return func(r *http.Request) (*telebit.Grants, error) {
// do we have a valid wss_client? // do we have a valid wss_client?
fmt.Printf("[authz] Authorization = %s\n", r.Header.Get("Authorization"))
var tokenString string var tokenString string
if auth := strings.Split(r.Header.Get("Authorization"), " "); len(auth) > 1 { if auth := strings.Split(r.Header.Get("Authorization"), " "); len(auth) > 1 {
// TODO handle Basic auth tokens as well // TODO handle Basic auth tokens as well
@ -25,10 +26,12 @@ func NewAuthorizer(authURL string) telebit.Authorizer {
r.URL.Query().Set("access_token", "[redacted]") r.URL.Query().Set("access_token", "[redacted]")
} }
fmt.Printf("[authz] authURL = %s\n", authURL)
fmt.Printf("[authz] token = %s\n", tokenString)
grants, err := telebit.Inspect(authURL, tokenString) grants, err := telebit.Inspect(authURL, tokenString)
if nil != err { if nil != err {
fmt.Println("return an error, do not go on") fmt.Printf("[authorizer] error inspecting %q: %s\ntoken: %s\n", authURL, err, tokenString)
return nil, err return nil, err
} }
if "" != r.URL.Query().Get("access_token") { if "" != r.URL.Query().Get("access_token") {

View File

@ -21,9 +21,10 @@ import (
"git.coolaj86.com/coolaj86/go-telebitd/mgmt" "git.coolaj86.com/coolaj86/go-telebitd/mgmt"
"git.coolaj86.com/coolaj86/go-telebitd/mgmt/authstore" "git.coolaj86.com/coolaj86/go-telebitd/mgmt/authstore"
telebit "git.coolaj86.com/coolaj86/go-telebitd/mplexer" telebit "git.coolaj86.com/coolaj86/go-telebitd/mplexer"
"git.coolaj86.com/coolaj86/go-telebitd/mplexer/dns01" tbDns01 "git.coolaj86.com/coolaj86/go-telebitd/mplexer/dns01"
httpshim "git.coolaj86.com/coolaj86/go-telebitd/relay/tunnel" httpshim "git.coolaj86.com/coolaj86/go-telebitd/relay/tunnel"
"git.coolaj86.com/coolaj86/go-telebitd/table" "git.coolaj86.com/coolaj86/go-telebitd/table"
legoDns01 "github.com/go-acme/lego/v3/challenge/dns01"
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
"github.com/denisbrodbeck/machineid" "github.com/denisbrodbeck/machineid"
@ -78,8 +79,6 @@ func main() {
portToPorts := flag.String("port-forward", "", "a list of <from-port>:<to-port> for raw port-forwarding") portToPorts := flag.String("port-forward", "", "a list of <from-port>:<to-port> for raw port-forwarding")
flag.Parse() flag.Parse()
authorizer = NewAuthorizer(*authURL)
if len(os.Args) >= 2 { if len(os.Args) >= 2 {
if "version" == os.Args[1] { if "version" == os.Args[1] {
fmt.Printf("telebit %s %s %s", GitVersion, GitRev[:7], GitTimestamp) fmt.Printf("telebit %s %s %s", GitVersion, GitRev[:7], GitTimestamp)
@ -164,14 +163,21 @@ func main() {
*relay = os.Getenv("RELAY") // "wss://example.com:443" *relay = os.Getenv("RELAY") // "wss://example.com:443"
} }
if 0 == len(*relay) { if 0 == len(*relay) {
fmt.Fprintf(os.Stderr, "Missing relay url\n") if len(bindAddrs) > 0 {
os.Exit(1) fmt.Fprintf(os.Stderr, "Acting as Relay\n")
return } else {
fmt.Fprintf(os.Stderr, "error: must provider or act as Relay\n")
os.Exit(1)
return
}
} }
if 0 == len(*acmeRelay) { if 0 == len(*acmeRelay) {
*acmeRelay = strings.Replace(*relay, "ws", "http", 1) // "https://example.com:443" *acmeRelay = strings.Replace(*relay, "ws", "http", 1) // "https://example.com:443"
} }
if 0 == len(*authURL) {
*authURL = os.Getenv("AUTH_URL")
}
if len(*relay) > 0 || len(*acmeRelay) > 0 { if len(*relay) > 0 || len(*acmeRelay) > 0 {
if "" == *authURL { if "" == *authURL {
*authURL = strings.Replace(*relay, "ws", "http", 1) // "https://example.com:443" *authURL = strings.Replace(*relay, "ws", "http", 1) // "https://example.com:443"
@ -192,6 +198,7 @@ func main() {
} }
fmt.Println("grants", grants) fmt.Println("grants", grants)
} }
authorizer = NewAuthorizer(*authURL)
provider, err := getACMEProvider(acmeRelay, token) provider, err := getACMEProvider(acmeRelay, token)
if nil != err { if nil != err {
@ -199,12 +206,22 @@ func main() {
os.Exit(1) os.Exit(1)
return return
} }
fmt.Printf("Email: %q\n", *email)
acme := &telebit.ACME{ acme := &telebit.ACME{
Email: *email, Email: *email,
StoragePath: *certpath, StoragePath: *certpath,
Agree: *acmeAgree, Agree: *acmeAgree,
Directory: *acmeDirectory, Directory: *acmeDirectory,
DNSProvider: provider, DNSProvider: provider,
//DNSChallengeOption: legoDns01.DNSProviderOption,
DNSChallengeOption: legoDns01.WrapPreCheck(func(domain, fqdn, value string, orig legoDns01.PreCheckFunc) (bool, error) {
ok, err := orig(fqdn, value)
if ok {
fmt.Println("[Telebit-ACME-DNS] sleeping an additional 5 seconds")
time.Sleep(5 * time.Second)
}
return ok, err
}),
EnableHTTPChallenge: *enableHTTP01, EnableHTTPChallenge: *enableHTTP01,
EnableTLSALPNChallenge: *enableTLSALPN01, EnableTLSALPNChallenge: *enableTLSALPN01,
} }
@ -229,8 +246,11 @@ func main() {
go func() { go func() {
httpsrv.Serve(listener) httpsrv.Serve(listener)
}() }()
fmt.Printf("Will respond to Websocket and API requests to %q\n", *apiHostname)
mux.HandleTCP(*apiHostname, telebit.HandlerFunc(func(client net.Conn) error { mux.HandleTCP(*apiHostname, telebit.HandlerFunc(func(client net.Conn) error {
fmt.Printf("[debug] Accepting API or WebSocket client %q\n", *apiHostname)
listener.Feed(client) listener.Feed(client)
fmt.Printf("[debug] done with %q client\n", *apiHostname)
// TODO use a more correct non-error error? // TODO use a more correct non-error error?
// or perhaps (ok, error) or (handled, error)? // or perhaps (ok, error) or (handled, error)?
return io.EOF return io.EOF
@ -332,6 +352,7 @@ func routeSubscribersAndClients(client net.Conn) error {
servername := strings.ToLower(wconn.Servername()) servername := strings.ToLower(wconn.Servername())
if "" != servername && !isHostname(servername) { if "" != servername && !isHostname(servername) {
_ = client.Close() _ = client.Close()
fmt.Println("[debug] invalid servername")
return fmt.Errorf("invalid servername") return fmt.Errorf("invalid servername")
} }
@ -365,6 +386,7 @@ func routeSubscribersAndClients(client net.Conn) error {
func tryToServeName(servername string, wconn *telebit.ConnWrap) bool { func tryToServeName(servername string, wconn *telebit.ConnWrap) bool {
srv, ok := table.GetServer(servername) srv, ok := table.GetServer(servername)
if !ok { if !ok {
fmt.Println("[debug] no server to server", servername)
return false return false
} }
@ -493,15 +515,15 @@ func newGoDaddyDNSProvider(id, secret string) (*godaddy.DNSProvider, error) {
} }
// newAPIDNSProvider is for the sake of demoing the tunnel // newAPIDNSProvider is for the sake of demoing the tunnel
func newAPIDNSProvider(baseURL string, token string) (*dns01.DNSProvider, error) { func newAPIDNSProvider(baseURL string, token string) (*tbDns01.DNSProvider, error) {
config := dns01.NewDefaultConfig() config := tbDns01.NewDefaultConfig()
config.Token = token config.Token = token
endpoint, err := url.Parse(baseURL) endpoint, err := url.Parse(baseURL)
if nil != err { if nil != err {
return nil, err return nil, err
} }
config.Endpoint = endpoint config.Endpoint = endpoint
return dns01.NewDNSProviderConfig(config) return tbDns01.NewDNSProviderConfig(config)
} }
/* /*

View File

@ -138,8 +138,9 @@ func (c *ConnWrap) isTerminated() bool {
c.SetDeadline(time.Now().Add(5 * time.Second)) c.SetDeadline(time.Now().Add(5 * time.Second))
n := 6 n := 6
b, _ := c.Peek(n) b, _ := c.Peek(n)
fmt.Println("Peek(n)", b) fmt.Println("Peek(n)", b, string(b))
defer c.SetDeadline(time.Time{}) defer c.SetDeadline(time.Time{})
var encrypted bool
if len(b) >= n { if len(b) >= n {
// SSL v3.x / TLS v1.x // SSL v3.x / TLS v1.x
// 0: TLS Byte // 0: TLS Byte
@ -153,15 +154,16 @@ func (c *ConnWrap) isTerminated() bool {
length := (int(b[3]) << 8) + int(b[4]) length := (int(b[3]) << 8) + int(b[4])
b, err := c.Peek(n - 1 + length) b, err := c.Peek(n - 1 + length)
if nil != err { if nil != err {
*c.encrypted = false c.encrypted = &encrypted
return !*c.encrypted return !*c.encrypted
} }
c.servername, _ = sni.GetHostname(b) c.servername, _ = sni.GetHostname(b)
*c.encrypted = true encrypted = true
c.encrypted = &encrypted
return !*c.encrypted return !*c.encrypted
} }
} }
*c.encrypted = false c.encrypted = &encrypted
return !*c.encrypted return !*c.encrypted
/* /*
if nil != err { if nil != err {

View File

@ -16,6 +16,7 @@ import (
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
"github.com/go-acme/lego/v3/challenge" "github.com/go-acme/lego/v3/challenge"
"github.com/go-acme/lego/v3/challenge/dns01"
) )
// Note: 64k is the TCP max, but 1460b is the 100mbit Ethernet max (1500 MTU - overhead), // Note: 64k is the TCP max, but 1460b is the 100mbit Ethernet max (1500 MTU - overhead),
@ -176,6 +177,7 @@ type ACME struct {
Email string Email string
Directory string Directory string
DNSProvider challenge.Provider DNSProvider challenge.Provider
DNSChallengeOption dns01.ChallengeOption
Storage certmagic.Storage Storage certmagic.Storage
StoragePath string StoragePath string
EnableHTTPChallenge bool EnableHTTPChallenge bool
@ -205,7 +207,7 @@ func TerminateTLS(client net.Conn, acme *ACME) net.Conn {
} }
var err error var err error
magic, err = newCertMagic(acme) magic, err = NewCertMagic(acme)
if nil != err { if nil != err {
fmt.Fprintf( fmt.Fprintf(
os.Stderr, os.Stderr,
@ -276,7 +278,7 @@ func TerminateTLS(client net.Conn, acme *ACME) net.Conn {
} }
} }
func newCertMagic(acme *ACME) (*certmagic.Config, error) { func NewCertMagic(acme *ACME) (*certmagic.Config, error) {
if !acme.Agree { if !acme.Agree {
fmt.Fprintf( fmt.Fprintf(
os.Stderr, os.Stderr,
@ -304,8 +306,10 @@ func newCertMagic(acme *ACME) (*certmagic.Config, error) {
}, },
}) })
// yes, a circular reference, passing `magic` to its own Issuer // yes, a circular reference, passing `magic` to its own Issuer
fmt.Printf("[debug] ACME Email: %q\n", acme.Email)
magic.Issuer = certmagic.NewACMEManager(magic, certmagic.ACMEManager{ magic.Issuer = certmagic.NewACMEManager(magic, certmagic.ACMEManager{
DNSProvider: acme.DNSProvider, DNSProvider: acme.DNSProvider,
DNSChallengeOption: acme.DNSChallengeOption,
CA: acme.Directory, CA: acme.Directory,
Email: acme.Email, Email: acme.Email,
Agreed: acme.Agree, Agreed: acme.Agree,