open-vault/builtin/logical/ssh/path_keys.go

111 lines
2.8 KiB
Go
Raw Normal View History

package ssh
import (
"context"
"fmt"
2015-07-29 18:21:36 +00:00
"golang.org/x/crypto/ssh"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
2015-07-29 18:21:36 +00:00
type sshHostKey struct {
2015-08-03 20:18:14 +00:00
Key string `json:"key"`
2015-07-29 18:21:36 +00:00
}
func pathKeys(b *backend) *framework.Path {
return &framework.Path{
Pattern: "keys/" + framework.GenericNameRegex("key_name"),
Fields: map[string]*framework.FieldSchema{
"key_name": {
Type: framework.TypeString,
Description: "[Required] Name of the key",
},
"key": {
Type: framework.TypeString,
Description: "[Required] SSH private key with super user privileges in host",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
2016-08-19 20:48:32 +00:00
logical.UpdateOperation: b.pathKeysWrite,
logical.DeleteOperation: b.pathKeysDelete,
},
HelpSynopsis: pathKeysSyn,
HelpDescription: pathKeysDesc,
}
}
func (b *backend) getKey(ctx context.Context, s logical.Storage, n string) (*sshHostKey, error) {
entry, err := s.Get(ctx, "keys/"+n)
if err != nil {
return nil, err
}
if entry == nil {
return nil, nil
}
2015-08-03 20:18:14 +00:00
var result sshHostKey
if err := entry.DecodeJSON(&result); err != nil {
return nil, err
}
return &result, nil
}
func (b *backend) pathKeysDelete(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
keyName := d.Get("key_name").(string)
keyPath := fmt.Sprintf("keys/%s", keyName)
err := req.Storage.Delete(ctx, keyPath)
if err != nil {
return nil, err
}
return nil, nil
}
func (b *backend) pathKeysWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
keyName := d.Get("key_name").(string)
if keyName == "" {
return logical.ErrorResponse("Missing key_name"), nil
}
keyString := d.Get("key").(string)
// Check if the key provided is infact a private key
2015-07-29 18:21:36 +00:00
signer, err := ssh.ParsePrivateKey([]byte(keyString))
if err != nil || signer == nil {
return logical.ErrorResponse("Invalid key"), nil
}
if keyString == "" {
return logical.ErrorResponse("Missing key"), nil
}
keyPath := fmt.Sprintf("keys/%s", keyName)
// Store the key
2015-08-03 20:18:14 +00:00
entry, err := logical.StorageEntryJSON(keyPath, map[string]interface{}{
"key": keyString,
})
if err != nil {
return nil, err
}
if err := req.Storage.Put(ctx, entry); err != nil {
return nil, err
}
return nil, nil
}
const pathKeysSyn = `
Register a shared private key with Vault.
`
const pathKeysDesc = `
Vault uses this key to install and uninstall dynamic keys in remote hosts. This
key should have sudoer privileges in remote hosts. This enables installing keys
2015-07-27 17:02:31 +00:00
for unprivileged usernames.
If this backend is mounted as "ssh", then the endpoint for registering shared
key is "ssh/keys/<name>". The name given here can be associated with any number
of roles via the endpoint "ssh/roles/".
`