diff --git a/client/config.go b/client/config.go index 1cc9401fc6a2a340e5d5d77979b5926e0e9f2f8e..e901b7296ad49ffa71d86496685331f8f714e65f 100644 --- a/client/config.go +++ b/client/config.go @@ -3,6 +3,8 @@ package client import ( "github.com/spf13/pflag" "github.com/spf13/viper" + "os/user" + "regexp" ) // Config holds the client configuration. @@ -12,6 +14,8 @@ type Config struct { Keysize int `mapstructure:"key_size"` Validity string `mapstructure:"validity"` ValidateTLSCertificate bool `mapstructure:"validate_tls_certificate"` + PublicKey string `mapstructure:"public_key"` + PublicCert string `mapstructure:"public_cert"` } func setDefaults() { @@ -19,9 +23,25 @@ func setDefaults() { viper.BindPFlag("key_type", pflag.Lookup("key_type")) viper.BindPFlag("key_size", pflag.Lookup("key_size")) viper.BindPFlag("validity", pflag.Lookup("validity")) + viper.BindPFlag("public_key", pflag.Lookup("public_key")) + viper.BindPFlag("public_cert", pflag.Lookup("public_cert")) viper.SetDefault("validateTLSCertificate", true) } +func ExpandTilde(path string) string { + re := regexp.MustCompile("^~([^/]*)(/.*)") + if m := re.FindStringSubmatch(path); len(m) > 0 { + u, _ := user.Current() + if m[1] != "" { + u, _ = user.Lookup(m[1]) + } + if u != nil { + return u.HomeDir + m[2] + } + } + return path +} + // ReadConfig reads the client configuration from a file into a Config struct. func ReadConfig(path string) (*Config, error) { setDefaults() diff --git a/cmd/cashier/main.go b/cmd/cashier/main.go index 26c6cbf4e63d905a8357e8fa656c9d20fe941bc7..69c63be0850ed84f17d8373123f6aa87ab8d474b 100644 --- a/cmd/cashier/main.go +++ b/cmd/cashier/main.go @@ -1,7 +1,9 @@ package main import ( + "encoding/base64" "fmt" + "io/ioutil" "log" "net" "os" @@ -12,16 +14,19 @@ import ( "github.com/nsheridan/cashier/client" "github.com/pkg/browser" "github.com/spf13/pflag" + "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) var ( - u, _ = user.Current() - cfg = pflag.String("config", path.Join(u.HomeDir, ".cashier.conf"), "Path to config file") - ca = pflag.String("ca", "http://localhost:10000", "CA server") - keysize = pflag.Int("key_size", 2048, "Key size. Ignored for ed25519 keys") - validity = pflag.Duration("validity", time.Hour*24, "Key validity") - keytype = pflag.String("key_type", "rsa", "Type of private key to generate - rsa, ecdsa or ed25519") + u, _ = user.Current() + cfg = pflag.String("config", path.Join(u.HomeDir, ".cashier.conf"), "Path to config file") + ca = pflag.String("ca", "http://localhost:10000", "CA server") + keysize = pflag.Int("key_size", 2048, "Key size. Ignored for ed25519 keys") + validity = pflag.Duration("validity", time.Hour*24, "Key validity") + keytype = pflag.String("key_type", "rsa", "Type of private key to generate - rsa, ecdsa or ed25519") + public_key = pflag.String("public_key", "", "Filename for public key") + public_cert = pflag.String("public_cert", "", "Filename for public cert") ) func main() { @@ -58,5 +63,9 @@ func main() { if err := client.InstallCert(a, cert, priv); err != nil { log.Fatalln(err) } + ioutil.WriteFile(client.ExpandTilde(c.PublicKey), + ssh.MarshalAuthorizedKey(pub), 0644) + ioutil.WriteFile(client.ExpandTilde(c.PublicCert), + []byte(cert.Type()+" "+base64.StdEncoding.EncodeToString(cert.Marshal())), 0644) fmt.Println("Credentials added.") }