This file is indexed.

/usr/share/gocode/src/github.com/docker/libtrust/trustgraph/memory_graph.go is in golang-github-docker-libtrust-dev 0.0~git20150526.0.9cbd2a1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package trustgraph

import (
	"strings"

	"github.com/docker/libtrust"
)

type grantNode struct {
	grants   []*Grant
	children map[string]*grantNode
}

type memoryGraph struct {
	roots map[string]*grantNode
}

func newGrantNode() *grantNode {
	return &grantNode{
		grants:   []*Grant{},
		children: map[string]*grantNode{},
	}
}

// NewMemoryGraph returns a new in memory trust graph created from
// a static list of grants.  This graph is immutable after creation
// and any alterations should create a new instance.
func NewMemoryGraph(grants []*Grant) TrustGraph {
	roots := map[string]*grantNode{}
	for _, grant := range grants {
		parts := strings.Split(grant.Grantee, "/")
		nodes := roots
		var node *grantNode
		var nodeOk bool
		for _, part := range parts {
			node, nodeOk = nodes[part]
			if !nodeOk {
				node = newGrantNode()
				nodes[part] = node
			}
			if part != "" {
				node.grants = append(node.grants, grant)
			}
			nodes = node.children
		}
	}
	return &memoryGraph{roots}
}

func (g *memoryGraph) getGrants(name string) []*Grant {
	nameParts := strings.Split(name, "/")
	nodes := g.roots
	var node *grantNode
	var nodeOk bool
	for _, part := range nameParts {
		node, nodeOk = nodes[part]
		if !nodeOk {
			return nil
		}
		nodes = node.children
	}
	return node.grants
}

func isSubName(name, sub string) bool {
	if strings.HasPrefix(name, sub) {
		if len(name) == len(sub) || name[len(sub)] == '/' {
			return true
		}
	}
	return false
}

type walkFunc func(*Grant, []*Grant) bool

func foundWalkFunc(*Grant, []*Grant) bool {
	return true
}

func (g *memoryGraph) walkGrants(start, target string, permission uint16, f walkFunc, chain []*Grant, visited map[*Grant]bool, collect bool) bool {
	if visited == nil {
		visited = map[*Grant]bool{}
	}
	grants := g.getGrants(start)
	subGrants := make([]*Grant, 0, len(grants))
	for _, grant := range grants {
		if visited[grant] {
			continue
		}
		visited[grant] = true
		if grant.Permission&permission == permission {
			if isSubName(target, grant.Subject) {
				if f(grant, chain) {
					return true
				}
			} else {
				subGrants = append(subGrants, grant)
			}
		}
	}
	for _, grant := range subGrants {
		var chainCopy []*Grant
		if collect {
			chainCopy = make([]*Grant, len(chain)+1)
			copy(chainCopy, chain)
			chainCopy[len(chainCopy)-1] = grant
		} else {
			chainCopy = nil
		}

		if g.walkGrants(grant.Subject, target, permission, f, chainCopy, visited, collect) {
			return true
		}
	}
	return false
}

func (g *memoryGraph) Verify(key libtrust.PublicKey, node string, permission uint16) (bool, error) {
	return g.walkGrants(key.KeyID(), node, permission, foundWalkFunc, nil, nil, false), nil
}

func (g *memoryGraph) GetGrants(key libtrust.PublicKey, node string, permission uint16) ([][]*Grant, error) {
	grants := [][]*Grant{}
	collect := func(grant *Grant, chain []*Grant) bool {
		grantChain := make([]*Grant, len(chain)+1)
		copy(grantChain, chain)
		grantChain[len(grantChain)-1] = grant
		grants = append(grants, grantChain)
		return false
	}
	g.walkGrants(key.KeyID(), node, permission, collect, nil, nil, true)
	return grants, nil
}