mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +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/framework"
 | |
| 	"github.com/hashicorp/vault/sdk/logical"
 | |
| )
 | |
| 
 | |
| 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": {
 | |
| 				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{
 | |
| 			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/".
 | |
| `
 | 
