Added ssh key import feature in "key import"

This commit is contained in:
Julien Dessaux 2018-03-11 18:16:18 +01:00 committed by Julien Dessaux
parent 6f2b58cbdc
commit b0afdf933a
3 changed files with 92 additions and 0 deletions

View file

@ -194,6 +194,7 @@ hostgroup rm [-h] HOSTGROUP...
# key management
key help
key create [-h] [--name=<value>] [--type=<value>] [--length=<value>] [--comment=<value>]
key import [-h] [--name=<value>] [--comment=<value>]
key inspect [-h] [--decrypt] KEY...
key ls [-h] [--latest] [--quiet]
key rm [-h] KEY...

View file

@ -9,6 +9,7 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"io"
"strings"
@ -52,6 +53,42 @@ func NewSSHKey(keyType string, length uint) (*SSHKey, error) {
return &key, nil
}
func ImportSSHKey(keyValue string) (*SSHKey, error) {
key := SSHKey{
Type: "rsa",
}
parsedKey, err := gossh.ParseRawPrivateKey([]byte(keyValue))
if err != nil {
return nil, err
}
var privateKey *rsa.PrivateKey
var ok bool
if privateKey, ok = parsedKey.(*rsa.PrivateKey); !ok {
return nil, errors.New("key type not supported")
}
key.Length = uint(privateKey.PublicKey.N.BitLen())
// convert priv key to x509 format
var pemKey = &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
}
buf := bytes.NewBufferString("")
if err = pem.Encode(buf, pemKey); err != nil {
return nil, err
}
key.PrivKey = buf.String()
// generte authorized-key formatted pubkey output
pub, err := gossh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return nil, err
}
key.PubKey = strings.TrimSpace(string(gossh.MarshalAuthorizedKey(pub)))
return &key, nil
}
func encrypt(key []byte, text string) (string, error) {
plaintext := []byte(text)
block, err := aes.NewCipher(key)

View file

@ -1182,6 +1182,60 @@ GLOBAL OPTIONS:
return nil
},
}, {
Name: "import",
Usage: "Imports an existing private key",
Description: "$> key import\n $> key import --name=mykey",
Flags: []cli.Flag{
cli.StringFlag{Name: "name", Usage: "Assigns a name to the key"},
cli.StringFlag{Name: "comment", Usage: "Adds a comment"},
},
Action: func(c *cli.Context) error {
if err := myself.CheckRoles([]string{"admin"}); err != nil {
return err
}
var name string
if c.String("name") != "" {
name = c.String("name")
} else {
name = namesgenerator.GetRandomName(0)
}
var value string
term := terminal.NewTerminal(s, "Paste your key and end with a blank line> ")
for {
line, err := term.ReadLine()
if err != nil {
return err
}
if line != "" {
value += line + "\n"
} else {
break
}
}
key, err := ImportSSHKey(value)
if err != nil {
return err
}
key.Name = name
key.Comment = c.String("comment")
if _, err := govalidator.ValidateStruct(key); err != nil {
return err
}
// FIXME: check if name already exists
// save the key in database
if err := db.Create(&key).Error; err != nil {
return err
}
fmt.Fprintf(s, "%d\n", key.ID)
return nil
},
}, {
Name: "inspect",
Usage: "Shows detailed information on one or more keys",
ArgsUsage: "KEY...",