open-vault/command/agent/auth/cf/cf.go
Becca Petrin c2894b8d05
Add Kerberos auth agent (#7999)
* add kerberos auth agent

* strip old comment

* changes from feedback

* strip appengine indirect dependency
2020-01-09 14:56:34 -08:00

84 lines
2.1 KiB
Go

package cf
import (
"context"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
cf "github.com/hashicorp/vault-plugin-auth-cf"
"github.com/hashicorp/vault-plugin-auth-cf/signatures"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/command/agent/auth"
)
type cfMethod struct {
mountPath string
roleName string
}
func NewCFAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
if conf == nil {
return nil, errors.New("empty config")
}
if conf.Config == nil {
return nil, errors.New("empty config data")
}
a := &cfMethod{
mountPath: conf.MountPath,
}
if raw, ok := conf.Config["role"]; ok {
if roleName, ok := raw.(string); ok {
a.roleName = roleName
} else {
return nil, errors.New("could not convert 'role' config value to string")
}
} else {
return nil, errors.New("missing 'role' value")
}
return a, nil
}
func (p *cfMethod) Authenticate(ctx context.Context, client *api.Client) (string, http.Header, map[string]interface{}, error) {
pathToClientCert := os.Getenv(cf.EnvVarInstanceCertificate)
if pathToClientCert == "" {
return "", nil, nil, fmt.Errorf("missing %q value", cf.EnvVarInstanceCertificate)
}
certBytes, err := ioutil.ReadFile(pathToClientCert)
if err != nil {
return "", nil, nil, err
}
pathToClientKey := os.Getenv(cf.EnvVarInstanceKey)
if pathToClientKey == "" {
return "", nil, nil, fmt.Errorf("missing %q value", cf.EnvVarInstanceKey)
}
signingTime := time.Now().UTC()
signatureData := &signatures.SignatureData{
SigningTime: signingTime,
Role: p.roleName,
CFInstanceCertContents: string(certBytes),
}
signature, err := signatures.Sign(pathToClientKey, signatureData)
if err != nil {
return "", nil, nil, err
}
data := map[string]interface{}{
"role": p.roleName,
"cf_instance_cert": string(certBytes),
"signing_time": signingTime.Format(signatures.TimeFormat),
"signature": signature,
}
return fmt.Sprintf("%s/login", p.mountPath), nil, data, nil
}
func (p *cfMethod) NewCreds() chan struct{} {
return nil
}
func (p *cfMethod) CredSuccess() {}
func (p *cfMethod) Shutdown() {}