mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 02:57:59 +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
|
package api
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SSH is used to return a client to invoke operations on SSH backend.
|
// SSH is used to return a client to invoke operations on SSH backend.
|
||||||
type SSH struct {
|
type SSH struct {
|
||||||
@@ -40,32 +37,3 @@ func (c *SSH) KeyCreate(role string, data map[string]interface{}) (*Secret, erro
|
|||||||
|
|
||||||
return ParseSecret(resp.Body)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
result = b.Secret(SecretOTPType).Response(map[string]interface{}{
|
result = b.Secret(SecretOTPType).Response(map[string]interface{}{
|
||||||
"otp": otp,
|
"key_type": role.KeyType,
|
||||||
|
"key": otp,
|
||||||
}, map[string]interface{}{
|
}, map[string]interface{}{
|
||||||
"otp": otp,
|
"otp": otp,
|
||||||
})
|
})
|
||||||
@@ -135,8 +136,8 @@ func (b *backend) pathRoleCreateWrite(
|
|||||||
}
|
}
|
||||||
result = b.Secret(SecretDynamicKeyType).Response(map[string]interface{}{
|
result = b.Secret(SecretDynamicKeyType).Response(map[string]interface{}{
|
||||||
"key": dynamicPrivateKey,
|
"key": dynamicPrivateKey,
|
||||||
}, map[string]interface{}{
|
|
||||||
"key_type": role.KeyType,
|
"key_type": role.KeyType,
|
||||||
|
}, map[string]interface{}{
|
||||||
"username": username,
|
"username": username,
|
||||||
"ip": ip,
|
"ip": ip,
|
||||||
"host_key_name": role.KeyName,
|
"host_key_name": role.KeyName,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
"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
|
// 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 {
|
func (c *SSHCommand) Run(args []string) int {
|
||||||
var role string
|
var role string
|
||||||
var port string
|
var port string
|
||||||
|
var sshCmdArgs []string
|
||||||
|
var sshDynamicKeyFileName string
|
||||||
flags := c.Meta.FlagSet("ssh", FlagSetDefault)
|
flags := c.Meta.FlagSet("ssh", FlagSetDefault)
|
||||||
flags.StringVar(&role, "role", "", "")
|
flags.StringVar(&role, "role", "", "")
|
||||||
flags.StringVar(&port, "port", "22", "")
|
flags.StringVar(&port, "port", "22", "")
|
||||||
@@ -64,15 +67,22 @@ func (c *SSHCommand) Run(args []string) int {
|
|||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if keySecret.Data["key_type"].(string) == ssh.KeyTypeDynamic {
|
||||||
sshDynamicKey := string(keySecret.Data["key"].(string))
|
sshDynamicKey := string(keySecret.Data["key"].(string))
|
||||||
if len(sshDynamicKey) == 0 {
|
if len(sshDynamicKey) == 0 {
|
||||||
c.Ui.Error(fmt.Sprintf("Invalid key"))
|
c.Ui.Error(fmt.Sprintf("Invalid key"))
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
sshDynamicKeyFileName := fmt.Sprintf("vault_temp_file_%s_%s", username, ip.String())
|
sshDynamicKeyFileName = fmt.Sprintf("vault_temp_file_%s_%s", username, ip.String())
|
||||||
err = ioutil.WriteFile(sshDynamicKeyFileName, []byte(sshDynamicKey), 0600)
|
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...)
|
sshCmdArgs = append(sshCmdArgs, args...)
|
||||||
|
|
||||||
sshCmd := exec.Command("ssh", sshCmdArgs...)
|
sshCmd := exec.Command("ssh", sshCmdArgs...)
|
||||||
@@ -84,10 +94,12 @@ func (c *SSHCommand) Run(args []string) int {
|
|||||||
c.Ui.Error(fmt.Sprintf("Error while running ssh command:%s", err))
|
c.Ui.Error(fmt.Sprintf("Error while running ssh command:%s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if keySecret.Data["key_type"].(string) == ssh.KeyTypeDynamic {
|
||||||
err = os.Remove(sshDynamicKeyFileName)
|
err = os.Remove(sshDynamicKeyFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error("Error cleaning up") // Intentionally not mentioning the exact error
|
c.Ui.Error("Error cleaning up") // Intentionally not mentioning the exact error
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = client.SSH().KeyRevoke(keySecret.LeaseID)
|
err = client.SSH().KeyRevoke(keySecret.LeaseID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user