Signed-off-by: cyli <cyli@twistedmatrix.com>
cyli authored on 2016/02/20 07:34:34... | ... |
@@ -88,7 +88,7 @@ RUN cd /usr/local/lvm2 \ |
88 | 88 |
|
89 | 89 |
# Install Go |
90 | 90 |
# IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines |
91 |
-# will need updating, to avoid errors. Ping #docker-maintainers on IRC |
|
91 |
+# will need updating, to avoid errors. Ping #docker-maintainers on IRC |
|
92 | 92 |
# with a heads-up. |
93 | 93 |
ENV GO_VERSION 1.5.3 |
94 | 94 |
RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" \ |
... | ... |
@@ -168,7 +168,7 @@ RUN set -x \ |
168 | 168 |
&& rm -rf "$GOPATH" |
169 | 169 |
|
170 | 170 |
# Install notary server |
171 |
-ENV NOTARY_VERSION docker-v1.10-5 |
|
171 |
+ENV NOTARY_VERSION docker-v1.10.2-1 |
|
172 | 172 |
RUN set -x \ |
173 | 173 |
&& export GOPATH="$(mktemp -d)" \ |
174 | 174 |
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \ |
... | ... |
@@ -145,7 +145,7 @@ RUN set -x \ |
145 | 145 |
&& rm -rf "$GOPATH" |
146 | 146 |
|
147 | 147 |
# Install notary server |
148 |
-ENV NOTARY_VERSION docker-v1.10-5 |
|
148 |
+ENV NOTARY_VERSION docker-v1.10.2-1 |
|
149 | 149 |
RUN set -x \ |
150 | 150 |
&& export GOPATH="$(mktemp -d)" \ |
151 | 151 |
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \ |
... | ... |
@@ -116,7 +116,7 @@ RUN set -x \ |
116 | 116 |
&& rm -rf "$GOPATH" |
117 | 117 |
|
118 | 118 |
# Install notary server |
119 |
-#ENV NOTARY_VERSION docker-v1.10-5 |
|
119 |
+#ENV NOTARY_VERSION docker-v1.10.2-1 |
|
120 | 120 |
#RUN set -x \ |
121 | 121 |
# && export GOPATH="$(mktemp -d)" \ |
122 | 122 |
# && git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \ |
... | ... |
@@ -116,7 +116,7 @@ RUN set -x \ |
116 | 116 |
&& rm -rf "$GOPATH" |
117 | 117 |
|
118 | 118 |
# Install notary server |
119 |
-ENV NOTARY_VERSION docker-v1.10-5 |
|
119 |
+ENV NOTARY_VERSION docker-v1.10.2-1 |
|
120 | 120 |
RUN set -x \ |
121 | 121 |
&& export GOPATH="$(mktemp -d)" \ |
122 | 122 |
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \ |
... | ... |
@@ -50,7 +50,7 @@ clone git github.com/docker/distribution 0f2d99b13ae0cfbcf118eff103e6e680b726b47 |
50 | 50 |
clone git github.com/vbatts/tar-split v0.9.11 |
51 | 51 |
|
52 | 52 |
# get desired notary commit, might also need to be updated in Dockerfile |
53 |
-clone git github.com/docker/notary docker-v1.10-5 |
|
53 |
+clone git github.com/docker/notary docker-v1.10.2-1 |
|
54 | 54 |
|
55 | 55 |
clone git google.golang.org/grpc 174192fc93efcb188fc8f46ca447f0da606b6885 https://github.com/grpc/grpc-go.git |
56 | 56 |
clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf |
... | ... |
@@ -9,6 +9,7 @@ import ( |
9 | 9 |
"net/url" |
10 | 10 |
"os" |
11 | 11 |
"path/filepath" |
12 |
+ "strings" |
|
12 | 13 |
"time" |
13 | 14 |
|
14 | 15 |
"github.com/Sirupsen/logrus" |
... | ... |
@@ -451,11 +452,48 @@ func (r *NotaryRepository) ListTargets(roles ...string) ([]*TargetWithRole, erro |
451 | 451 |
roles = []string{data.CanonicalTargetsRole} |
452 | 452 |
} |
453 | 453 |
targets := make(map[string]*TargetWithRole) |
454 |
+ |
|
454 | 455 |
for _, role := range roles { |
456 |
+ var foundRole *data.Role |
|
457 |
+ walkRoles := []*data.Role{} |
|
458 |
+ if role == data.CanonicalTargetsRole { |
|
459 |
+ foundRole = &data.Role{ |
|
460 |
+ Name: data.CanonicalTargetsRole, |
|
461 |
+ Paths: []string{""}, |
|
462 |
+ PathHashPrefixes: []string{""}, |
|
463 |
+ } |
|
464 |
+ } |
|
465 |
+ |
|
466 |
+ walkRoles = append(walkRoles, r.tufRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles...) |
|
467 |
+ for len(walkRoles) > 0 && foundRole == nil { |
|
468 |
+ currRole := walkRoles[0] |
|
469 |
+ walkRoles = walkRoles[1:] |
|
470 |
+ if currRole.Name == role { |
|
471 |
+ foundRole = currRole |
|
472 |
+ break |
|
473 |
+ } |
|
474 |
+ if strings.HasPrefix(role, currRole.Name+"/") { |
|
475 |
+ targetMeta, ok := r.tufRepo.Targets[currRole.Name] |
|
476 |
+ if !ok { |
|
477 |
+ continue |
|
478 |
+ } |
|
479 |
+ for _, childRole := range targetMeta.Signed.Delegations.Roles { |
|
480 |
+ restricted, err := data.Restrict(*currRole, *childRole) |
|
481 |
+ if err == nil { |
|
482 |
+ walkRoles = append(walkRoles, restricted) |
|
483 |
+ } |
|
484 |
+ } |
|
485 |
+ } |
|
486 |
+ } |
|
487 |
+ |
|
488 |
+ if foundRole == nil { |
|
489 |
+ continue |
|
490 |
+ } |
|
491 |
+ |
|
455 | 492 |
// we don't need to do anything special with removing role from |
456 | 493 |
// roles because listSubtree always processes role and only excludes |
457 | 494 |
// descendant delegations that appear in roles. |
458 |
- r.listSubtree(targets, role, roles...) |
|
495 |
+ r.listSubtree(targets, foundRole, roles...) |
|
459 | 496 |
} |
460 | 497 |
|
461 | 498 |
var targetList []*TargetWithRole |
... | ... |
@@ -466,29 +504,32 @@ func (r *NotaryRepository) ListTargets(roles ...string) ([]*TargetWithRole, erro |
466 | 466 |
return targetList, nil |
467 | 467 |
} |
468 | 468 |
|
469 |
-func (r *NotaryRepository) listSubtree(targets map[string]*TargetWithRole, role string, exclude ...string) { |
|
469 |
+func (r *NotaryRepository) listSubtree(targets map[string]*TargetWithRole, role *data.Role, exclude ...string) { |
|
470 | 470 |
excl := make(map[string]bool) |
471 | 471 |
for _, r := range exclude { |
472 | 472 |
excl[r] = true |
473 | 473 |
} |
474 |
- roles := []string{role} |
|
474 |
+ roles := []*data.Role{role} |
|
475 | 475 |
for len(roles) > 0 { |
476 | 476 |
role = roles[0] |
477 | 477 |
roles = roles[1:] |
478 |
- tgts, ok := r.tufRepo.Targets[role] |
|
478 |
+ tgts, ok := r.tufRepo.Targets[role.Name] |
|
479 | 479 |
if !ok { |
480 | 480 |
// not every role has to exist |
481 | 481 |
continue |
482 | 482 |
} |
483 | 483 |
for name, meta := range tgts.Signed.Targets { |
484 |
- if _, ok := targets[name]; !ok { |
|
484 |
+ if _, ok := targets[name]; !ok && role.CheckPaths(name) { |
|
485 | 485 |
targets[name] = &TargetWithRole{ |
486 |
- Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: role} |
|
486 |
+ Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: role.Name} |
|
487 | 487 |
} |
488 | 488 |
} |
489 |
- for _, d := range tgts.Signed.Delegations.Roles { |
|
490 |
- if !excl[d.Name] { |
|
491 |
- roles = append(roles, d.Name) |
|
489 |
+ for _, child := range tgts.Signed.Delegations.Roles { |
|
490 |
+ if !excl[child.Name] { |
|
491 |
+ child, err := data.Restrict(*role, *child) |
|
492 |
+ if err == nil { |
|
493 |
+ roles = append(roles, child) |
|
494 |
+ } |
|
492 | 495 |
} |
493 | 496 |
} |
494 | 497 |
} |
... | ... |
@@ -511,10 +552,47 @@ func (r *NotaryRepository) GetTargetByName(name string, roles ...string) (*Targe |
511 | 511 |
roles = append(roles, data.CanonicalTargetsRole) |
512 | 512 |
} |
513 | 513 |
for _, role := range roles { |
514 |
- meta, foundRole := c.TargetMeta(role, name, roles...) |
|
514 |
+ |
|
515 |
+ var foundRole *data.Role |
|
516 |
+ walkRoles := []*data.Role{} |
|
517 |
+ if role == data.CanonicalTargetsRole { |
|
518 |
+ foundRole = &data.Role{ |
|
519 |
+ Name: data.CanonicalTargetsRole, |
|
520 |
+ Paths: []string{""}, |
|
521 |
+ PathHashPrefixes: []string{""}, |
|
522 |
+ } |
|
523 |
+ } |
|
524 |
+ |
|
525 |
+ walkRoles = append(walkRoles, r.tufRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles...) |
|
526 |
+ for len(walkRoles) > 0 && foundRole == nil { |
|
527 |
+ currRole := walkRoles[0] |
|
528 |
+ walkRoles = walkRoles[1:] |
|
529 |
+ if currRole.Name == role { |
|
530 |
+ foundRole = currRole |
|
531 |
+ break |
|
532 |
+ } |
|
533 |
+ if strings.HasPrefix(role, currRole.Name+"/") { |
|
534 |
+ targetMeta, ok := r.tufRepo.Targets[currRole.Name] |
|
535 |
+ if !ok { |
|
536 |
+ continue |
|
537 |
+ } |
|
538 |
+ for _, childRole := range targetMeta.Signed.Delegations.Roles { |
|
539 |
+ restricted, err := data.Restrict(*currRole, *childRole) |
|
540 |
+ if err == nil && restricted.CheckPaths(name) { |
|
541 |
+ walkRoles = append(walkRoles, restricted) |
|
542 |
+ } |
|
543 |
+ } |
|
544 |
+ } |
|
545 |
+ } |
|
546 |
+ |
|
547 |
+ if foundRole == nil { |
|
548 |
+ continue |
|
549 |
+ } |
|
550 |
+ |
|
551 |
+ meta, ownerName := c.TargetMeta(foundRole, name, roles...) |
|
515 | 552 |
if meta != nil { |
516 | 553 |
return &TargetWithRole{ |
517 |
- Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: foundRole}, nil |
|
554 |
+ Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: ownerName}, nil |
|
518 | 555 |
} |
519 | 556 |
} |
520 | 557 |
return nil, fmt.Errorf("No trust data for %s", name) |
... | ... |
@@ -526,39 +526,44 @@ func (c Client) RoleTargetsPath(role string, hashSha256 string, consistent bool) |
526 | 526 |
|
527 | 527 |
// TargetMeta ensures the repo is up to date. It assumes downloadTargets |
528 | 528 |
// has already downloaded all delegated roles |
529 |
-func (c Client) TargetMeta(role, path string, excludeRoles ...string) (*data.FileMeta, string) { |
|
529 |
+func (c Client) TargetMeta(role *data.Role, path string, excludeRoles ...string) (*data.FileMeta, string) { |
|
530 | 530 |
excl := make(map[string]bool) |
531 | 531 |
for _, r := range excludeRoles { |
532 | 532 |
excl[r] = true |
533 | 533 |
} |
534 | 534 |
|
535 |
- pathDigest := sha256.Sum256([]byte(path)) |
|
536 |
- pathHex := hex.EncodeToString(pathDigest[:]) |
|
537 |
- |
|
538 | 535 |
// FIFO list of targets delegations to inspect for target |
539 |
- roles := []string{role} |
|
536 |
+ roles := []*data.Role{role} |
|
540 | 537 |
var ( |
541 | 538 |
meta *data.FileMeta |
542 |
- curr string |
|
539 |
+ curr *data.Role |
|
543 | 540 |
) |
544 | 541 |
for len(roles) > 0 { |
545 | 542 |
// have to do these lines here because of order of execution in for statement |
546 | 543 |
curr = roles[0] |
547 | 544 |
roles = roles[1:] |
548 | 545 |
|
549 |
- meta = c.local.TargetMeta(curr, path) |
|
546 |
+ meta = c.local.TargetMeta(curr.Name, path) |
|
550 | 547 |
if meta != nil { |
551 | 548 |
// we found the target! |
552 |
- return meta, curr |
|
549 |
+ return meta, curr.Name |
|
550 |
+ } |
|
551 |
+ tgts, ok := c.local.Targets[curr.Name] |
|
552 |
+ if !ok { |
|
553 |
+ // not every role has to exist |
|
554 |
+ continue |
|
553 | 555 |
} |
554 |
- delegations := c.local.TargetDelegations(curr, path, pathHex) |
|
555 |
- for _, d := range delegations { |
|
556 |
- if !excl[d.Name] { |
|
557 |
- roles = append(roles, d.Name) |
|
556 |
+ |
|
557 |
+ for _, child := range tgts.Signed.Delegations.Roles { |
|
558 |
+ if !excl[child.Name] { |
|
559 |
+ child, err := data.Restrict(*curr, *child) |
|
560 |
+ if err == nil && child.CheckPaths(path) { |
|
561 |
+ roles = append(roles, child) |
|
562 |
+ } |
|
558 | 563 |
} |
559 | 564 |
} |
560 | 565 |
} |
561 |
- return meta, "" |
|
566 |
+ return nil, "" |
|
562 | 567 |
} |
563 | 568 |
|
564 | 569 |
// DownloadTarget downloads the target to dst from the remote |
... | ... |
@@ -2,10 +2,11 @@ package data |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 |
- "github.com/Sirupsen/logrus" |
|
6 | 5 |
"path" |
7 | 6 |
"regexp" |
8 | 7 |
"strings" |
8 |
+ |
|
9 |
+ "github.com/Sirupsen/logrus" |
|
9 | 10 |
) |
10 | 11 |
|
11 | 12 |
// Canonical base role names |
... | ... |
@@ -244,3 +245,40 @@ func subtractStrSlices(orig, remove []string) []string { |
244 | 244 |
} |
245 | 245 |
return keep |
246 | 246 |
} |
247 |
+ |
|
248 |
+// Restrict restricts the paths and path hash prefixes for the passed in delegation role, |
|
249 |
+// returning a copy of the role with validated paths as if it was a direct child |
|
250 |
+func Restrict(parent, child Role) (*Role, error) { |
|
251 |
+ if path.Dir(child.Name) != parent.Name { |
|
252 |
+ return nil, fmt.Errorf("%s is not a parent of %s", parent.Name, child.Name) |
|
253 |
+ } |
|
254 |
+ return &Role{ |
|
255 |
+ RootRole: child.RootRole, |
|
256 |
+ Name: child.Name, |
|
257 |
+ Paths: RestrictDelegationPathPrefixes(parent.Paths, child.Paths), |
|
258 |
+ }, nil |
|
259 |
+} |
|
260 |
+ |
|
261 |
+// RestrictDelegationPathPrefixes returns the list of valid delegationPaths that are prefixed by parentPaths |
|
262 |
+func RestrictDelegationPathPrefixes(parentPaths, delegationPaths []string) []string { |
|
263 |
+ validPaths := []string{} |
|
264 |
+ if len(delegationPaths) == 0 { |
|
265 |
+ return validPaths |
|
266 |
+ } |
|
267 |
+ |
|
268 |
+ // Validate each individual delegation path |
|
269 |
+ for _, delgPath := range delegationPaths { |
|
270 |
+ isPrefixed := false |
|
271 |
+ for _, parentPath := range parentPaths { |
|
272 |
+ if strings.HasPrefix(delgPath, parentPath) { |
|
273 |
+ isPrefixed = true |
|
274 |
+ break |
|
275 |
+ } |
|
276 |
+ } |
|
277 |
+ // If the delegation path did not match prefix against any parent path, it is not valid |
|
278 |
+ if isPrefixed { |
|
279 |
+ validPaths = append(validPaths, delgPath) |
|
280 |
+ } |
|
281 |
+ } |
|
282 |
+ return validPaths |
|
283 |
+} |
... | ... |
@@ -459,6 +459,9 @@ func (tr *Repo) SetTargets(role string, s *data.SignedTargets) error { |
459 | 459 |
tr.keysDB.AddKey(k) |
460 | 460 |
} |
461 | 461 |
for _, r := range s.Signed.Delegations.Roles { |
462 |
+ if path.Dir(r.Name) != role || tr.keysDB.GetRole(r.Name) != nil { |
|
463 |
+ continue |
|
464 |
+ } |
|
462 | 465 |
tr.keysDB.AddRole(r) |
463 | 466 |
} |
464 | 467 |
tr.Targets[role] = s |