From 8c6de46aca69787082af2f6a14375d54d78ffd07 Mon Sep 17 00:00:00 2001 From: Diogo Monica Date: Thu, 9 Jul 2015 14:51:31 -0700 Subject: [PATCH] Added list keys that ignores symlinks --- client/client.go | 16 +++++----------- client/client_test.go | 2 +- cmd/notary/keys.go | 4 ++-- trustmanager/filestore.go | 32 ++++++++++++++++---------------- trustmanager/filestore_test.go | 27 ++++++++++++++++++++------- trustmanager/keyfilestore.go | 9 ++++++++- trustmanager/x509filestore.go | 5 +++-- trustmanager/x509utils.go | 2 +- 8 files changed, 56 insertions(+), 41 deletions(-) diff --git a/client/client.go b/client/client.go index a786c15e17..444d7ed630 100644 --- a/client/client.go +++ b/client/client.go @@ -515,7 +515,7 @@ Example TUF Content for root key: } } */ -func (r *NotaryRepository) ValidateRoot(root *data.Signed) error { +func (r *NotaryRepository) validateRoot(root *data.Signed) error { rootSigned := &data.Root{} err := json.Unmarshal(root.Signed, rootSigned) if err != nil { @@ -581,7 +581,7 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) { return nil, err } - err = r.ValidateRoot(root) + err = r.validateRoot(root) if err != nil { return nil, err } @@ -594,8 +594,6 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) { return nil, err } - // TODO(dlaw): Where does this keyDB come in - return tufclient.NewClient( r.tufRepo, remote, @@ -603,14 +601,10 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) { ), nil } -// ListPrivateKeys lists all availables private keys. Does not include private key +// ListPrivateKeys lists all available root keys. Does not include private key // material -func (c *NotaryRepository) ListPrivateKeys() []string { - // TODO(diogo): Make this work - for _, k := range c.rootKeyStore.ListAll() { - fmt.Println(k) - } - return nil +func (c *NotaryRepository) ListRootKeys() []string { + return c.rootKeyStore.ListKeys() } // GenRootKey generates a new root key protected by a given passphrase diff --git a/client/client_test.go b/client/client_test.go index d89b0552b4..bb89273cd2 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -52,7 +52,7 @@ func TestInitRepo(t *testing.T) { // Look for keys in private. The filenames should match the key IDs // in the private key store. - privKeyList := repo.privKeyStore.ListAll() + privKeyList := repo.privKeyStore.ListFiles(true) for _, privKeyName := range privKeyList { _, err := os.Stat(privKeyName) assert.NoError(t, err, "missing private key: %s", privKeyName) diff --git a/cmd/notary/keys.go b/cmd/notary/keys.go index 897ea2472f..7b3cc58923 100644 --- a/cmd/notary/keys.go +++ b/cmd/notary/keys.go @@ -92,7 +92,7 @@ func keysRemove(cmd *cobra.Command, args []string) { } // We didn't find a certificate with this ID, let's try to see if we can find keys. - keyList := privKeyStore.ListDir(gunOrID) + keyList := privKeyStore.ListDir(gunOrID, true) if len(keyList) < 1 { fatalf("no Private Keys found under Global Unique Name: %s", gunOrID) } @@ -187,7 +187,7 @@ func keysList(cmd *cobra.Command, args []string) { fmt.Println("") fmt.Println("# Signing keys: ") - for _, k := range privKeyStore.ListAll() { + for _, k := range privKeyStore.ListFiles(true) { printKey(k) } } diff --git a/trustmanager/filestore.go b/trustmanager/filestore.go index e55dbdeba0..44ad6b2774 100644 --- a/trustmanager/filestore.go +++ b/trustmanager/filestore.go @@ -17,17 +17,11 @@ type FileStore interface { RemoveDir(directoryName string) error Get(fileName string) ([]byte, error) GetPath(fileName string) string - ListAll() []string - ListDir(directoryName string) []string + ListFiles(symlinks bool) []string + ListDir(directoryName string, symlinks bool) []string Link(src, dst string) error } -type EncryptedFileStore interface { - FileStore - AddEncrypted(fileName string, data []byte, passphrase string) error - GetDecrypted(fileName, passphrase string) ([]byte, error) -} - // SimpleFileStore implements FileStore type SimpleFileStore struct { baseDir string @@ -36,7 +30,7 @@ type SimpleFileStore struct { } // NewFileStore creates a directory with 755 permissions -func NewFileStore(baseDir string, fileExt string) (FileStore, error) { +func NewSimpleFileStore(baseDir string, fileExt string) (FileStore, error) { if err := CreateDirectory(baseDir); err != nil { return nil, err } @@ -49,7 +43,7 @@ func NewFileStore(baseDir string, fileExt string) (FileStore, error) { } // NewPrivateFileStore creates a directory with 700 permissions -func NewPrivateFileStore(baseDir string, fileExt string) (FileStore, error) { +func NewPrivateSimpleFileStore(baseDir string, fileExt string) (FileStore, error) { if err := CreatePrivateDirectory(baseDir); err != nil { return nil, err } @@ -110,18 +104,18 @@ func (f *SimpleFileStore) GetPath(name string) string { } // List lists all the files inside of a store -func (f *SimpleFileStore) ListAll() []string { - return f.list(f.baseDir) +func (f *SimpleFileStore) ListFiles(symlinks bool) []string { + return f.list(f.baseDir, symlinks) } // List lists all the files inside of a directory identified by a name -func (f *SimpleFileStore) ListDir(name string) []string { +func (f *SimpleFileStore) ListDir(name string, symlinks bool) []string { fullPath := filepath.Join(f.baseDir, name) - return f.list(fullPath) + return f.list(fullPath, symlinks) } -// list lists all the files in a directory given a full path -func (f *SimpleFileStore) list(path string) []string { +// list lists all the files in a directory given a full path. Ignores symlinks. +func (f *SimpleFileStore) list(path string, symlinks bool) []string { files := make([]string, 0, 0) filepath.Walk(path, func(fp string, fi os.FileInfo, err error) error { // If there are errors, ignore this particular file @@ -132,6 +126,12 @@ func (f *SimpleFileStore) list(path string) []string { if fi.IsDir() { return nil } + + // If this is a symlink, and symlinks is true, ignore it + if !symlinks && fi.Mode()&os.ModeSymlink == os.ModeSymlink { + return nil + } + // Only allow matches that end with our certificate extension (e.g. *.crt) matched, _ := filepath.Match("*"+f.fileExt, fi.Name()) diff --git a/trustmanager/filestore_test.go b/trustmanager/filestore_test.go index 8b08686343..392e8835b4 100644 --- a/trustmanager/filestore_test.go +++ b/trustmanager/filestore_test.go @@ -129,7 +129,7 @@ func TestRemoveDir(t *testing.T) { } } -func TestListAll(t *testing.T) { +func TestListFiles(t *testing.T) { testName := "docker.com/notary/certificate" testExt := "crt" perms := os.FileMode(0755) @@ -144,11 +144,18 @@ func TestListAll(t *testing.T) { // Create 10 randomfiles for i := 1; i <= 10; i++ { // Since we're generating this manually we need to add the extension '.' - expectedFilePath = filepath.Join(tempBaseDir, testName+string(i)+"."+testExt) + expectedFilename := testName + strconv.Itoa(i) + "." + testExt + expectedFilePath = filepath.Join(tempBaseDir, expectedFilename) _, err = generateRandomFile(expectedFilePath, perms) if err != nil { t.Fatalf("failed to generate random file: %v", err) } + + // Create symlinks for all the files + err = os.Symlink(expectedFilename, filepath.Join(tempBaseDir, expectedFilename+".link."+testExt)) + if err != nil { + t.Fatalf("failed to create symlink: %v", err) + } } // Create our SimpleFileStore @@ -158,11 +165,17 @@ func TestListAll(t *testing.T) { perms: perms, } - // Call the List function - files := store.ListAll() + // Call the List function. Expect 10 real files when not listing symlinks + files := store.ListFiles(false) if len(files) != 10 { t.Fatalf("expected 10 files in listing, got: %d", len(files)) } + + // Call the List function. Expect 20 total files when listing symlinks + files = store.ListFiles(true) + if len(files) != 20 { + t.Fatalf("expected 20 files in listing, got: %d", len(files)) + } } func TestListDir(t *testing.T) { @@ -196,15 +209,15 @@ func TestListDir(t *testing.T) { } // Call the ListDir function - files := store.ListDir("docker.com/") + files := store.ListDir("docker.com/", true) if len(files) != 10 { t.Fatalf("expected 10 files in listing, got: %d", len(files)) } - files = store.ListDir("docker.com/notary") + files = store.ListDir("docker.com/notary", true) if len(files) != 10 { t.Fatalf("expected 10 files in listing, got: %d", len(files)) } - files = store.ListDir("fakedocker.com/") + files = store.ListDir("fakedocker.com/", true) if len(files) != 0 { t.Fatalf("expected 0 files in listing, got: %d", len(files)) } diff --git a/trustmanager/keyfilestore.go b/trustmanager/keyfilestore.go index beaa7fbef9..c734f035bb 100644 --- a/trustmanager/keyfilestore.go +++ b/trustmanager/keyfilestore.go @@ -14,7 +14,7 @@ type KeyFileStore struct { // NewKeyFileStore returns a new KeyFileStore creating a private directory to // hold the keys. func NewKeyFileStore(baseDir string) (*KeyFileStore, error) { - fileStore, err := NewFileStore(baseDir, keyExtension) + fileStore, err := NewPrivateSimpleFileStore(baseDir, keyExtension) if err != nil { return nil, err } @@ -74,3 +74,10 @@ func (s *KeyFileStore) GetDecryptedKey(name string, passphrase string) (*data.Pr return privKey, nil } + +// ListKeys returns a list of unique PublicKeys present on the KeyFileStore. +// There might be symlinks associating Certificate IDs to Public Keys, so this +// method only returns the IDs that aren't symlinks +func (s *KeyFileStore) ListKeys() []string { + return s.ListFiles(false) +} diff --git a/trustmanager/x509filestore.go b/trustmanager/x509filestore.go index 8c476d7d29..ea2b7b0f14 100644 --- a/trustmanager/x509filestore.go +++ b/trustmanager/x509filestore.go @@ -3,9 +3,10 @@ package trustmanager import ( "crypto/x509" "errors" - "github.com/Sirupsen/logrus" "os" "path" + + "github.com/Sirupsen/logrus" ) // X509FileStore implements X509Store that persists on disk @@ -30,7 +31,7 @@ func NewX509FilteredFileStore(directory string, validate func(*x509.Certificate) } func newX509FileStore(directory string, validate func(*x509.Certificate) bool) (*X509FileStore, error) { - fileStore, err := NewFileStore(directory, certExtension) + fileStore, err := NewSimpleFileStore(directory, certExtension) if err != nil { return nil, err } diff --git a/trustmanager/x509utils.go b/trustmanager/x509utils.go index 1994d2de50..fb408019ae 100644 --- a/trustmanager/x509utils.go +++ b/trustmanager/x509utils.go @@ -133,7 +133,7 @@ func fingerprintCert(cert *x509.Certificate) CertID { // loadCertsFromDir receives a store AddCertFromFile for each certificate found func loadCertsFromDir(s *X509FileStore) { - certFiles := s.fileStore.ListAll() + certFiles := s.fileStore.ListFiles(true) for _, c := range certFiles { s.AddCertFromFile(c) }