From a1858098c5224127de933caa347eb9fa8877925d Mon Sep 17 00:00:00 2001
From: Wenkai Yin <yinw@vmware.com>
Date: Thu, 23 Feb 2017 18:02:19 +0800
Subject: [PATCH] using different secret to mark himself when communicates with
 other components

---
 make/common/templates/adminserver/env |  2 +-
 make/common/templates/jobservice/env  |  1 +
 make/common/templates/ui/env          |  1 +
 make/prepare                          |  9 ++++++---
 src/adminserver/api/cfg.go            |  6 ++++--
 src/common/models/replication_job.go  |  2 +-
 src/jobservice/api/replication.go     |  2 +-
 src/jobservice/config/config.go       | 12 +++++++++---
 src/jobservice/job/statemachine.go    |  2 +-
 src/ui/api/repository.go              |  2 +-
 src/ui/config/config.go               | 10 ++++++++--
 src/ui/service/token/token.go         |  7 ++++---
 src/ui/service/utils/utils.go         |  8 +++-----
 13 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/make/common/templates/adminserver/env b/make/common/templates/adminserver/env
index ff0153215..d537720f8 100644
--- a/make/common/templates/adminserver/env
+++ b/make/common/templates/adminserver/env
@@ -31,7 +31,7 @@ VERIFY_REMOTE_CERT=$verify_remote_cert
 MAX_JOB_WORKERS=$max_job_workers
 LOG_DIR=/var/log/jobs
 UI_SECRET=$ui_secret
-SECRET_KEY=$secret_key
+JOBSERVICE_SECRET=$jobservice_secret
 TOKEN_EXPIRATION=$token_expiration
 CFG_EXPIRATION=5
 USE_COMPRESSED_JS=$use_compressed_js
diff --git a/make/common/templates/jobservice/env b/make/common/templates/jobservice/env
index 06c8b0f22..c5e37fc0f 100644
--- a/make/common/templates/jobservice/env
+++ b/make/common/templates/jobservice/env
@@ -1,4 +1,5 @@
 LOG_LEVEL=debug
 CONFIG_PATH=/etc/jobservice/app.conf
 UI_SECRET=$ui_secret
+JOBSERVICE_SECRET=$jobservice_secret
 GODEBUG=netdns=cgo
diff --git a/make/common/templates/ui/env b/make/common/templates/ui/env
index fc0d133ab..1f457e257 100644
--- a/make/common/templates/ui/env
+++ b/make/common/templates/ui/env
@@ -1,4 +1,5 @@
 LOG_LEVEL=debug
 CONFIG_PATH=/etc/ui/app.conf
 UI_SECRET=$ui_secret
+JOBSERVICE_SECRET=$jobservice_secret
 GODEBUG=netdns=cgo
diff --git a/make/prepare b/make/prepare
index 28d46a376..7fb47671e 100755
--- a/make/prepare
+++ b/make/prepare
@@ -125,6 +125,7 @@ secret_key = get_secret_key(secretkey_path)
 ########
 
 ui_secret = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(16))  
+jobservice_secret = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(16))  
 
 adminserver_config_dir = os.path.join(config_dir,"adminserver")
 if not os.path.exists(adminserver_config_dir):
