Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
Alexander Morozov 2015-04-20 12:48:33 -07:00
Родитель b5584ec24a
Коммит 9e50bf6270
6 изменённых файлов: 74 добавлений и 85 удалений

Просмотреть файл

@ -108,7 +108,6 @@ type Daemon struct {
containerGraph *graphdb.Database
driver graphdriver.Driver
execDriver execdriver.Driver
trustStore *trust.TrustStore
statsCollector *statsCollector
defaultLogConfig runconfig.LogConfig
RegistryService *registry.Service
@ -129,9 +128,6 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
if err := daemon.Repositories().Install(eng); err != nil {
return err
}
if err := daemon.trustStore.Install(eng); err != nil {
return err
}
// FIXME: this hack is necessary for legacy integration tests to access
// the daemon object.
eng.HackSetGlobalVar("httpapi.daemon", daemon)
@ -903,22 +899,29 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
return nil, err
}
eventsService := events.New()
logrus.Debug("Creating repository list")
repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, trustKey, registryService, eventsService)
if err != nil {
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
}
trustDir := path.Join(config.Root, "trust")
if err := os.MkdirAll(trustDir, 0700); err != nil && !os.IsExist(err) {
return nil, err
}
t, err := trust.NewTrustStore(trustDir)
trustService, err := trust.NewTrustStore(trustDir)
if err != nil {
return nil, fmt.Errorf("could not create trust store: %s", err)
}
eventsService := events.New()
logrus.Debug("Creating repository list")
tagCfg := &graph.TagStoreConfig{
Graph: g,
Key: trustKey,
Registry: registryService,
Events: eventsService,
Trust: trustService,
}
repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), tagCfg)
if err != nil {
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
}
if !config.DisableNetwork {
if err := bridge.InitDriver(&config.Bridge); err != nil {
return nil, fmt.Errorf("Error initializing Bridge: %v", err)
@ -980,7 +983,6 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
sysInitPath: sysInitPath,
execDriver: ed,
eng: eng,
trustStore: t,
statsCollector: newStatsCollector(1 * time.Second),
defaultLogConfig: config.LogConfig,
RegistryService: registryService,

Просмотреть файл

@ -1,7 +1,6 @@
package graph
import (
"bytes"
"encoding/json"
"fmt"
@ -9,6 +8,7 @@ import (
"github.com/docker/distribution/digest"
"github.com/docker/docker/engine"
"github.com/docker/docker/registry"
"github.com/docker/docker/trust"
"github.com/docker/docker/utils"
"github.com/docker/libtrust"
)
@ -69,32 +69,28 @@ func (s *TagStore) loadManifest(eng *engine.Engine, manifestBytes []byte, dgst,
var verified bool
for _, key := range keys {
job := eng.Job("trust_key_check")
b, err := key.MarshalJSON()
if err != nil {
return nil, false, fmt.Errorf("error marshalling public key: %s", err)
}
namespace := manifest.Name
if namespace[0] != '/' {
namespace = "/" + namespace
}
stdoutBuffer := bytes.NewBuffer(nil)
job.Args = append(job.Args, namespace)
job.Setenv("PublicKey", string(b))
// Check key has read/write permission (0x03)
job.SetenvInt("Permission", 0x03)
job.Stdout.Add(stdoutBuffer)
if err = job.Run(); err != nil {
return nil, false, fmt.Errorf("error running key check: %s", err)
b, err := key.MarshalJSON()
if err != nil {
return nil, false, fmt.Errorf("error marshalling public key: %s", err)
}
result := engine.Tail(stdoutBuffer, 1)
logrus.Debugf("Key check result: %q", result)
if result == "verified" {
verified = true
// Check key has read/write permission (0x03)
v, err := s.trustService.CheckKey(namespace, b, 0x03)
if err != nil {
vErr, ok := err.(trust.NotVerifiedError)
if !ok {
return nil, false, fmt.Errorf("error running key check: %s", err)
}
logrus.Debugf("Key check result: %v", vErr)
}
verified = v
if verified {
logrus.Debug("Key check result: verified")
}
}
return &manifest, verified, nil
}

Просмотреть файл

@ -70,10 +70,7 @@ func (s *TagStore) Pull(image string, tag string, imagePullConfig *ImagePullConf
if len(repoInfo.Index.Mirrors) == 0 && (repoInfo.Index.Official || endpoint.Version == registry.APIVersion2) {
if repoInfo.Official {
j := eng.Job("trust_update_base")
if err = j.Run(); err != nil {
logrus.Errorf("error updating trust base graph: %s", err)
}
s.trustService.UpdateBase()
}
logrus.Debugf("pulling v2 repository with local name %q", repoInfo.LocalName)

Просмотреть файл

@ -18,6 +18,7 @@ import (
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/registry"
"github.com/docker/docker/trust"
"github.com/docker/docker/utils"
"github.com/docker/libtrust"
)
@ -42,6 +43,7 @@ type TagStore struct {
pushingPool map[string]chan struct{}
registryService *registry.Service
eventsService *events.Events
trustService *trust.TrustStore
}
type Repository map[string]string
@ -64,7 +66,15 @@ func (r Repository) Contains(u Repository) bool {
return true
}
func NewTagStore(path string, graph *Graph, key libtrust.PrivateKey, registryService *registry.Service, eventsService *events.Events) (*TagStore, error) {
type TagStoreConfig struct {
Graph *Graph
Key libtrust.PrivateKey
Registry *registry.Service
Events *events.Events
Trust *trust.TrustStore
}
func NewTagStore(path string, cfg *TagStoreConfig) (*TagStore, error) {
abspath, err := filepath.Abs(path)
if err != nil {
return nil, err
@ -72,13 +82,14 @@ func NewTagStore(path string, graph *Graph, key libtrust.PrivateKey, registrySer
store := &TagStore{
path: abspath,
graph: graph,
trustKey: key,
graph: cfg.Graph,
trustKey: cfg.Key,
Repositories: make(map[string]Repository),
pullingPool: make(map[string]chan struct{}),
pushingPool: make(map[string]chan struct{}),
registryService: registryService,
eventsService: eventsService,
registryService: cfg.Registry,
eventsService: cfg.Events,
trustService: cfg.Trust,
}
// Load the json file if it exists, otherwise create it.
if err := store.reload(); os.IsNotExist(err) {

Просмотреть файл

@ -60,7 +60,11 @@ func mkTestTagStore(root string, t *testing.T) *TagStore {
if err != nil {
t.Fatal(err)
}
store, err := NewTagStore(path.Join(root, "tags"), graph, nil, nil, events.New())
tagCfg := &TagStoreConfig{
Graph: graph,
Events: events.New(),
}
store, err := NewTagStore(path.Join(root, "tags"), tagCfg)
if err != nil {
t.Fatal(err)
}

Просмотреть файл

@ -5,70 +5,49 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/engine"
"github.com/docker/libtrust"
)
func (t *TrustStore) Install(eng *engine.Engine) error {
for name, handler := range map[string]engine.Handler{
"trust_key_check": t.CmdCheckKey,
"trust_update_base": t.CmdUpdateBase,
} {
if err := eng.Register(name, handler); err != nil {
return fmt.Errorf("Could not register %q: %v", name, err)
}
}
return nil
type NotVerifiedError string
func (e NotVerifiedError) Error() string {
return string(e)
}
func (t *TrustStore) CmdCheckKey(job *engine.Job) error {
if n := len(job.Args); n != 1 {
return fmt.Errorf("Usage: %s NAMESPACE", job.Name)
func (t *TrustStore) CheckKey(ns string, key []byte, perm uint16) (bool, error) {
if len(key) == 0 {
return false, fmt.Errorf("Missing PublicKey")
}
var (
namespace = job.Args[0]
keyBytes = job.Getenv("PublicKey")
)
if keyBytes == "" {
return fmt.Errorf("Missing PublicKey")
}
pk, err := libtrust.UnmarshalPublicKeyJWK([]byte(keyBytes))
pk, err := libtrust.UnmarshalPublicKeyJWK(key)
if err != nil {
return fmt.Errorf("Error unmarshalling public key: %s", err)
return false, fmt.Errorf("Error unmarshalling public key: %v", err)
}
permission := uint16(job.GetenvInt("Permission"))
if permission == 0 {
permission = 0x03
if perm == 0 {
perm = 0x03
}
t.RLock()
defer t.RUnlock()
if t.graph == nil {
job.Stdout.Write([]byte("no graph"))
return nil
return false, NotVerifiedError("no graph")
}
// Check if any expired grants
verified, err := t.graph.Verify(pk, namespace, permission)
verified, err := t.graph.Verify(pk, ns, perm)
if err != nil {
return fmt.Errorf("Error verifying key to namespace: %s", namespace)
return false, fmt.Errorf("Error verifying key to namespace: %s", ns)
}
if !verified {
logrus.Debugf("Verification failed for %s using key %s", namespace, pk.KeyID())
job.Stdout.Write([]byte("not verified"))
} else if t.expiration.Before(time.Now()) {
job.Stdout.Write([]byte("expired"))
} else {
job.Stdout.Write([]byte("verified"))
logrus.Debugf("Verification failed for %s using key %s", ns, pk.KeyID())
return false, NotVerifiedError("not verified")
}
return nil
if t.expiration.Before(time.Now()) {
return false, NotVerifiedError("expired")
}
return true, nil
}
func (t *TrustStore) CmdUpdateBase(job *engine.Job) error {
func (t *TrustStore) UpdateBase() {
t.fetch()
return nil
}