Adding client-side root-ca server and config

Signed-off-by: Diogo Monica <diogo@docker.com>
This commit is contained in:
Diogo Monica 2015-10-09 21:36:37 -07:00
parent 75893ffed3
commit aeb96f27a2
3 changed files with 83 additions and 38 deletions

7
cmd/notary/config.json Normal file
View File

@ -0,0 +1,7 @@
{
"remote_server": {
"addr": "localhost:4443",
"root_ca": "./fixtures/root-ca.crt"
}
}

View File

@ -7,24 +7,30 @@ import (
"strings" "strings"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/docker/notary/pkg/passphrase" "github.com/docker/notary/pkg/passphrase"
"github.com/docker/notary/version" "github.com/docker/notary/version"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
) )
const configFileName string = "config" const (
const defaultTrustDir string = ".notary/" configDir = ".notary/"
const defaultServerURL = "https://notary-server:4443" defaultServerURL = "https://notary-server:4443"
const idSize = 64 idSize = 64
)
var rawOutput bool var (
var trustDir string rawOutput bool
var remoteTrustServer string verbose bool
var verbose bool trustDir string
var retriever passphrase.Retriever configFile string
remoteTrustServer string
configPath string
configFileName = "config"
configFileExt = "json"
retriever passphrase.Retriever
)
func init() { func init() {
retriever = getPassphraseRetriever() retriever = getPassphraseRetriever()
@ -45,17 +51,27 @@ func parseConfig() {
if homeDir == "" { if homeDir == "" {
fatalf("cannot get current user home directory") fatalf("cannot get current user home directory")
} }
trustDir = filepath.Join(homeDir, filepath.Dir(defaultTrustDir)) trustDir = filepath.Join(homeDir, filepath.Dir(configDir))
logrus.Debugf("no trust directory provided, using default: %s", trustDir) logrus.Debugf("no trust directory provided, using default: %s", trustDir)
} else { } else {
logrus.Debugf("trust directory provided: %s", trustDir) logrus.Debugf("trust directory provided: %s", trustDir)
} }
// Setup the configuration details // 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
if configFile != "" {
configFileExt = strings.TrimPrefix(filepath.Ext(configFile), ".")
configFileName = strings.TrimSuffix(filepath.Base(configFile), filepath.Ext(configFile))
configPath = filepath.Dir(configFile)
} else {
configPath = trustDir
}
// Setup the configuration details into viper
viper.SetConfigName(configFileName) viper.SetConfigName(configFileName)
viper.AddConfigPath(trustDir) viper.SetConfigType(configFileExt)
viper.SetConfigType("json") viper.AddConfigPath(configPath)
// Find and read the config file // Find and read the config file
err := viper.ReadInConfig() err := viper.ReadInConfig()
@ -69,11 +85,6 @@ func parseConfig() {
} }
func main() { func main() {
serverURL := os.Getenv("NOTARY_SERVER_URL")
if serverURL == "" {
serverURL = defaultServerURL
}
var notaryCmd = &cobra.Command{ var notaryCmd = &cobra.Command{
Use: "notary", Use: "notary",
Short: "notary allows the creation of trusted collections.", Short: "notary allows the creation of trusted collections.",
@ -92,25 +103,26 @@ func main() {
notaryCmd.AddCommand(versionCmd) 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().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
notaryCmd.AddCommand(cmdKey) notaryCmd.AddCommand(cmdKey)
notaryCmd.AddCommand(cmdCert) notaryCmd.AddCommand(cmdCert)
notaryCmd.AddCommand(cmdTufInit) notaryCmd.AddCommand(cmdTufInit)
cmdTufInit.Flags().StringVarP(&remoteTrustServer, "server", "s", serverURL, "Remote trust server location") cmdTufInit.Flags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.AddCommand(cmdTufList) notaryCmd.AddCommand(cmdTufList)
cmdTufList.Flags().BoolVarP(&rawOutput, "raw", "", false, "Instructs notary list to output a nonpretty printed version of the targets list. Useful if you need to parse the list.") cmdTufList.Flags().BoolVarP(&rawOutput, "raw", "", false, "Instructs notary list to output a nonpretty printed version of the targets list. Useful if you need to parse the list.")
cmdTufList.Flags().StringVarP(&remoteTrustServer, "server", "s", serverURL, "Remote trust server location") cmdTufList.Flags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.AddCommand(cmdTufAdd) notaryCmd.AddCommand(cmdTufAdd)
notaryCmd.AddCommand(cmdTufRemove) notaryCmd.AddCommand(cmdTufRemove)
notaryCmd.AddCommand(cmdTufStatus) notaryCmd.AddCommand(cmdTufStatus)
notaryCmd.AddCommand(cmdTufPublish) notaryCmd.AddCommand(cmdTufPublish)
cmdTufPublish.Flags().StringVarP(&remoteTrustServer, "server", "s", serverURL, "Remote trust server location") cmdTufPublish.Flags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.AddCommand(cmdTufLookup) notaryCmd.AddCommand(cmdTufLookup)
cmdTufLookup.Flags().BoolVarP(&rawOutput, "raw", "", false, "Instructs notary lookup to output a nonpretty printed version of the targets list. Useful if you need to parse the list.") cmdTufLookup.Flags().BoolVarP(&rawOutput, "raw", "", false, "Instructs notary lookup to output a nonpretty printed version of the targets list. Useful if you need to parse the list.")
cmdTufLookup.Flags().StringVarP(&remoteTrustServer, "server", "s", serverURL, "Remote trust server location") cmdTufLookup.Flags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.AddCommand(cmdVerify) notaryCmd.AddCommand(cmdVerify)
cmdVerify.Flags().StringVarP(&remoteTrustServer, "server", "s", serverURL, "Remote trust server location") cmdVerify.Flags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.Execute() notaryCmd.Execute()
} }

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"crypto/sha256" "crypto/sha256"
"crypto/tls" "crypto/tls"
"crypto/x509"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
@ -20,6 +21,7 @@ import (
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/pkg/term" "github.com/docker/docker/pkg/term"
notaryclient "github.com/docker/notary/client" notaryclient "github.com/docker/notary/client"
"github.com/docker/notary/trustmanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -93,7 +95,7 @@ func tufAdd(cmd *cobra.Command, args []string) {
parseConfig() parseConfig()
// no online operations are performed by add so the transport argument // no online operations are performed by add so the transport argument
// should be nil // should be nil
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, nil, retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -118,7 +120,7 @@ func tufInit(cmd *cobra.Command, args []string) {
gun := args[0] gun := args[0]
parseConfig() parseConfig()
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, getTransport(gun, false), retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, false), retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -160,7 +162,7 @@ func tufList(cmd *cobra.Command, args []string) {
gun := args[0] gun := args[0]
parseConfig() parseConfig()
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, getTransport(gun, true), retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -186,7 +188,7 @@ func tufLookup(cmd *cobra.Command, args []string) {
targetName := args[1] targetName := args[1]
parseConfig() parseConfig()
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, getTransport(gun, true), retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -208,7 +210,7 @@ func tufStatus(cmd *cobra.Command, args []string) {
gun := args[0] gun := args[0]
parseConfig() parseConfig()
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, nil, retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -242,7 +244,7 @@ func tufPublish(cmd *cobra.Command, args []string) {
fmt.Println("Pushing changes to ", gun, ".") fmt.Println("Pushing changes to ", gun, ".")
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, getTransport(gun, false), retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, false), retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -264,7 +266,7 @@ func tufRemove(cmd *cobra.Command, args []string) {
// no online operation are performed by remove so the transport argument // no online operation are performed by remove so the transport argument
// should be nil. // should be nil.
repo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, nil, retriever) repo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), nil, retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -291,7 +293,7 @@ func verify(cmd *cobra.Command, args []string) {
gun := args[0] gun := args[0]
targetName := args[1] targetName := args[1]
nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, remoteTrustServer, getTransport(gun, true), retriever) nRepo, err := notaryclient.NewNotaryRepository(trustDir, gun, getRemoteTrustServer(), getTransport(gun, true), retriever)
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
@ -357,11 +359,23 @@ func (ps passwordStore) Basic(u *url.URL) (string, string) {
} }
func getTransport(gun string, readOnly bool) http.RoundTripper { func getTransport(gun string, readOnly bool) http.RoundTripper {
// Attempt to get a root CA from the config file. Nil is the host defaults.
rootPool := x509.NewCertPool()
rootCAFile := viper.GetString("remote_server.root_ca")
if rootCAFile != "" {
rootCert, err := trustmanager.LoadCertFromFile(viper.GetString("remote_server.root_ca"))
if err != nil {
rootPool = nil
}
rootPool.AddCert(rootCert)
}
// skipTLSVerify is false by default so verification will // skipTLSVerify is false by default so verification will
// be performed. // be performed.
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
InsecureSkipVerify: viper.GetBool("skipTLSVerify"), InsecureSkipVerify: viper.GetBool("remote_server.skipTLSVerify"),
MinVersion: tls.VersionTLS10, MinVersion: tls.VersionTLS10,
RootCAs: rootPool,
} }
base := &http.Transport{ base := &http.Transport{
@ -386,9 +400,9 @@ func tokenAuth(baseTransport *http.Transport, gun string, readOnly bool) http.Ro
Transport: authTransport, Transport: authTransport,
Timeout: 5 * time.Second, Timeout: 5 * time.Second,
} }
endpoint, err := url.Parse(remoteTrustServer) endpoint, err := url.Parse(getRemoteTrustServer())
if err != nil { if err != nil {
fatalf("could not parse remote trust server url (%s): %s", remoteTrustServer, err.Error()) fatalf("could not parse remote trust server url (%s): %s", getRemoteTrustServer(), err.Error())
} }
subPath, err := url.Parse("v2/") subPath, err := url.Parse("v2/")
if err != nil { if err != nil {
@ -416,3 +430,15 @@ func tokenAuth(baseTransport *http.Transport, gun string, readOnly bool) http.Ro
modifier := transport.RequestModifier(auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler)) modifier := transport.RequestModifier(auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler))
return transport.NewTransport(baseTransport, modifier) return transport.NewTransport(baseTransport, modifier)
} }
func getRemoteTrustServer() string {
if remoteTrustServer == "" {
configRemote := viper.GetString("remote_server.addr")
if configRemote != "" {
remoteTrustServer = configRemote
} else {
remoteTrustServer = defaultServerURL
}
}
return remoteTrustServer
}