From 415bdfa61faf479a9431b8fd636fe38c3560686c Mon Sep 17 00:00:00 2001 From: wang yan Date: Fri, 8 Nov 2019 13:59:27 +0800 Subject: [PATCH] Disable policy check when pull without bearer token This commit is to fix https://github.com/goharbor/harbor/issues/9780. To align with OCI spec, when a docker pull request without bearer token in header comes in, Harbor should not intecepte it(return a 412 if check fail) when the policy check is enabled. As the 401 is expected by the docker/caller, and then to ask token service which url is in the 401 header. Signed-off-by: wang yan --- src/core/middlewares/contenttrust/handler.go | 4 ++++ src/core/middlewares/regtoken/handler.go | 2 ++ src/core/middlewares/util/util.go | 13 +++++++++++++ src/core/middlewares/vulnerable/handler.go | 5 +++++ 4 files changed, 24 insertions(+) diff --git a/src/core/middlewares/contenttrust/handler.go b/src/core/middlewares/contenttrust/handler.go index 049a2a88b..af2be936d 100644 --- a/src/core/middlewares/contenttrust/handler.go +++ b/src/core/middlewares/contenttrust/handler.go @@ -49,6 +49,10 @@ func (cth contentTrustHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque cth.next.ServeHTTP(rw, req) return } + if pullWithBearer, ok := util.DockerPullAuthFromContext(req.Context()); ok && !pullWithBearer { + cth.next.ServeHTTP(rw, req) + return + } if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull { cth.next.ServeHTTP(rw, req) return diff --git a/src/core/middlewares/regtoken/handler.go b/src/core/middlewares/regtoken/handler.go index d1f561e12..1fa53ec8b 100644 --- a/src/core/middlewares/regtoken/handler.go +++ b/src/core/middlewares/regtoken/handler.go @@ -43,6 +43,8 @@ func (r *regTokenHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { r.next.ServeHTTP(rw, req) return } + *req = *(req.WithContext(util.NewDockerPullAuthContext(req.Context(), true))) + rawToken := parts[1] opt := pkg_token.DefaultTokenOptions() regTK, err := pkg_token.Parse(opt, rawToken, ®istry.Claim{}) diff --git a/src/core/middlewares/util/util.go b/src/core/middlewares/util/util.go index 52d203071..2130c3d35 100644 --- a/src/core/middlewares/util/util.go +++ b/src/core/middlewares/util/util.go @@ -51,6 +51,8 @@ const ( ImageInfoCtxKey = contextKey("ImageInfo") // ScannerPullCtxKey the context key for robot account to bypass the pull policy check. ScannerPullCtxKey = contextKey("ScannerPullCheck") + // DockerPullAuthCtxKey the context key to index whether docker pull request with bearer token + DockerPullAuthCtxKey = contextKey("DockerPullWithBearer") // TokenUsername ... // TODO: temp solution, remove after vmware/harbor#2242 is resolved. TokenUsername = "harbor-core" @@ -457,6 +459,17 @@ func ScannerPullFromContext(ctx context.Context) (bool, bool) { return info, ok } +// NewDockerPullAuthContext returns context with bearer token +func NewDockerPullAuthContext(ctx context.Context, withBearer bool) context.Context { + return context.WithValue(ctx, DockerPullAuthCtxKey, withBearer) +} + +// DockerPullAuthFromContext returns whether the docker pull with bearer +func DockerPullAuthFromContext(ctx context.Context) (bool, bool) { + info, ok := ctx.Value(DockerPullAuthCtxKey).(bool) + return info, ok +} + // NewBlobInfoContext returns context with blob info func NewBlobInfoContext(ctx context.Context, info *BlobInfo) context.Context { return context.WithValue(ctx, blobInfoKey, info) diff --git a/src/core/middlewares/vulnerable/handler.go b/src/core/middlewares/vulnerable/handler.go index 108d683f4..3c9128b55 100644 --- a/src/core/middlewares/vulnerable/handler.go +++ b/src/core/middlewares/vulnerable/handler.go @@ -52,6 +52,11 @@ func (vh vulnerableHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } + if pullWithBearer, ok := util.DockerPullAuthFromContext(req.Context()); ok && !pullWithBearer { + vh.next.ServeHTTP(rw, req) + return + } + if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull { vh.next.ServeHTTP(rw, req) return