Vault SSH: Helper for OTP creation and role read

This commit is contained in:
vishalnayak 2015-08-13 11:12:30 -07:00
parent c11bcecbbb
commit 2320bfb1e4
3 changed files with 30 additions and 20 deletions

View File

@ -54,17 +54,13 @@ func (b *backend) pathCredsCreateWrite(
return logical.ErrorResponse("Missing ip"), nil
}
roleEntry, err := req.Storage.Get(fmt.Sprintf("roles/%s", roleName))
role, err := b.getRole(req.Storage, roleName)
if err != nil {
return nil, fmt.Errorf("error retrieving role: %s", err)
}
if roleEntry == nil {
if role == nil {
return logical.ErrorResponse(fmt.Sprintf("Role '%s' not found", roleName)), nil
}
var role sshRole
if err := roleEntry.DecodeJSON(&role); err != nil {
return nil, err
}
// Set the default username
if username == "" {
@ -101,7 +97,7 @@ func (b *backend) pathCredsCreateWrite(
"otp": otp,
})
} else if role.KeyType == KeyTypeDynamic {
dynamicPublicKey, dynamicPrivateKey, err := b.GenerateDynamicCredential(req, &role, username, ip)
dynamicPublicKey, dynamicPrivateKey, err := b.GenerateDynamicCredential(req, role, username, ip)
if err != nil {
return nil, err
}
@ -160,7 +156,7 @@ func (b *backend) GenerateDynamicCredential(req *logical.Request, role *sshRole,
}
// Transfer the public key to target machine
publicKeyFileName := uuid.GenerateUUID()
_, publicKeyFileName := b.GenerateSaltedOTP()
err = scpUpload(role.AdminUser, ip, role.Port, hostKey.Key, publicKeyFileName, dynamicPublicKey)
if err != nil {
return "", "", fmt.Errorf("error uploading public key: %s", err)
@ -180,15 +176,19 @@ func (b *backend) GenerateDynamicCredential(req *logical.Request, role *sshRole,
return dynamicPublicKey, dynamicPrivateKey, nil
}
// Generates a UUID OTP and its salted value based on the salt of the backend.
func (b *backend) GenerateSaltedOTP() (string, string) {
str := uuid.GenerateUUID()
return str, b.salt.SaltID(str)
}
// Generates a salted OTP and creates an entry for the same in storage backend.
func (b *backend) GenerateOTPCredential(req *logical.Request, username, ip string) (string, error) {
otp := uuid.GenerateUUID()
otpSalted := b.salt.SaltID(otp)
otp, otpSalted := b.GenerateSaltedOTP()
entry, err := req.Storage.Get("otp/" + otpSalted)
// Make sure that new OTP is not replacing an existing one
for err == nil && entry != nil {
otp = uuid.GenerateUUID()
otpSalted = b.salt.SaltID(otp)
otp, otpSalted = b.GenerateSaltedOTP()
entry, err = req.Storage.Get("otp/" + otpSalted)
if err != nil {
return "", err

View File

@ -194,21 +194,32 @@ func (b *backend) pathRoleWrite(req *logical.Request, d *framework.FieldData) (*
return nil, nil
}
func (b *backend) pathRoleRead(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
roleName := d.Get("role").(string)
roleEntry, err := req.Storage.Get(fmt.Sprintf("roles/%s", roleName))
func (b *backend) getRole(s logical.Storage, n string) (*sshRole, error) {
entry, err := s.Get("roles/" + n)
if err != nil {
return nil, err
}
if roleEntry == nil {
if entry == nil {
return nil, nil
}
var role sshRole
if err := roleEntry.DecodeJSON(&role); err != nil {
var result sshRole
if err := entry.DecodeJSON(&result); err != nil {
return nil, err
}
return &result, nil
}
func (b *backend) pathRoleRead(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
role, err := b.getRole(req.Storage, d.Get("role").(string))
if err != nil {
return nil, err
}
if role == nil {
return nil, nil
}
if role.KeyType == KeyTypeOTP {
return &logical.Response{
Data: map[string]interface{}{

View File

@ -4,7 +4,6 @@ import (
"fmt"
"time"
"github.com/hashicorp/vault/helper/uuid"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
@ -115,7 +114,7 @@ func (b *backend) secretDynamicKeyRevoke(req *logical.Request, d *framework.Fiel
}
// Transfer the dynamic public key to target machine and use it to remove the entry from authorized_keys file
dynamicPublicKeyFileName := uuid.GenerateUUID()
_, dynamicPublicKeyFileName := b.GenerateSaltedOTP()
err = scpUpload(adminUser, ip, port, hostKey.Key, dynamicPublicKeyFileName, dynamicPublicKey)
if err != nil {
return nil, fmt.Errorf("error uploading pubic key: %s", err)