Add some target fields and move some things around (#3879)
In preparation for putting proxy code in the api package this creates some necessary fields in the target output and it pre-moves credential parsing and proxy handshake code to their new places. This will make the diff for the actual proxy code move quite a bit smaller. Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
This commit is contained in:
1 parent
82b3f202c0
commit
fb4a5a98dc
27 files changed
+733
-444
No files matched your search
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/boundary/api/targets"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
const (
|
||||
usernamePasswordCredentialType = "username_password"
|
||||
sshPrivateKeyCredentialType = "ssh_private_key"
|
||||
)
|
||||
|
||||
// UsernamePassword contains username and password credentials
|
||||
type UsernamePassword struct {
|
||||
Username string `mapstructure:"username"`
|
||||
Password string `mapstructure:"password"`
|
||||
|
||||
Raw *targets.SessionCredential
|
||||
// Consumed can be set by the caller to indicate that the credential has
|
||||
// been used, e.g. displayed to the user
|
||||
Consumed bool
|
||||
}
|
||||
|
||||
// SshPrivateKey contains the username and private key with optional passphrase
|
||||
// for the key
|
||||
type SshPrivateKey struct {
|
||||
Username string `mapstructure:"username"`
|
||||
PrivateKey string `mapstructure:"private_key"`
|
||||
Passphrase string `mapstructure:"private_key_passphrase"`
|
||||
|
||||
Raw *targets.SessionCredential
|
||||
// Consumed can be set by the caller to indicate that the credential has
|
||||
// been used, e.g. displayed to the user
|
||||
Consumed bool
|
||||
}
|
||||
|
||||
type Credentials struct {
|
||||
UsernamePassword []UsernamePassword
|
||||
SshPrivateKey []SshPrivateKey
|
||||
// Unspecified are credentials that do not match one of the types above
|
||||
Unspecified []*targets.SessionCredential
|
||||
}
|
||||
|
||||
func (c Credentials) UnconsumedSessionCredentials() []*targets.SessionCredential {
|
||||
out := make([]*targets.SessionCredential, 0, len(c.SshPrivateKey)+len(c.UsernamePassword)+len(c.Unspecified))
|
||||
|
||||
// Unspecified credentials cannot be consumed
|
||||
out = append(out, c.Unspecified...)
|
||||
|
||||
for _, c := range c.SshPrivateKey {
|
||||
if !c.Consumed {
|
||||
out = append(out, c.Raw)
|
||||
}
|
||||
}
|
||||
for _, c := range c.UsernamePassword {
|
||||
if !c.Consumed {
|
||||
out = append(out, c.Raw)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ParseCredentials(creds []*targets.SessionCredential) (Credentials, error) {
|
||||
if creds == nil {
|
||||
return Credentials{}, nil
|
||||
}
|
||||
var out Credentials
|
||||
for _, cred := range creds {
|
||||
if cred.CredentialSource == nil {
|
||||
return Credentials{}, errors.New("missing credential source")
|
||||
}
|
||||
|
||||
var upCred UsernamePassword
|
||||
var spkCred SshPrivateKey
|
||||
switch cred.CredentialSource.CredentialType {
|
||||
case usernamePasswordCredentialType:
|
||||
// Decode attributes from credential struct
|
||||
if err := mapstructure.Decode(cred.Credential, &upCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
|
||||
if upCred.Username != "" && upCred.Password != "" {
|
||||
upCred.Raw = cred
|
||||
out.UsernamePassword = append(out.UsernamePassword, upCred)
|
||||
continue
|
||||
}
|
||||
|
||||
case sshPrivateKeyCredentialType:
|
||||
// Decode attributes from credential struct
|
||||
if err := mapstructure.Decode(cred.Credential, &spkCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
|
||||
if spkCred.Username != "" && spkCred.PrivateKey != "" {
|
||||
spkCred.Raw = cred
|
||||
out.SshPrivateKey = append(out.SshPrivateKey, spkCred)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Credential type is unspecified, make a best effort attempt to parse
|
||||
// a credential from the Decoded field if it exists
|
||||
if cred.Secret != nil && cred.Secret.Decoded != nil {
|
||||
// Attempt unmarshaling into username password creds
|
||||
if err := mapstructure.Decode(cred.Secret.Decoded, &upCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
if upCred.Username != "" && upCred.Password != "" {
|
||||
upCred.Raw = cred
|
||||
out.UsernamePassword = append(out.UsernamePassword, upCred)
|
||||
continue
|
||||
}
|
||||
|
||||
// Attempt unmarshaling into ssh private key creds
|
||||
if err := mapstructure.Decode(cred.Secret.Decoded, &spkCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
if spkCred.Username != "" && spkCred.PrivateKey != "" {
|
||||
spkCred.Raw = cred
|
||||
out.SshPrivateKey = append(out.SshPrivateKey, spkCred)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// We could not parse the credential
|
||||
out.Unspecified = append(out.Unspecified, cred)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
Reference in new issue
Block a user