@@ -219,14 +220,15 @@ render(os.path.join(templates_dir, "adminserver", "env"),
 		verify_remote_cert=verify_remote_cert,
 		max_job_workers=max_job_workers,
 		ui_secret=ui_secret,
-        secret_key=secret_key,
+		jobservice_secret=jobservice_secret,
 		token_expiration=token_expiration,
 		use_compressed_js=use_compressed_js
 	)
 
 render(os.path.join(templates_dir, "ui", "env"), 
 		ui_conf_env, 
-		ui_secret=ui_secret)
+		ui_secret=ui_secret,
+		jobservice_secret=jobservice_secret,)
 
 render(os.path.join(templates_dir, "registry", 
 		"config.yml"),
@@ -239,7 +241,8 @@ render(os.path.join(templates_dir, "db", "env"),
 
 render(os.path.join(templates_dir, "jobservice", "env"),
         job_conf_env,
-        ui_secret=ui_secret)
+        ui_secret=ui_secret,
+		jobservice_secret=jobservice_secret)
 		
 print("Generated configuration file: %s" % jobservice_conf)
 shutil.copyfile(os.path.join(templates_dir, "jobservice", "app.conf"), jobservice_conf)
diff --git a/src/adminserver/api/cfg.go b/src/adminserver/api/cfg.go
index 6a2198c6e..23469eef8 100644
--- a/src/adminserver/api/cfg.go
+++ b/src/adminserver/api/cfg.go
@@ -26,7 +26,8 @@ import (
 )
 
 func isAuthenticated(r *http.Request) (bool, error) {
-	secret := os.Getenv("UI_SECRET")
+	uiSecret := os.Getenv("UI_SECRET")
+	jobserviceSecret := os.Getenv("JOBSERVICE_SECRET")
 	c, err := r.Cookie("secret")
 	if err != nil {
 		if err == http.ErrNoCookie {
@@ -34,7 +35,8 @@ func isAuthenticated(r *http.Request) (bool, error) {
 		}
 		return false, err
 	}
-	return c != nil && c.Value == secret, nil
+	return c != nil && (c.Value == uiSecret ||
+		c.Value == jobserviceSecret), nil
 }
 
 // ListCfgs lists configurations
diff --git a/src/common/models/replication_job.go b/src/common/models/replication_job.go
index 2908e4569..ae47371fd 100644
--- a/src/common/models/replication_job.go
+++ b/src/common/models/replication_job.go
@@ -44,7 +44,7 @@ const (
 	//RepOpDelete represents the operation of a job to remove repository from a remote registry/harbor instance.
 	RepOpDelete string = "delete"
 	//UISecretCookie is the cookie name to contain the UI secret
-	UISecretCookie string = "uisecret"
+	UISecretCookie string = "secret"
 )
 
 // RepPolicy is the model for a replication policy, which associate to a project and a target (destination)
diff --git a/src/jobservice/api/replication.go b/src/jobservice/api/replication.go
index 25aef81e4..bfe7dd5c5 100644
--- a/src/jobservice/api/replication.go
+++ b/src/jobservice/api/replication.go
@@ -194,7 +194,7 @@ func getRepoList(projectID int64) ([]string, error) {
 			return repositories, err
 		}
 
-		req.AddCookie(&http.Cookie{Name: models.UISecretCookie, Value: config.UISecret()})
+		req.AddCookie(&http.Cookie{Name: models.UISecretCookie, Value: config.JobserviceSecret()})
 
 		resp, err := client.Do(req)
 		if err != nil {
diff --git a/src/jobservice/config/config.go b/src/jobservice/config/config.go
index 0a13ab5d4..c58f20b78 100644
--- a/src/jobservice/config/config.go
+++ b/src/jobservice/config/config.go
@@ -41,7 +41,7 @@ func Init() error {
 	if len(adminServerURL) == 0 {
 		adminServerURL = "http://adminserver"
 	}
-	mg = comcfg.NewManager(adminServerURL, UISecret(), true)
+	mg = comcfg.NewManager(adminServerURL, JobserviceSecret(), true)
 
 	if err := mg.Init(); err != nil {
 		return err
@@ -132,12 +132,18 @@ func SecretKey() (string, error) {
 	return keyProvider.Get(nil)
 }
 
-// UISecret returns a secret used for communication of UI, JobService
-// and Adminserver
+// UISecret returns a secret to mark UI when communicate with other
+// component
 func UISecret() string {
 	return os.Getenv("UI_SECRET")
 }
 
+// JobserviceSecret returns a secret to mark Jobservice when communicate with
+// other component
+func JobserviceSecret() string {
+	return os.Getenv("JOBSERVICE_SECRET")
+}
+
 // ExtEndpoint ...
 func ExtEndpoint() (string, error) {
 	cfg, err := mg.Get()
diff --git a/src/jobservice/job/statemachine.go b/src/jobservice/job/statemachine.go
index b6c9cd47a..db0d79a79 100644
--- a/src/jobservice/job/statemachine.go
+++ b/src/jobservice/job/statemachine.go
@@ -285,7 +285,7 @@ func addTestTransition(sm *SM) error {
 }
 
 func addImgTransferTransition(sm *SM) {
-	base := replication.InitBaseHandler(sm.Parms.Repository, sm.Parms.LocalRegURL, config.UISecret(),
+	base := replication.InitBaseHandler(sm.Parms.Repository, sm.Parms.LocalRegURL, config.JobserviceSecret(),
 		sm.Parms.TargetURL, sm.Parms.TargetUsername, sm.Parms.TargetPassword,
 		sm.Parms.Insecure, sm.Parms.Tags, sm.Logger)
 
diff --git a/src/ui/api/repository.go b/src/ui/api/repository.go
index 012ced2d3..94aa302ee 100644
--- a/src/ui/api/repository.go
+++ b/src/ui/api/repository.go
@@ -66,7 +66,7 @@ func (ra *RepositoryAPI) Get() {
 	if project.Public == 0 {
 		var userID int
 
-		if svc_utils.VerifySecret(ra.Ctx.Request) {
+		if svc_utils.VerifySecret(ra.Ctx.Request, config.JobserviceSecret()) {
 			userID = 1
 		} else {
 			userID = ra.ValidateUser()
diff --git a/src/ui/config/config.go b/src/ui/config/config.go
index fb100fe7f..d6d34b906 100644
--- a/src/ui/config/config.go
+++ b/src/ui/config/config.go
@@ -242,8 +242,14 @@ func Database() (*models.Database, error) {
 	return database, nil
 }
 
-// UISecret returns a secret used for communication of UI, JobService
-// and Adminserver
+// UISecret returns a secret to mark UI when communicate with
+// other component
 func UISecret() string {
 	return os.Getenv("UI_SECRET")
 }
+
+// JobserviceSecret returns a secret to mark Jobservice when communicate with
+// other component
+func JobserviceSecret() string {
+	return os.Getenv("JOBSERVICE_SECRET")
+}
diff --git a/src/ui/service/token/token.go b/src/ui/service/token/token.go
index 2d408cbc5..b144e322a 100644
--- a/src/ui/service/token/token.go
+++ b/src/ui/service/token/token.go
@@ -19,10 +19,11 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/vmware/harbor/src/ui/auth"
 	"github.com/vmware/harbor/src/common/models"
-	svc_utils "github.com/vmware/harbor/src/ui/service/utils"
 	"github.com/vmware/harbor/src/common/utils/log"
+	"github.com/vmware/harbor/src/ui/auth"
+	"github.com/vmware/harbor/src/ui/config"
+	svc_utils "github.com/vmware/harbor/src/ui/service/utils"
 
 	"github.com/astaxie/beego"
 	"github.com/docker/distribution/registry/auth/token"
@@ -45,7 +46,7 @@ func (h *Handler) Get() {
 	access := GetResourceActions(scopes)
 	log.Infof("request url: %v", request.URL.String())
 
-	if svc_utils.VerifySecret(request) {
+	if svc_utils.VerifySecret(request, config.JobserviceSecret()) {
 		log.Debugf("Will grant all access as this request is from job service with legal secret.")
 		username = "job-service-user"
 	} else {
diff --git a/src/ui/service/utils/utils.go b/src/ui/service/utils/utils.go
index 007b9b720..44674d127 100644
--- a/src/ui/service/utils/utils.go
+++ b/src/ui/service/utils/utils.go
@@ -20,15 +20,13 @@ import (
 	"net/http"
 
 	"github.com/vmware/harbor/src/common/utils/log"
-	"github.com/vmware/harbor/src/ui/config"
 )
 
 // VerifySecret verifies the UI_SECRET cookie in a http request.
-func VerifySecret(r *http.Request) bool {
-	secret := config.UISecret()
-	c, err := r.Cookie("uisecret")
+func VerifySecret(r *http.Request, expectedSecret string) bool {
+	c, err := r.Cookie("secret")
 	if err != nil {
 		log.Warningf("Failed to get secret cookie, error: %v", err)
 	}
-	return c != nil && c.Value == secret
+	return c != nil && c.Value == expectedSecret
 }