From e02de2068ac6968e31f008bc8f6066df091db39c Mon Sep 17 00:00:00 2001 From: Tan Jiang Date: Wed, 3 Jan 2018 16:21:29 +0800 Subject: [PATCH] Enable configuring the CA Certificate for UAA Enable configuring the path of root cert of UAA in harbor.cfg. It only takes effects if the verify_cert is set to "true" If the file does not exist, the configuration is skipped. The intention for this commit is to support integration with nested UAA in PAS or PKS, we don't expect user to manually configure this value, though he can do it if he wants. --- make/docker-compose.tpl | 2 +- make/harbor.cfg | 1 + make/prepare | 12 ++++++++++++ src/common/utils/uaa/client.go | 23 ++++++++++++++--------- src/common/utils/uaa/client_test.go | 2 +- src/ui/auth/uaa/uaa.go | 2 ++ 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/make/docker-compose.tpl b/make/docker-compose.tpl index 26a87a6e3..a6755236b 100644 --- a/make/docker-compose.tpl +++ b/make/docker-compose.tpl @@ -76,7 +76,7 @@ services: volumes: - ./common/config/ui/app.conf:/etc/ui/app.conf:z - ./common/config/ui/private_key.pem:/etc/ui/private_key.pem:z - - ./common/config/ui/certificates/:/etc/ui/certifates/ + - ./common/config/ui/certificates/:/etc/ui/certificates/ - /data/secretkey:/etc/ui/key:z - /data/ca_download/:/etc/ui/ca/:z - /data/psc/:/etc/ui/token/:z diff --git a/make/harbor.cfg b/make/harbor.cfg index 8df07e977..156a6acfa 100644 --- a/make/harbor.cfg +++ b/make/harbor.cfg @@ -142,4 +142,5 @@ uaa_endpoint = uaa.mydomain.org uaa_clientid = id uaa_clientsecret = secret uaa_verify_cert = true +uaa_ca_cert = /path/to/ca.pem ############# diff --git a/make/prepare b/make/prepare index 017162e3e..ba5e7476c 100755 --- a/make/prepare +++ b/make/prepare @@ -250,6 +250,7 @@ uaa_endpoint = rcp.get("configuration", "uaa_endpoint") uaa_clientid = rcp.get("configuration", "uaa_clientid") uaa_clientsecret = rcp.get("configuration", "uaa_clientsecret") uaa_verify_cert = rcp.get("configuration", "uaa_verify_cert") +uaa_ca_cert = rcp.get("configuration", "uaa_ca_cert") secret_key = get_secret_key(secretkey_path) log_rotate_count = rcp.get("configuration", "log_rotate_count") @@ -280,6 +281,7 @@ log_config_dir = prep_conf_dir (config_dir, "log") adminserver_conf_env = os.path.join(config_dir, "adminserver", "env") ui_conf_env = os.path.join(config_dir, "ui", "env") ui_conf = os.path.join(config_dir, "ui", "app.conf") +ui_cert_dir = os.path.join(config_dir, "ui", "certificates") jobservice_conf = os.path.join(config_dir, "jobservice", "app.conf") registry_conf = os.path.join(config_dir, "registry", "config.yml") db_conf_env = os.path.join(config_dir, "db", "env") @@ -387,6 +389,16 @@ shutil.copyfile(os.path.join(templates_dir, "jobservice", "app.conf"), jobservic print("Generated configuration file: %s" % ui_conf) shutil.copyfile(os.path.join(templates_dir, "ui", "app.conf"), ui_conf) +if auth_mode == "uaa_auth": + if os.path.isfile(uaa_ca_cert): + if not os.path.isdir(ui_cert_dir): + os.makedirs(ui_cert_dir, mode=0o600) + ui_uaa_ca = os.path.join(ui_cert_dir, "uaa_ca.pem") + print("Copying UAA CA cert to %s" % ui_uaa_ca) + shutil.copyfile(uaa_ca_cert, ui_uaa_ca) + else: + print("Can not find UAA CA cert: %s, skip" % uaa_ca_cert) + def validate_crt_subj(dirty_subj): subj_list = [item for item in dirty_subj.strip().split("/") \ diff --git a/src/common/utils/uaa/client.go b/src/common/utils/uaa/client.go index 8aab55027..07da2e792 100644 --- a/src/common/utils/uaa/client.go +++ b/src/common/utils/uaa/client.go @@ -22,6 +22,7 @@ import ( "fmt" "io/ioutil" "net/http" + "os" "strings" "github.com/vmware/harbor/src/common/utils/log" @@ -179,16 +180,20 @@ func NewDefaultClient(cfg *ClientConfig) (Client, error) { InsecureSkipVerify: cfg.SkipTLSVerify, } if !cfg.SkipTLSVerify && len(cfg.CARootPath) > 0 { - content, err := ioutil.ReadFile(cfg.CARootPath) - if err != nil { - return nil, err - } - pool := x509.NewCertPool() - //Do not throw error if the certificate is malformed, so we can put a place holder. - if ok := pool.AppendCertsFromPEM(content); !ok { - log.Warningf("Failed to append certificate to cert pool, cert path: %s", cfg.CARootPath) + if _, err := os.Stat(cfg.CARootPath); !os.IsNotExist(err) { + content, err := ioutil.ReadFile(cfg.CARootPath) + if err != nil { + return nil, err + } + pool := x509.NewCertPool() + //Do not throw error if the certificate is malformed, so we can put a place holder. + if ok := pool.AppendCertsFromPEM(content); !ok { + log.Warningf("Failed to append certificate to cert pool, cert path: %s", cfg.CARootPath) + } else { + tc.RootCAs = pool + } } else { - tc.RootCAs = pool + log.Warningf("The root certificate file %s is not found, skip configuring root cert in UAA client.", cfg.CARootPath) } } hc := &http.Client{ diff --git a/src/common/utils/uaa/client_test.go b/src/common/utils/uaa/client_test.go index 774392106..f56440a56 100644 --- a/src/common/utils/uaa/client_test.go +++ b/src/common/utils/uaa/client_test.go @@ -98,7 +98,7 @@ func TestNewClientWithCACert(t *testing.T) { CARootPath: "/notexist", } _, err := NewDefaultClient(cfg) - assert.NotNil(err) + assert.Nil(err) //Skip if it's malformed. cfg.CARootPath = path.Join(currPath(), "test", "non-ca.pem") _, err = NewDefaultClient(cfg) diff --git a/src/ui/auth/uaa/uaa.go b/src/ui/auth/uaa/uaa.go index 22557a9bf..62ae1e319 100644 --- a/src/ui/auth/uaa/uaa.go +++ b/src/ui/auth/uaa/uaa.go @@ -16,6 +16,7 @@ package uaa import ( "fmt" + "os" "strings" "sync" @@ -38,6 +39,7 @@ func CreateClient() (uaa.Client, error) { ClientSecret: UAASettings.ClientSecret, Endpoint: UAASettings.Endpoint, SkipTLSVerify: !UAASettings.VerifyCert, + CARootPath: os.Getenv("UAA_CA_ROOT"), } return uaa.NewDefaultClient(cfg) }