mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Vault SSH: Support OTP key type from CLI
This commit is contained in:
34
api/ssh.go
34
api/ssh.go
@@ -1,9 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
// SSH is used to return a client to invoke operations on SSH backend.
|
||||
type SSH struct {
|
||||
@@ -40,32 +37,3 @@ func (c *SSH) KeyCreate(role string, data map[string]interface{}) (*Secret, erro
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
// Invokes the SSH backend API to list the roles associated with given IP address.
|
||||
func (c *SSH) Lookup(data map[string]interface{}) (*SSHRoles, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/ssh/lookup")
|
||||
if err := r.SetJSONBody(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var roles SSHRoles
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
if err := dec.Decode(&roles); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &roles, nil
|
||||
}
|
||||
|
||||
// Structures for the requests/resposne are all down here. They aren't
|
||||
// individually documentd because the map almost directly to the raw HTTP API
|
||||
// documentation. Please refer to that documentation for more details.
|
||||
|
||||
type SSHRoles struct {
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
@@ -95,7 +95,8 @@ func (b *backend) pathRoleCreateWrite(
|
||||
return nil, err
|
||||
}
|
||||
result = b.Secret(SecretOTPType).Response(map[string]interface{}{
|
||||
"otp": otp,
|
||||
"key_type": role.KeyType,
|
||||
"key": otp,
|
||||
}, map[string]interface{}{
|
||||
"otp": otp,
|
||||
})
|
||||
@@ -134,9 +135,9 @@ func (b *backend) pathRoleCreateWrite(
|
||||
return nil, fmt.Errorf("error creating OTP:'%s'", err)
|
||||
}
|
||||
result = b.Secret(SecretDynamicKeyType).Response(map[string]interface{}{
|
||||
"key": dynamicPrivateKey,
|
||||
"key": dynamicPrivateKey,
|
||||
"key_type": role.KeyType,
|
||||
}, map[string]interface{}{
|
||||
"key_type": role.KeyType,
|
||||
"username": username,
|
||||
"ip": ip,
|
||||
"host_key_name": role.KeyName,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/builtin/logical/ssh"
|
||||
)
|
||||
|
||||
// SSHCommand is a Command that establishes a SSH connection with target by generating a dynamic key
|
||||
@@ -19,6 +20,8 @@ type SSHCommand struct {
|
||||
func (c *SSHCommand) Run(args []string) int {
|
||||
var role string
|
||||
var port string
|
||||
var sshCmdArgs []string
|
||||
var sshDynamicKeyFileName string
|
||||
flags := c.Meta.FlagSet("ssh", FlagSetDefault)
|
||||
flags.StringVar(&role, "role", "", "")
|
||||
flags.StringVar(&port, "port", "22", "")
|
||||
@@ -64,15 +67,22 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
return 2
|
||||
}
|
||||
|
||||
sshDynamicKey := string(keySecret.Data["key"].(string))
|
||||
if len(sshDynamicKey) == 0 {
|
||||
c.Ui.Error(fmt.Sprintf("Invalid key"))
|
||||
return 2
|
||||
}
|
||||
sshDynamicKeyFileName := fmt.Sprintf("vault_temp_file_%s_%s", username, ip.String())
|
||||
err = ioutil.WriteFile(sshDynamicKeyFileName, []byte(sshDynamicKey), 0600)
|
||||
if keySecret.Data["key_type"].(string) == ssh.KeyTypeDynamic {
|
||||
sshDynamicKey := string(keySecret.Data["key"].(string))
|
||||
if len(sshDynamicKey) == 0 {
|
||||
c.Ui.Error(fmt.Sprintf("Invalid key"))
|
||||
return 2
|
||||
}
|
||||
sshDynamicKeyFileName = fmt.Sprintf("vault_temp_file_%s_%s", username, ip.String())
|
||||
err = ioutil.WriteFile(sshDynamicKeyFileName, []byte(sshDynamicKey), 0600)
|
||||
sshCmdArgs = append(sshCmdArgs, []string{"-i", sshDynamicKeyFileName}...)
|
||||
|
||||
sshCmdArgs := []string{"-p", port, "-i", sshDynamicKeyFileName}
|
||||
} else if keySecret.Data["key_type"].(string) == ssh.KeyTypeOTP {
|
||||
fmt.Printf("OTP for the session is %s\n", string(keySecret.Data["key"].(string)))
|
||||
} else {
|
||||
c.Ui.Error("Key not present")
|
||||
}
|
||||
sshCmdArgs = append(sshCmdArgs, []string{"-p", port}...)
|
||||
sshCmdArgs = append(sshCmdArgs, args...)
|
||||
|
||||
sshCmd := exec.Command("ssh", sshCmdArgs...)
|
||||
@@ -84,9 +94,11 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
c.Ui.Error(fmt.Sprintf("Error while running ssh command:%s", err))
|
||||
}
|
||||
|
||||
err = os.Remove(sshDynamicKeyFileName)
|
||||
if err != nil {
|
||||
c.Ui.Error("Error cleaning up") // Intentionally not mentioning the exact error
|
||||
if keySecret.Data["key_type"].(string) == ssh.KeyTypeDynamic {
|
||||
err = os.Remove(sshDynamicKeyFileName)
|
||||
if err != nil {
|
||||
c.Ui.Error("Error cleaning up") // Intentionally not mentioning the exact error
|
||||
}
|
||||
}
|
||||
|
||||
err = client.SSH().KeyRevoke(keySecret.LeaseID)
|
||||
|
||||
Reference in New Issue
Block a user