Merge pull request #3383 from reasonerjt/uaa-integration

Make the root CA certificate of UAA configurable
This commit is contained in:
Daniel Jiang 2017-10-17 12:20:22 +08:00 committed by GitHub
commit e6874cf9f1
11 changed files with 80 additions and 4 deletions

View File

@ -3,3 +3,4 @@ CONFIG_PATH=/etc/ui/app.conf
UI_SECRET=$ui_secret
JOBSERVICE_SECRET=$jobservice_secret
GODEBUG=netdns=cgo
UAA_CA_ROOT=/etc/ui/certificates/uaa_ca.pem

View File

@ -77,6 +77,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/
- /data/secretkey:/etc/ui/key:z
- /data/ca_download/:/etc/ui/ca/:z
- /data/psc/:/etc/ui/token/:z

View File

@ -120,4 +120,5 @@ db_user = root
uaa_endpoint = uaa.mydomain.org
uaa_clientid= id
uaa_clientsecret= secret
uaa_ca_root= /path/to/uaa_ca.pem
#############

View File

@ -160,6 +160,7 @@ pg_password = rcp.get("configuration", "clair_db_password")
uaa_endpoint = rcp.get("configuration", "uaa_endpoint")
uaa_clientid = rcp.get("configuration", "uaa_clientid")
uaa_clientsecret = rcp.get("configuration", "uaa_clientsecret")
uaa_ca_root = rcp.get("configuration", "uaa_ca_root")
secret_key = get_secret_key(secretkey_path)
log_rotate_days = rcp.get("configuration", "log_rotate_days")
########
@ -172,6 +173,7 @@ if not os.path.exists(adminserver_config_dir):
os.makedirs(os.path.join(config_dir, "adminserver"))
ui_config_dir = prep_conf_dir(config_dir,"ui")
ui_certificates_dir = prep_conf_dir(ui_config_dir,"certificates")
db_config_dir = prep_conf_dir(config_dir, "db")
job_config_dir = prep_conf_dir(config_dir, "jobservice")
registry_config_dir = prep_conf_dir(config_dir, "registry")
@ -205,6 +207,12 @@ else:
render(os.path.join(templates_dir, "nginx", "nginx.http.conf"),
nginx_conf)
if auth_mode == "uaa_auth":
if os.path.isfile(uaa_ca_root):
shutil.copy2(uaa_ca_root, os.path.join(ui_certificates_dir, "uaa_ca.pem"))
else:
raise Exception("Error: Invalid path for uaa ca root: %s" % uaa_ca_root)
render(os.path.join(templates_dir, "adminserver", "env"),
adminserver_conf_env,
ui_url=ui_url,

View File

@ -19,4 +19,5 @@ type UAASettings struct {
Endpoint string
ClientID string
ClientSecret string
CARootPath string
}

View File

@ -17,9 +17,12 @@ package uaa
import (
"context"
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net/http"
"strings"
"github.com/vmware/harbor/src/common/utils/log"
"golang.org/x/oauth2"
)
@ -61,8 +64,18 @@ func NewDefaultClient(cfg *ClientConfig) (Client, error) {
tc := &tls.Config{
InsecureSkipVerify: cfg.SkipTLSVerify,
}
if len(cfg.CARootPath) > 0 {
//TODO
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)
} else {
tc.RootCAs = pool
}
}
hc := &http.Client{
Transport: &http.Transport{

View File

@ -5,6 +5,8 @@ import (
"github.com/vmware/harbor/src/common/utils/uaa/test"
"net/http/httptest"
"os"
"path"
"runtime"
"testing"
)
@ -40,3 +42,31 @@ func TestPasswordAuth(t *testing.T) {
_, err = client.PasswordAuth("wrong", "wrong")
assert.NotNil(err)
}
func currPath() string {
_, f, _, ok := runtime.Caller(0)
if !ok {
panic("Failed to get current directory")
}
return path.Dir(f)
}
func TestNewClientWithCACert(t *testing.T) {
assert := assert.New(t)
cfg := &ClientConfig{
ClientID: "uaa",
ClientSecret: "secret",
Endpoint: mockUAAServer.URL,
SkipTLSVerify: false,
CARootPath: "/notexist",
}
_, err := NewDefaultClient(cfg)
assert.NotNil(err)
//Skip if it's malformed.
cfg.CARootPath = path.Join(currPath(), "test", "non-ca.pem")
_, err = NewDefaultClient(cfg)
assert.Nil(err)
cfg.CARootPath = path.Join(currPath(), "test", "ca.pem")
_, err = NewDefaultClient(cfg)
assert.Nil(err)
}

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC7TCCAdWgAwIBAgIJAKmFRnILlp3XMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV
BAMMAmNhMB4XDTE3MDkyNDA3MDA1M1oXDTI3MDkyMjA3MDA1M1owDTELMAkGA1UE
AwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCr4+HxXkY81j1p
5OD3htFkbJI+XulBgc7ja5YorU323VB7JfNBnau3rDZS8NdyvkLLEQT4rKw5Dd4p
phlmdKsmIq9ej1OlDjWnCOGr+HG2jG5POgPYRCf5WgCGoQ4eUIA+IXcVroG8f1YM
LDzZEBKlEP80W0zyh0ma/BYN8HG4Ica4q/iIjffJc7ob/tWFGt2HobI9wbTSyBgR
s7JSs6MBIISXGAuOE3cs7vJNzKtWhQSBw4j8FFUZSYCyONFYfOg2OtZG6z1XhpTC
rfVMm6cEsYla/mf9bJB2AqtRiUdUZwAOWQbalWPFKEO73Bj4/5sVNHKFCd/S6J1z
LHaWM0W7AgMBAAGjUDBOMB0GA1UdDgQWBBR0jFgTuL9K2iWE0wzU7r4RZT0k+zAf
BgNVHSMEGDAWgBR0jFgTuL9K2iWE0wzU7r4RZT0k+zAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQCemrfEKHPe5ahb2III89+iuIDmbPgVESXqnf88UUdS
Iv+htE8hu9CkSemsErXcC0kUbPSM0vWN9IbHINq78cXucVyi+YTzaKJ8zsK01/zf
x0xYeK5bffYTQzs+BopTCwVqd9zHSs9a2zPnsBVHXCn25j30anQgQH9ODsspXZ3i
WUAkEOmZDnNuX7tGDesA+7h8BPcZ8zrz94kxsrdneMXuHdT1iHxS/hTxTEUUhOMF
FntwT6zx3fGL4cNG06d+pdjjp+CuUR+8GRxeASbYBWhXeiY1ykipiptxkp1zhZ3x
SNandCCdeMRntnNs/+xvRhsEGbhyrvzg2WFL2NrqiKtg
-----END CERTIFICATE-----

View File

@ -0,0 +1 @@
abcdef

View File

@ -42,8 +42,7 @@ func GetClient() (uaa.Client, error) {
ClientID: UAASettings.ClientID,
ClientSecret: UAASettings.ClientSecret,
Endpoint: UAASettings.Endpoint,
//TODO: remove it
SkipTLSVerify: true,
CARootPath: UAASettings.CARootPath,
}
client, err = uaa.NewDefaultClient(cfg)
return client, err

View File

@ -434,5 +434,8 @@ func UAASettings() (*models.UAASettings, error) {
ClientID: cfg[common.UAAClientID].(string),
ClientSecret: cfg[common.UAAClientSecret].(string),
}
if len(os.Getenv("UAA_CA_ROOT")) != 0 {
us.CARootPath = os.Getenv("UAA_CA_ROOT")
}
return us, nil
}