diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000..c5a1abbe51 Binary files /dev/null and b/.DS_Store differ diff --git a/cmd/notary/cert.go b/cmd/notary/cert.go index 9ed6937724..e941dd4249 100644 --- a/cmd/notary/cert.go +++ b/cmd/notary/cert.go @@ -53,9 +53,9 @@ func certRemove(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify the cert ID or the GUN of the certificates to remove") } - parseConfig() + trustDir := mainViper.GetString("trustDir") keysPath := filepath.Join(trustDir, notary.PrivDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { @@ -122,9 +122,9 @@ func certList(cmd *cobra.Command, args []string) { cmd.Usage() os.Exit(1) } - parseConfig() + trustDir := mainViper.GetString("trustDir") keysPath := filepath.Join(trustDir, notary.PrivDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { diff --git a/cmd/notary/integration_test.go b/cmd/notary/integration_test.go index 0cf30fee4b..f2c0c09e27 100644 --- a/cmd/notary/integration_test.go +++ b/cmd/notary/integration_test.go @@ -510,6 +510,27 @@ func TestClientCertInteraction(t *testing.T) { assertNumCerts(t, tempDir, 0) } +// Tests default root key generation +func TestDefaultRootKeyGeneration(t *testing.T) { + // -- setup -- + cleanup := setUp(t) + defer cleanup() + + tempDir, err := ioutil.TempDir("/tmp", "repo") + assert.NoError(t, err) + defer os.RemoveAll(tempDir) + + // -- tests -- + + // starts out with no keys + assertNumKeys(t, tempDir, 0, 0, true) + + // generate root key with no algorithm produces a single ECDSA root key and no other keys + _, err = runCommand(t, tempDir, "key", "generate") + assert.NoError(t, err) + assertNumKeys(t, tempDir, 1, 0, true) +} + func TestMain(m *testing.M) { if testing.Short() { // skip diff --git a/cmd/notary/keys.go b/cmd/notary/keys.go index 985d33e427..b8e179c180 100644 --- a/cmd/notary/keys.go +++ b/cmd/notary/keys.go @@ -97,7 +97,7 @@ func keysList(cmd *cobra.Command, args []string) { parseConfig() - stores := getKeyStores(cmd, trustDir, retriever, true) + stores := getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true) keys := make(map[trustmanager.KeyStore]map[string]string) for _, store := range stores { @@ -137,15 +137,19 @@ func keysList(cmd *cobra.Command, args []string) { } func keysGenerateRootKey(cmd *cobra.Command, args []string) { - if len(args) < 1 { - cmd.Usage() - fatalf("Must specify an Algorithm (RSA, ECDSA)") + parseConfig() + + // If no param is given to generate, generates an ecdsa key by default + algorithm := data.ECDSAKey + + // If we were provided an argument lets attempt to use it as an algorithm + if len(args) > 0 { + algorithm = args[0] } - algorithm := args[0] allowedCiphers := map[string]bool{ - "rsa": true, - "ecdsa": true, + data.ECDSAKey: true, + data.RSAKey: true, } if !allowedCiphers[strings.ToLower(algorithm)] { @@ -156,7 +160,7 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) { cs := cryptoservice.NewCryptoService( "", - getKeyStores(cmd, trustDir, retriever, true)..., + getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true)..., ) pubKey, err := cs.Create(data.CanonicalRootRole, algorithm) @@ -174,13 +178,12 @@ func keysExport(cmd *cobra.Command, args []string) { fatalf("Must specify output filename for export") } - exportFilename := args[0] - parseConfig() + exportFilename := args[0] cs := cryptoservice.NewCryptoService( "", - getKeyStores(cmd, trustDir, retriever, true)..., + getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true)..., ) exportFile, err := os.Create(exportFilename) @@ -212,6 +215,8 @@ func keysExportRoot(cmd *cobra.Command, args []string) { fatalf("Must specify key ID and output filename for export") } + parseConfig() + keyID := args[0] exportFilename := args[1] @@ -223,7 +228,7 @@ func keysExportRoot(cmd *cobra.Command, args []string) { cs := cryptoservice.NewCryptoService( "", - getKeyStores(cmd, trustDir, retriever, true)..., + getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true)..., ) exportFile, err := os.Create(exportFilename) @@ -258,7 +263,7 @@ func keysImport(cmd *cobra.Command, args []string) { cs := cryptoservice.NewCryptoService( "", - getKeyStores(cmd, trustDir, retriever, true)..., + getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true)..., ) zipReader, err := zip.OpenReader(importFilename) @@ -281,15 +286,15 @@ func keysImportRoot(cmd *cobra.Command, args []string) { fatalf("Must specify input filename for import") } - importFilename := args[0] - parseConfig() cs := cryptoservice.NewCryptoService( "", - getKeyStores(cmd, trustDir, retriever, true)..., + getKeyStores(cmd, mainViper.GetString("trustDir"), retriever, true)..., ) + importFilename := args[0] + importFile, err := os.Open(importFilename) if err != nil { fatalf("Opening file for import: %v", err) @@ -317,7 +322,7 @@ func keysRotate(cmd *cobra.Command, args []string) { parseConfig() gun := args[0] - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, nil, retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, remoteTrustServer, nil, retriever) if err != nil { fatalf(err.Error()) } diff --git a/cmd/notary/main.go b/cmd/notary/main.go index 78791f80b0..c01fb0cae5 100644 --- a/cmd/notary/main.go +++ b/cmd/notary/main.go @@ -43,21 +43,17 @@ func parseConfig() { logrus.SetOutput(os.Stderr) } - if trustDir == "" { - // Get home directory for current user - homeDir, err := homedir.Dir() - if err != nil { - fatalf("Cannot get current user home directory: %v", err) - } - if homeDir == "" { - fatalf("Cannot get current user home directory") - } - trustDir = filepath.Join(homeDir, filepath.Dir(configDir)) - - logrus.Debugf("no trust directory provided, using default: %s", trustDir) - } else { - logrus.Debugf("trust directory provided: %s", trustDir) + // Get home directory for current user + homeDir, err := homedir.Dir() + if err != nil { + fatalf("Cannot get current user home directory: %v", err) } + if homeDir == "" { + fatalf("Cannot get current user home directory") + } + + // By default our trust directory (where keys are stored) is in ~/.notary/ + mainViper.SetDefault("trustDir", filepath.Join(homeDir, filepath.Dir(configDir))) // If there was a commandline configFile set, we parse that. // If there wasn't we attempt to find it on the default location ~/.notary/config @@ -66,7 +62,7 @@ func parseConfig() { configFileName = strings.TrimSuffix(filepath.Base(configFile), filepath.Ext(configFile)) configPath = filepath.Dir(configFile) } else { - configPath = trustDir + configPath = filepath.Join(homeDir, filepath.Dir(configDir)) } // Setup the configuration details into viper @@ -75,7 +71,7 @@ func parseConfig() { mainViper.AddConfigPath(configPath) // Find and read the config file - err := mainViper.ReadInConfig() + err = mainViper.ReadInConfig() if err != nil { logrus.Debugf("configuration file not found, using defaults") // Ignore if the configuration file doesn't exist, we can use the defaults @@ -83,6 +79,20 @@ func parseConfig() { fatalf("Fatal error config file: %v", err) } } + + // At this point we either have the default value or the one set by the config. + // Either way, the command-line flag has precedence and overwrives the value + if trustDir != "" { + mainViper.Set("trustDir", trustDir) + } + + // Expands all the possible ~/ that have been given, either through -d or config + // If there is no error, user it, if not, attempt to use whatever the user gave us + expandedTrustDir, err := homedir.Expand(mainViper.GetString("trustDir")) + if err == nil { + mainViper.Set("trustDir", expandedTrustDir) + } + logrus.Debugf("using the following trust directory: %s", mainViper.GetString("trustDir")) } func setupCommand(notaryCmd *cobra.Command) { @@ -97,7 +107,7 @@ func setupCommand(notaryCmd *cobra.Command) { notaryCmd.AddCommand(versionCmd) - notaryCmd.PersistentFlags().StringVarP(&trustDir, "trustdir", "d", "", "Directory where the trust data is persisted to") + notaryCmd.PersistentFlags().StringVarP(&trustDir, "trustDir", "d", "", "Directory where the trust data is persisted to") notaryCmd.PersistentFlags().StringVarP(&configFile, "configFile", "c", "", "Path to the configuration file to use") notaryCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output") notaryCmd.PersistentFlags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location") diff --git a/cmd/notary/tuf.go b/cmd/notary/tuf.go index 16b6ef57d7..299bb18f77 100644 --- a/cmd/notary/tuf.go +++ b/cmd/notary/tuf.go @@ -86,15 +86,15 @@ func tufAdd(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify a GUN, target, and path to target data") } + parseConfig() gun := args[0] targetName := args[1] targetPath := args[2] - parseConfig() // no online operations are performed by add so the transport argument // should be nil - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), nil, retriever) if err != nil { fatalf(err.Error()) } @@ -118,10 +118,10 @@ func tufInit(cmd *cobra.Command, args []string) { fatalf("Must specify a GUN") } - gun := args[0] parseConfig() + gun := args[0] - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, false), retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), getTransport(gun, false), retriever) if err != nil { fatalf(err.Error()) } @@ -154,10 +154,10 @@ func tufList(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify a GUN") } - gun := args[0] parseConfig() + gun := args[0] - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), getTransport(gun, true), retriever) if err != nil { fatalf(err.Error()) } @@ -179,11 +179,12 @@ func tufLookup(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify a GUN and target") } - gun := args[0] - targetName := args[1] parseConfig() - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever) + gun := args[0] + targetName := args[1] + + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), getTransport(gun, true), retriever) if err != nil { fatalf(err.Error()) } @@ -202,10 +203,10 @@ func tufStatus(cmd *cobra.Command, args []string) { fatalf("Must specify a GUN") } - gun := args[0] parseConfig() + gun := args[0] - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), nil, retriever) if err != nil { fatalf(err.Error()) } @@ -234,12 +235,12 @@ func tufPublish(cmd *cobra.Command, args []string) { fatalf("Must specify a GUN") } - gun := args[0] parseConfig() + gun := args[0] cmd.Println("Pushing changes to", gun) - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, false), retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), getTransport(gun, false), retriever) if err != nil { fatalf(err.Error()) } @@ -255,13 +256,14 @@ func tufRemove(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify a GUN and target") } + parseConfig() + gun := args[0] targetName := args[1] - parseConfig() // no online operation are performed by remove so the transport argument // should be nil. - repo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever) + repo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), nil, retriever) if err != nil { fatalf(err.Error()) } @@ -278,6 +280,7 @@ func verify(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("Must specify a GUN and target") } + parseConfig() // Reads all of the data on STDIN @@ -288,7 +291,7 @@ func verify(cmd *cobra.Command, args []string) { gun := args[0] targetName := args[1] - nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever) + nRepo, err := notaryclient.NewNotaryRepository(mainViper.GetString("trustDir"), gun, getRemoteTrustServer(), getTransport(gun, true), retriever) if err != nil { fatalf(err.Error()) }