Skip to content

Commit

Permalink
chore: RBAC investigations, do not merge
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Nov 7, 2024
1 parent f2c318c commit 7ccb305
Showing 1 changed file with 26 additions and 76 deletions.
102 changes: 26 additions & 76 deletions internal/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"net"
"net/http"
"os"
"strings"
"syscall"
"time"
Expand All @@ -21,91 +20,42 @@ import (
"github.com/TBD54566975/ftl/internal/log"
)

// InitialiseClients initialises global HTTP clients used by the RPC system.
//
// "authenticators" are authenticator executables to use for each endpoint. The key is the URL of the endpoint, the
// value is the path to the authenticator executable.
//
// "allowInsecure" skips certificate verification, making TLS susceptible to machine-in-the-middle attacks.
func InitialiseClients(authenticators map[string]string, allowInsecure bool) {
// We can't have a client-wide timeout because it also applies to
// streaming RPCs, timing them out.
h2cClient = &http.Client{
Transport: authn.Transport(&http2.Transport{
AllowHTTP: true,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: allowInsecure, // #nosec G402
},
DialTLSContext: func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) {
conn, err := dialer.Dial(network, addr)
return conn, err
},
}, authenticators),
}
tlsClient = &http.Client{
Transport: authn.Transport(&http2.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: allowInsecure, // #nosec G402
},
DialTLSContext: func(ctx context.Context, network, addr string, config *tls.Config) (net.Conn, error) {
tlsDialer := tls.Dialer{Config: config, NetDialer: dialer}
conn, err := tlsDialer.DialContext(ctx, network, addr)
return conn, err
},
}, authenticators),
}

// Use a separate client for HTTP/1.1 with TLS.
http1TLSClient = &http.Client{
Transport: authn.Transport(&http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: allowInsecure, // #nosec G402
},
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
logger := log.FromContext(ctx)
logger.Debugf("HTTP/1.1 connecting to %s %s", network, addr)

tlsDialer := tls.Dialer{NetDialer: dialer}
conn, err := tlsDialer.DialContext(ctx, network, addr)
return conn, fmt.Errorf("HTTP/1.1 TLS dial failed: %w", err)
},
}, authenticators),
}
}

func init() {
InitialiseClients(map[string]string{}, false)
}

var (
dialer = &net.Dialer{
Timeout: time.Second * 10,
}
h2cClient *http.Client
tlsClient *http.Client
// Temporary client for HTTP/1.1 with TLS to help with debugging.
http1TLSClient *http.Client
)

type Pingable interface {
Ping(ctx context.Context, req *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error)
}

// GetHTTPClient returns a HTTP client usable for the given URL.
func GetHTTPClient(url string) *http.Client {
if h2cClient == nil {
panic("rpc.InitialiseClients() must be called before GetHTTPClient()")
}

// TEMP_GRPC_HTTP1_ONLY set to non blank will use http1TLSClient
if os.Getenv("TEMP_GRPC_HTTP1_ONLY") != "" {
return http1TLSClient
dialer := &net.Dialer{
Timeout: time.Second * 15,
}

if strings.HasPrefix(url, "http://") {
return h2cClient
return &http.Client{
Transport: authn.Transport(&http2.Transport{
AllowHTTP: true,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false, // #nosec G402
},
DialTLSContext: func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) {
conn, err := dialer.Dial(network, addr)
return conn, err
},
}, make(map[string]string)),
}
}
return &http.Client{
Transport: authn.Transport(&http2.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false, // #nosec G402
},
DialTLSContext: func(ctx context.Context, network, addr string, config *tls.Config) (net.Conn, error) {
tlsDialer := tls.Dialer{Config: config, NetDialer: dialer}
conn, err := tlsDialer.DialContext(ctx, network, addr)
return conn, err
},
}, make(map[string]string)),
}
return tlsClient
}

// ClientFactory is a function that creates a new client and is typically one of
Expand Down

0 comments on commit 7ccb305

Please sign in to comment.