0 Star 1 Fork 0

蒋佳李 / vault

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
path_code.go 3.32 KB
一键复制 编辑 原始数据 按行查看 历史
蒋佳李 提交于 2021-03-25 17:46 . 更新
package totp
import (
"context"
"fmt"
"time"
"gitee.com/jiangjiali/vault/sdk/framework"
"gitee.com/jiangjiali/vault/sdk/helper/errwrap"
otplib "gitee.com/jiangjiali/vault/sdk/helper/otp"
totplib "gitee.com/jiangjiali/vault/sdk/helper/otp/totp"
"gitee.com/jiangjiali/vault/sdk/logical"
)
func pathCode(b *backend) *framework.Path {
return &framework.Path{
Pattern: "code/" + framework.GenericNameWithAtRegex("name"),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeString,
Description: "Name of the key.",
},
"code": {
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(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
name := data.Get("name").(string)
// Get the key
key, err := b.Key(ctx, 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(ctx context.Context, 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(ctx, req.Storage, name)
if err != nil {
return nil, err
}
if key == nil {
return logical.ErrorResponse(fmt.Sprintf("unknown key: %s", name)), nil
}
usedName := fmt.Sprintf("%s_%s", name, code)
_, ok := b.usedCodes.Get(usedName)
if ok {
return logical.ErrorResponse("code already used; wait until the next time period"), 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 occurred while validating the code"), err
}
// Take the key skew, add two for behind and in front, and multiple that by
// the period to cover the full possibility of the validity of the key
err = b.usedCodes.Add(usedName, nil, time.Duration(
int64(time.Second)*
int64(key.Period)*
int64(2+key.Skew)))
if err != nil {
return nil, errwrap.Wrapf("error adding code to used cache: {{err}}", 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.
`
Go
1
https://gitee.com/jiangjiali/vault.git
git@gitee.com:jiangjiali/vault.git
jiangjiali
vault
vault
v1.1.11

搜索帮助

53164aa7 5694891 3bd8fe86 5694891