1 package client
2
3 import (
4 "github.com/theupdateframework/go-tuf/data"
5 "github.com/theupdateframework/go-tuf/pkg/targets"
6 "github.com/theupdateframework/go-tuf/verify"
7 )
8
9
10
11 func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) {
12 snapshot, err := c.loadLocalSnapshot()
13 if err != nil {
14 return data.TargetFileMeta{}, err
15 }
16
17 targetFileMeta, _, err := c.getTargetFileMetaDelegationPath(target, snapshot)
18 if err != nil {
19 return data.TargetFileMeta{}, err
20 }
21 return targetFileMeta, nil
22 }
23
24
25
26
27 func (c *Client) getTargetFileMetaDelegationPath(target string, snapshot *data.Snapshot) (data.TargetFileMeta, []string, error) {
28
29
30
31
32
33 delegations, err := targets.NewDelegationsIterator(target, c.db)
34 if err != nil {
35 return data.TargetFileMeta{}, nil, err
36 }
37
38 targetFileMeta := data.TargetFileMeta{}
39 delegationRole := ""
40
41 for i := 0; i < c.MaxDelegations; i++ {
42 d, ok := delegations.Next()
43 if !ok {
44 return data.TargetFileMeta{}, nil, ErrUnknownTarget{target, snapshot.Version}
45 }
46
47
48 targets, err := c.loadDelegatedTargets(snapshot, d.Delegatee.Name, d.DB)
49 if err != nil {
50 return data.TargetFileMeta{}, nil, err
51 }
52
53
54 if m, ok := targets.Targets[target]; ok {
55 delegationRole = d.Delegatee.Name
56 targetFileMeta = m
57 break
58 }
59
60 if targets.Delegations != nil {
61 delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations)
62 if err != nil {
63 return data.TargetFileMeta{}, nil, err
64 }
65 err = delegations.Add(targets.Delegations.Roles, d.Delegatee.Name, delegationsDB)
66 if err != nil {
67 return data.TargetFileMeta{}, nil, err
68 }
69 }
70 }
71
72 if len(delegationRole) > 0 {
73 return targetFileMeta, buildPath(delegations.Parent, delegationRole, ""), nil
74 }
75
76 return data.TargetFileMeta{}, nil, ErrMaxDelegations{
77 Target: target,
78 MaxDelegations: c.MaxDelegations,
79 SnapshotVersion: snapshot.Version,
80 }
81 }
82
83 func buildPath(parent func(string) string, start string, end string) []string {
84 if start == end {
85 return nil
86 }
87
88 path := []string{start}
89 current := start
90 for {
91 current = parent(current)
92 if current == end {
93 break
94 }
95 path = append(path, current)
96 }
97 return path
98 }
99
100 func (c *Client) loadLocalSnapshot() (*data.Snapshot, error) {
101 if err := c.getLocalMeta(); err != nil {
102 return nil, err
103 }
104 rawS, ok := c.localMeta["snapshot.json"]
105 if !ok {
106 return nil, ErrNoLocalSnapshot
107 }
108
109 snapshot := &data.Snapshot{}
110 if err := c.db.Unmarshal(rawS, snapshot, "snapshot", c.snapshotVer); err != nil {
111 return nil, ErrDecodeFailed{"snapshot.json", err}
112 }
113 return snapshot, nil
114 }
115
116
117 func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, role string, db *verify.DB) (*data.Targets, error) {
118 var err error
119 fileName := role + ".json"
120 fileMeta, ok := snapshot.Meta[fileName]
121 if !ok {
122 return nil, ErrRoleNotInSnapshot{role, snapshot.Version}
123 }
124
125
126
127
128 raw, alreadyStored := c.localMetaFromSnapshot(fileName, fileMeta)
129 if !alreadyStored {
130 raw, err = c.downloadMetaFromSnapshot(fileName, fileMeta)
131 if err != nil {
132 return nil, err
133 }
134 }
135
136 targets := &data.Targets{}
137
138
139
140 err = db.Unmarshal(raw, targets, role, fileMeta.Version)
141 if err != nil {
142 return nil, ErrDecodeFailed{fileName, err}
143 }
144
145
146 if !alreadyStored {
147 if err := c.local.SetMeta(fileName, raw); err != nil {
148 return nil, err
149 }
150 }
151 return targets, nil
152 }
153
View as plain text