4c0e3c5d2f
* Initialized basic outline of TOTP backend using Postgresql backend as template * Updated TOTP backend.go's structure and help string * Updated TOTP path_roles.go's structure and help strings * Updated TOTP path_role_create.go's structure and help strings * Fixed typo in path_roles.go * Fixed errors in path_role_create.go and path_roles.go * Added TOTP secret backend information to cli commands * Fixed build errors in path_roles.go and path_role_create.go * Changed field values of period and digits from uint to int, added uint conversion of period when generating passwords * Initialized TOTP test file based on structure of postgresql test file * Added enforcement of input values * Added otp library to vendor folder * Added test steps and cleaned up errors * Modified read credential test step, not working yet * Use of vendored package not allowed - Test error * Removed vendor files for TOTP library * Revert "Removed vendor files for TOTP library" This reverts commit fcd030994bc1741dbf490f3995944e091b11da61. * Hopefully fixed vendor folder issue with TOTP Library * Added additional tests for TOTP backend * Cleaned up comments in TOTP backend_test.go * Added default values of period, algorithm and digits to field schema * Changed account_name and issuer fields to optional * Removed MD5 as a hash algorithm option * Implemented requested pull request changes * Added ability to validate TOTP codes * Added ability to have a key generated * Added skew, qr size and key size parameters * Reset vendor.json prior to merge * Readded otp and barcode libraries to vendor.json * Modified help strings for path_role_create.go * Fixed test issue in testAccStepReadRole * Cleaned up error formatting, variable names and path names. Also added some additional documentation * Moveed barcode and url output to key creation function and did some additional cleanup based on requested changes * Added ability to pass in TOTP urls * Added additional tests for TOTP server functions * Removed unused QRSize, URL and Generate members of keyEntry struct * Removed unnecessary urlstring variable from pathKeyCreate * Added website documentation for TOTP secret backend * Added errors if generate is true and url or key is passed, removed logger from backend, and revised parameter documentation. * Updated website documentation and added QR example * Added exported variable and ability to disable QR generation, cleaned up error reporting, changed default skew value, updated documentation and added additional tests * Updated API documentation to inlude to exported variable and qr size option * Cleaned up return statements in path_code, added error handling while validating codes and clarified documentation for generate parameters in path_keys
111 lines
2.7 KiB
Go
111 lines
2.7 KiB
Go
package totp
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hashicorp/vault/logical"
|
|
"github.com/hashicorp/vault/logical/framework"
|
|
otplib "github.com/pquerna/otp"
|
|
totplib "github.com/pquerna/otp/totp"
|
|
)
|
|
|
|
func pathCode(b *backend) *framework.Path {
|
|
return &framework.Path{
|
|
Pattern: "code/" + framework.GenericNameRegex("name"),
|
|
Fields: map[string]*framework.FieldSchema{
|
|
"name": &framework.FieldSchema{
|
|
Type: framework.TypeString,
|
|
Description: "Name of the key.",
|
|
},
|
|
"code": &framework.FieldSchema{
|
|
Type: framework.TypeString,
|
|
Description: "TOTP code to be validated.",
|
|
},
|
|
},
|
|
|
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
|
logical.ReadOperation: b.pathReadCode,
|
|
logical.UpdateOperation: b.pathValidateCode,
|
|
},
|
|
|
|
HelpSynopsis: pathCodeHelpSyn,
|
|
HelpDescription: pathCodeHelpDesc,
|
|
}
|
|
}
|
|
|
|
func (b *backend) pathReadCode(
|
|
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
|
name := data.Get("name").(string)
|
|
|
|
// Get the key
|
|
key, err := b.Key(req.Storage, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if key == nil {
|
|
return logical.ErrorResponse(fmt.Sprintf("unknown key: %s", name)), nil
|
|
}
|
|
|
|
// Generate password using totp library
|
|
totpToken, err := totplib.GenerateCodeCustom(key.Key, time.Now(), totplib.ValidateOpts{
|
|
Period: key.Period,
|
|
Digits: key.Digits,
|
|
Algorithm: key.Algorithm,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Return the secret
|
|
return &logical.Response{
|
|
Data: map[string]interface{}{
|
|
"code": totpToken,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (b *backend) pathValidateCode(
|
|
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
|
name := data.Get("name").(string)
|
|
code := data.Get("code").(string)
|
|
|
|
// Enforce input value requirements
|
|
if code == "" {
|
|
return logical.ErrorResponse("the code value is required"), nil
|
|
}
|
|
|
|
// Get the key's stored values
|
|
key, err := b.Key(req.Storage, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if key == nil {
|
|
return logical.ErrorResponse(fmt.Sprintf("unknown key: %s", name)), nil
|
|
}
|
|
|
|
valid, err := totplib.ValidateCustom(code, key.Key, time.Now(), totplib.ValidateOpts{
|
|
Period: key.Period,
|
|
Skew: key.Skew,
|
|
Digits: key.Digits,
|
|
Algorithm: key.Algorithm,
|
|
})
|
|
if err != nil && err != otplib.ErrValidateInputInvalidLength {
|
|
return logical.ErrorResponse("an error occured while validating the code"), err
|
|
}
|
|
|
|
return &logical.Response{
|
|
Data: map[string]interface{}{
|
|
"valid": valid,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
const pathCodeHelpSyn = `
|
|
Request time-based one-time use password or validate a password for a certain key .
|
|
`
|
|
const pathCodeHelpDesc = `
|
|
This path generates and validates time-based one-time use passwords for a certain key.
|
|
|
|
`
|