mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-04 04:28:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package ssh
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"golang.org/x/crypto/ssh"
 | 
						|
 | 
						|
	"github.com/hashicorp/vault/sdk/logical"
 | 
						|
	"github.com/hashicorp/vault/sdk/framework"
 | 
						|
)
 | 
						|
 | 
						|
type sshHostKey struct {
 | 
						|
	Key string `json:"key"`
 | 
						|
}
 | 
						|
 | 
						|
func pathKeys(b *backend) *framework.Path {
 | 
						|
	return &framework.Path{
 | 
						|
		Pattern: "keys/" + framework.GenericNameRegex("key_name"),
 | 
						|
		Fields: map[string]*framework.FieldSchema{
 | 
						|
			"key_name": &framework.FieldSchema{
 | 
						|
				Type:        framework.TypeString,
 | 
						|
				Description: "[Required] Name of the key",
 | 
						|
			},
 | 
						|
			"key": &framework.FieldSchema{
 | 
						|
				Type:        framework.TypeString,
 | 
						|
				Description: "[Required] SSH private key with super user privileges in host",
 | 
						|
			},
 | 
						|
		},
 | 
						|
		Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
						|
			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
 | 
						|
	}
 | 
						|
 | 
						|
	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
 | 
						|
	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
 | 
						|
	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
 | 
						|
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/".
 | 
						|
`
 |