Create setting to allow to trust the system root CAs

Previously, when rootCA was set, the trusted system root CAs were ignored. Now, allow for both being able to be configured and used

Signed-off-by: Daniel Haus <dhaus@redhat.com>
This commit is contained in:
Daniel Haus 2021-11-26 21:27:25 +01:00
parent a322f42a10
commit 2b262ff5d6
No known key found for this signature in database
GPG Key ID: 262B7643F39EB8A9
2 changed files with 47 additions and 36 deletions

View File

@ -28,13 +28,14 @@ const (
// Config holds configuration options for OpenShift login // Config holds configuration options for OpenShift login
type Config struct { type Config struct {
Issuer string `json:"issuer"` Issuer string `json:"issuer"`
ClientID string `json:"clientID"` ClientID string `json:"clientID"`
ClientSecret string `json:"clientSecret"` ClientSecret string `json:"clientSecret"`
RedirectURI string `json:"redirectURI"` RedirectURI string `json:"redirectURI"`
Groups []string `json:"groups"` Groups []string `json:"groups"`
InsecureCA bool `json:"insecureCA"` InsecureCA bool `json:"insecureCA"`
RootCA string `json:"rootCA"` RootCA string `json:"rootCA"`
IncludeSystemRootCAs bool `json:"includeSystemRootCAs"`
} }
var ( var (
@ -43,17 +44,18 @@ var (
) )
type openshiftConnector struct { type openshiftConnector struct {
apiURL string apiURL string
redirectURI string redirectURI string
clientID string clientID string
clientSecret string clientSecret string
cancel context.CancelFunc cancel context.CancelFunc
logger log.Logger logger log.Logger
httpClient *http.Client httpClient *http.Client
oauth2Config *oauth2.Config oauth2Config *oauth2.Config
insecureCA bool insecureCA bool
rootCA string rootCA string
groups []string includeSystemRootCAs bool
groups []string
} }
type user struct { type user struct {
@ -73,18 +75,19 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
req, err := http.NewRequest(http.MethodGet, wellKnownURL, nil) req, err := http.NewRequest(http.MethodGet, wellKnownURL, nil)
openshiftConnector := openshiftConnector{ openshiftConnector := openshiftConnector{
apiURL: c.Issuer, apiURL: c.Issuer,
cancel: cancel, cancel: cancel,
clientID: c.ClientID, clientID: c.ClientID,
clientSecret: c.ClientSecret, clientSecret: c.ClientSecret,
insecureCA: c.InsecureCA, insecureCA: c.InsecureCA,
logger: logger, logger: logger,
redirectURI: c.RedirectURI, redirectURI: c.RedirectURI,
rootCA: c.RootCA, rootCA: c.RootCA,
groups: c.Groups, includeSystemRootCAs: c.IncludeSystemRootCAs,
groups: c.Groups,
} }
if openshiftConnector.httpClient, err = newHTTPClient(c.InsecureCA, c.RootCA); err != nil { if openshiftConnector.httpClient, err = newHTTPClient(c.InsecureCA, c.RootCA, c.IncludeSystemRootCAs); err != nil {
cancel() cancel()
return nil, fmt.Errorf("failed to create HTTP client: %v", err) return nil, fmt.Errorf("failed to create HTTP client: %v", err)
} }
@ -248,16 +251,24 @@ func validateAllowedGroups(userGroups, allowedGroups []string) bool {
} }
// newHTTPClient returns a new HTTP client // newHTTPClient returns a new HTTP client
func newHTTPClient(insecureCA bool, rootCA string) (*http.Client, error) { func newHTTPClient(insecureCA bool, rootCA string, includeSystemRootCAs bool) (*http.Client, error) {
tlsConfig := tls.Config{} tlsConfig := tls.Config{}
if insecureCA { if insecureCA {
tlsConfig = tls.Config{InsecureSkipVerify: true} tlsConfig = tls.Config{InsecureSkipVerify: true}
} else if rootCA != "" { } else if rootCA != "" {
tlsConfig = tls.Config{RootCAs: x509.NewCertPool()} if !includeSystemRootCAs {
tlsConfig = tls.Config{RootCAs: x509.NewCertPool()}
} else {
systemCAs, err := x509.SystemCertPool()
if err != nil {
return nil, fmt.Errorf("failed to read host CA: %w", err)
}
tlsConfig = tls.Config{RootCAs: systemCAs}
}
rootCABytes, err := os.ReadFile(rootCA) rootCABytes, err := os.ReadFile(rootCA)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read root-ca: %v", err) return nil, fmt.Errorf("failed to read root-ca: %w", err)
} }
if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) {
return nil, fmt.Errorf("no certs found in root CA file %q", rootCA) return nil, fmt.Errorf("no certs found in root CA file %q", rootCA)

View File

@ -70,7 +70,7 @@ func TestGetUser(t *testing.T) {
_, err = http.NewRequest("GET", hostURL.String(), nil) _, err = http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err) expectNil(t, err)
h, err := newHTTPClient(true, "") h, err := newHTTPClient(true, "", false)
expectNil(t, err) expectNil(t, err)
@ -128,7 +128,7 @@ func TestVerifyGroup(t *testing.T) {
_, err = http.NewRequest("GET", hostURL.String(), nil) _, err = http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err) expectNil(t, err)
h, err := newHTTPClient(true, "") h, err := newHTTPClient(true, "", false)
expectNil(t, err) expectNil(t, err)
@ -164,7 +164,7 @@ func TestCallbackIdentity(t *testing.T) {
req, err := http.NewRequest("GET", hostURL.String(), nil) req, err := http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err) expectNil(t, err)
h, err := newHTTPClient(true, "") h, err := newHTTPClient(true, "", false)
expectNil(t, err) expectNil(t, err)
@ -198,7 +198,7 @@ func TestRefreshIdentity(t *testing.T) {
}) })
defer s.Close() defer s.Close()
h, err := newHTTPClient(true, "") h, err := newHTTPClient(true, "", false)
expectNil(t, err) expectNil(t, err)
oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{ oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{
@ -237,7 +237,7 @@ func TestRefreshIdentityFailure(t *testing.T) {
}) })
defer s.Close() defer s.Close()
h, err := newHTTPClient(true, "") h, err := newHTTPClient(true, "", false)
expectNil(t, err) expectNil(t, err)
oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{ oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{