open-vault/builtin/logical/ssh/path_keys.go
2015-08-03 16:18:14 -04:00

115 lines
2.9 KiB
Go

package ssh
import (
"fmt"
"golang.org/x/crypto/ssh"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
type sshHostKey struct {
Key string `json:"key"`
}
func pathKeys(b *backend) *framework.Path {
return &framework.Path{
Pattern: "keys/(?P<name>[-\\w]+)",
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "name of the key",
},
"key": &framework.FieldSchema{
Type: framework.TypeString,
Description: "SSH private key for host.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathKeysRead,
logical.WriteOperation: b.pathKeysWrite,
logical.DeleteOperation: b.pathKeysDelete,
},
HelpSynopsis: pathKeysSyn,
HelpDescription: pathKeysDesc,
}
}
func (b *backend) pathKeysRead(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
keyName := d.Get("name").(string)
keyPath := fmt.Sprintf("keys/%s", keyName)
entry, err := req.Storage.Get(keyPath)
if err != nil {
return nil, err
}
if entry == nil {
return nil, nil
}
var result sshHostKey
if err := entry.DecodeJSON(&result); err != nil {
return nil, err
}
return &logical.Response{
Data: map[string]interface{}{
"key": result.Key,
},
}, nil
}
func (b *backend) pathKeysDelete(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
keyName := d.Get("name").(string)
keyPath := fmt.Sprintf("keys/%s", keyName)
err := req.Storage.Delete(keyPath)
if err != nil {
return nil, err
}
return nil, nil
}
func (b *backend) pathKeysWrite(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
keyName := d.Get("name").(string)
keyString := d.Get("key").(string)
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)
entry, err := logical.StorageEntryJSON(keyPath, map[string]interface{}{
"key": keyString,
})
if err != nil {
return nil, err
}
if err := req.Storage.Put(entry); err != nil {
return nil, err
}
return nil, nil
}
const pathKeysSyn = `
Register a shared key which can be used to install dynamic key
in remote machine.
`
const pathKeysDesc = `
The shared key registered will be used to install and uninstall
long lived dynamic keys in remote machine. This key should have
"root" privileges at target machine. This enables installing keys
for unprivileged usernames.
If this backend is mounted as "ssh", then the endpoint for registering
shared key is "ssh/keys/webrack", if "webrack" is the user coined
name for the key. The name given here can be associated with any
number of roles via the endpoint "ssh/roles/".
`