mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
ssh: Use temporary file to store the identity file
This commit is contained in:
@@ -34,7 +34,6 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
var role, mountPoint, format, userKnownHostsFile, strictHostKeyChecking string
|
||||
var noExec bool
|
||||
var sshCmdArgs []string
|
||||
var sshDynamicKeyFileName string
|
||||
flags := c.Meta.FlagSet("ssh", meta.FlagSetDefault)
|
||||
flags.StringVar(&strictHostKeyChecking, "strict-host-key-checking", "", "")
|
||||
flags.StringVar(&userKnownHostsFile, "user-known-hosts-file", "", "")
|
||||
@@ -76,7 +75,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing client: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -92,7 +91,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
if len(input) == 1 {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error fetching username: %s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error fetching username: %v", err))
|
||||
return 1
|
||||
}
|
||||
username = u.Username
|
||||
@@ -101,7 +100,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
username = input[0]
|
||||
ipAddr = input[1]
|
||||
} else {
|
||||
c.Ui.Error(fmt.Sprintf("Invalid parameter: %s", args[0]))
|
||||
c.Ui.Error(fmt.Sprintf("Invalid parameter: %q", args[0]))
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -109,7 +108,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
// Vault only deals with IP addresses.
|
||||
ip, err := net.ResolveIPAddr("ip", ipAddr)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error resolving IP Address: %s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error resolving IP Address: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -120,14 +119,14 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
if role == "" {
|
||||
role, err = c.defaultRole(mountPoint, ip.String())
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error choosing role: %s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error choosing role: %v", err))
|
||||
return 1
|
||||
}
|
||||
// Print the default role chosen so that user knows the role name
|
||||
// if something doesn't work. If the role chosen is not allowed to
|
||||
// be used by the user (ACL enforcement), then user should see an
|
||||
// error message accordingly.
|
||||
c.Ui.Output(fmt.Sprintf("Vault SSH: Role: %s", role))
|
||||
c.Ui.Output(fmt.Sprintf("Vault SSH: Role: %q", role))
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
@@ -137,7 +136,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
|
||||
keySecret, err := client.SSHWithMountPoint(mountPoint).Credential(role, data)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting key for SSH session:%s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error getting key for SSH session: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -152,7 +151,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
}
|
||||
var resp SSHCredentialResp
|
||||
if err := mapstructure.Decode(keySecret.Data, &resp); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing the credential response:%s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing the credential response: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -161,9 +160,21 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
c.Ui.Error(fmt.Sprintf("Invalid key"))
|
||||
return 1
|
||||
}
|
||||
sshDynamicKeyFileName = fmt.Sprintf("vault_ssh_%s_%s", username, ip.String())
|
||||
err = ioutil.WriteFile(sshDynamicKeyFileName, []byte(resp.Key), 0600)
|
||||
sshCmdArgs = append(sshCmdArgs, []string{"-i", sshDynamicKeyFileName}...)
|
||||
sshDynamicKeyFile, err := ioutil.TempFile("", fmt.Sprintf("vault_ssh_%s_%s_", username, ip.String()))
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating temporary file: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Ensure that we delete the temporary file
|
||||
defer os.Remove(sshDynamicKeyFile.Name())
|
||||
|
||||
if err = ioutil.WriteFile(sshDynamicKeyFile.Name(),
|
||||
[]byte(resp.Key), 0600); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error storing the dynamic key into the temporary file: %v", err))
|
||||
return 1
|
||||
}
|
||||
sshCmdArgs = append(sshCmdArgs, []string{"-i", sshDynamicKeyFile.Name()}...)
|
||||
|
||||
} else if resp.KeyType == ssh.KeyTypeOTP {
|
||||
// Check if the application 'sshpass' is installed in the client machine.
|
||||
@@ -182,7 +193,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
sshCmd.Stdout = os.Stdout
|
||||
err = sshCmd.Run()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to establish SSH connection:%s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Failed to establish SSH connection: %q", err))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -204,15 +215,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
// to establish an independent session like this.
|
||||
err = sshCmd.Run()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error while running ssh command:%s", err))
|
||||
}
|
||||
|
||||
// Delete the temporary key file generated by the command.
|
||||
if resp.KeyType == ssh.KeyTypeDynamic {
|
||||
// Ignoring the error from the below call since it is not a security
|
||||
// issue if the deletion of file is not successful. User is authorized
|
||||
// to have this secret.
|
||||
os.Remove(sshDynamicKeyFileName)
|
||||
c.Ui.Error(fmt.Sprintf("Error while running ssh command: %q", err))
|
||||
}
|
||||
|
||||
// If the session established was longer than the lease expiry, the secret
|
||||
@@ -222,7 +225,7 @@ func (c *SSHCommand) Run(args []string) int {
|
||||
// is run, a fresh credential is generated anyways.
|
||||
err = client.Sys().Revoke(keySecret.LeaseID)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error revoking the key: %s", err))
|
||||
c.Ui.Error(fmt.Sprintf("Error revoking the key: %q", err))
|
||||
}
|
||||
|
||||
return 0
|
||||
@@ -241,15 +244,15 @@ func (c *SSHCommand) defaultRole(mountPoint, ip string) (string, error) {
|
||||
}
|
||||
secret, err := client.Logical().Write(mountPoint+"/lookup", data)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error finding roles for IP %s: %s", ip, err)
|
||||
return "", fmt.Errorf("Error finding roles for IP %q: %q", ip, err)
|
||||
|
||||
}
|
||||
if secret == nil {
|
||||
return "", fmt.Errorf("Error finding roles for IP %s: %s", ip, err)
|
||||
return "", fmt.Errorf("Error finding roles for IP %q: %q", ip, err)
|
||||
}
|
||||
|
||||
if secret.Data["roles"] == nil {
|
||||
return "", fmt.Errorf("No matching roles found for IP %s", ip)
|
||||
return "", fmt.Errorf("No matching roles found for IP %q", ip)
|
||||
}
|
||||
|
||||
if len(secret.Data["roles"].([]interface{})) == 1 {
|
||||
@@ -260,7 +263,7 @@ func (c *SSHCommand) defaultRole(mountPoint, ip string) (string, error) {
|
||||
roleNames += item.(string) + ", "
|
||||
}
|
||||
roleNames = strings.TrimRight(roleNames, ", ")
|
||||
return "", fmt.Errorf("Roles:[%s]"+`
|
||||
return "", fmt.Errorf("Roles:%q. "+`
|
||||
Multiple roles are registered for this IP.
|
||||
Select a role using '-role' option.
|
||||
Note that all roles may not be permitted, based on ACLs.`, roleNames)
|
||||
|
||||
Reference in New Issue
Block a user