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:
Jeff MitchellandJohan Brandhorst-Satzkorn authored and GitHub committed 2023-10-22 20:48:54 -04:00
1 parent 82b3f202c0
commit fb4a5a98dc
27 files changed
+733 -444

No files matched your search

+5
View File
@@ -878,6 +878,11 @@ var inputStructs = []*structInfo{
outFile: "targets/session_authorization.gen.go",
subtypeName: "SessionAuthorization",
},
{
inProto: &targets.SessionAuthorizationData{},
outFile: "targets/session_authorization_data.gen.go",
subtypeName: "SessionAuthorizationData",
},
{
inProto: &targets.WorkerInfo{},
outFile: "targets/worker_info.gen.go",
+5 -4
View File
@@ -21,11 +21,12 @@ import (
"time"
"github.com/hashicorp/boundary/api"
apiproxy "github.com/hashicorp/boundary/api/proxy"
"github.com/hashicorp/boundary/api/targets"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/proxy"
targetspb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
"github.com/hashicorp/boundary/sdk/pbs/proxy"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-secure-stdlib/base62"
"github.com/mitchellh/cli"
@@ -824,10 +825,10 @@ func (c *Command) handleExec(passthroughArgs []string) {
var envs []string
var argsErr error
var creds credentials
var creds apiproxy.Credentials
if c.sessionAuthz != nil {
var err error
creds, err = parseCredentials(c.sessionAuthz.Credentials)
creds, err = apiproxy.ParseCredentials(c.sessionAuthz.Credentials)
if err != nil {
c.PrintCliError(fmt.Errorf("Error interpreting secret: %w", err))
c.execCmdReturnValue.Store(int32(3))
@@ -884,7 +885,7 @@ func (c *Command) handleExec(passthroughArgs []string) {
return
}
if err := c.printCredentials(creds.unconsumedSessionCredentials()); err != nil {
if err := c.printCredentials(creds.UnconsumedSessionCredentials()); err != nil {
c.PrintCliError(fmt.Errorf("Failed to print credentials: %w", err))
c.execCmdReturnValue.Store(int32(2))
return
@@ -1,123 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package connect
import (
"errors"
"github.com/hashicorp/boundary/api/targets"
"github.com/hashicorp/boundary/globals"
"github.com/mitchellh/mapstructure"
)
type usernamePassword struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
raw *targets.SessionCredential
consumed bool
}
type sshPrivateKey struct {
Username string `mapstructure:"username"`
PrivateKey string `mapstructure:"private_key"`
Passphrase string `mapstructure:"private_key_passphrase"`
raw *targets.SessionCredential
consumed bool
}
type credentials struct {
usernamePassword []usernamePassword
sshPrivateKey []sshPrivateKey
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 globals.CredentialType(cred.CredentialSource.CredentialType) {
case globals.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 globals.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
}
@@ -1,625 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package connect
import (
"testing"
"github.com/hashicorp/boundary/api/targets"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/credential/static"
"github.com/hashicorp/boundary/internal/credential/vault"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
typedUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
CredentialType: string(globals.UsernamePasswordCredentialType),
},
Credential: map[string]any{
"username": "user",
"password": "pass",
},
}
typedSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
CredentialType: string(globals.SshPrivateKeyCredentialType),
},
Credential: map[string]any{
"username": "user",
"private_key": "my-pk",
},
}
vaultUsernamePasswordDeprecatedSubtype = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vault.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"password": "vault-decoded-pass",
},
},
}
vaultSshPrivateKeyDeprecatedSubtype = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vault.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"private_key": "vault-decoded-pk",
},
},
}
vaultUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vault.GenericLibrarySubtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"password": "vault-decoded-pass",
},
},
}
vaultSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vault.GenericLibrarySubtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"private_key": "vault-decoded-pk",
},
},
}
unknownUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "unknown-decoded-user",
"password": "unknown-decoded-pass",
},
},
}
unknownSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "unknown-decoded-user",
"private_key": "unknown-decoded-pk",
},
},
}
staticUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: static.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "static-decoded-user",
"password": "static-decoded-pass",
},
},
}
staticSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: static.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "static-decoded-user",
"private_key": "static-decoded-pk",
},
},
}
staticKv = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: static.Subtype.String(),
CredentialType: "json",
CredentialStoreId: "csst_id",
Description: "test",
Name: "test unspecified json cred",
Id: "credjson_id",
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"secret": map[string]any{
"username": "password",
},
},
},
}
unspecifiedCred = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: static.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"some-value": "decoded-some-value",
},
},
}
unspecifiedCred1 = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: static.Subtype.String(),
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"some-value1": "decoded-some-value1",
},
},
}
)
func Test_parseCredentials(t *testing.T) {
tests := []struct {
name string
creds []*targets.SessionCredential
wantCreds credentials
wantErr bool
}{
{
name: "no-creds",
wantErr: false,
},
{
name: "no-credential-source",
creds: []*targets.SessionCredential{
{
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"private_key": "decoded-pk",
},
},
},
},
wantErr: true,
},
{
name: "username-password-typed",
creds: []*targets.SessionCredential{
typedUsernamePassword,
},
wantCreds: credentials{
usernamePassword: []usernamePassword{
{
Username: "user",
Password: "pass",
raw: typedUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "ssh-private-key-typed",
creds: []*targets.SessionCredential{
typedSshPrivateKey,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "user",
PrivateKey: "my-pk",
raw: typedSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "vault-username-password-decoded",
creds: []*targets.SessionCredential{
vaultUsernamePassword,
},
wantCreds: credentials{
usernamePassword: []usernamePassword{
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
raw: vaultUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "vault-private-key-decoded",
creds: []*targets.SessionCredential{
vaultSshPrivateKey,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
raw: vaultSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "vault-deprecated-username-password-decoded",
creds: []*targets.SessionCredential{
vaultUsernamePasswordDeprecatedSubtype,
},
wantCreds: credentials{
usernamePassword: []usernamePassword{
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
raw: vaultUsernamePasswordDeprecatedSubtype,
},
},
},
wantErr: false,
},
{
name: "vault-deprecated-private-key-decoded",
creds: []*targets.SessionCredential{
vaultSshPrivateKeyDeprecatedSubtype,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
raw: vaultSshPrivateKeyDeprecatedSubtype,
},
},
},
wantErr: false,
},
{
name: "unknown-username-password-decoded",
creds: []*targets.SessionCredential{
unknownUsernamePassword,
},
wantCreds: credentials{
usernamePassword: []usernamePassword{
{
Username: "unknown-decoded-user",
Password: "unknown-decoded-pass",
raw: unknownUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "unknown-private-key-decoded",
creds: []*targets.SessionCredential{
unknownSshPrivateKey,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "unknown-decoded-user",
PrivateKey: "unknown-decoded-pk",
raw: unknownSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "static-username-password-decoded",
creds: []*targets.SessionCredential{
staticUsernamePassword,
},
wantCreds: credentials{
usernamePassword: []usernamePassword{
{
Username: "static-decoded-user",
Password: "static-decoded-pass",
raw: staticUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "static-private-key-decoded",
creds: []*targets.SessionCredential{
staticSshPrivateKey,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "static-decoded-user",
PrivateKey: "static-decoded-pk",
raw: staticSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "unspecified",
creds: []*targets.SessionCredential{
unspecifiedCred,
},
wantCreds: credentials{
unspecified: []*targets.SessionCredential{
unspecifiedCred,
},
},
wantErr: false,
},
{
name: "unspecified-static-json",
creds: []*targets.SessionCredential{
staticKv,
},
wantCreds: credentials{
unspecified: []*targets.SessionCredential{
staticKv,
},
},
wantErr: false,
},
{
name: "mixed",
creds: []*targets.SessionCredential{
staticSshPrivateKey, unspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
unspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
staticKv,
},
wantCreds: credentials{
sshPrivateKey: []sshPrivateKey{
{
Username: "static-decoded-user",
PrivateKey: "static-decoded-pk",
raw: staticSshPrivateKey,
},
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
raw: vaultSshPrivateKey,
},
{
Username: "user",
PrivateKey: "my-pk",
raw: typedSshPrivateKey,
},
},
usernamePassword: []usernamePassword{
{
Username: "static-decoded-user",
Password: "static-decoded-pass",
raw: staticUsernamePassword,
},
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
raw: vaultUsernamePassword,
},
{
Username: "user",
Password: "pass",
raw: typedUsernamePassword,
},
},
unspecified: []*targets.SessionCredential{
unspecifiedCred, unspecifiedCred1, staticKv,
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
creds, err := parseCredentials(tt.creds)
if tt.wantErr {
require.Error(err)
assert.Empty(creds)
return
}
require.NoError(err)
assert.ElementsMatch(tt.wantCreds.usernamePassword, creds.usernamePassword)
assert.ElementsMatch(tt.wantCreds.sshPrivateKey, creds.sshPrivateKey)
assert.ElementsMatch(tt.wantCreds.unspecified, creds.unspecified)
})
}
}
func Test_unconsumedSessionCredentials(t *testing.T) {
tests := []struct {
name string
creds credentials
wantCreds []*targets.SessionCredential
}{
{
name: "no-creds",
wantCreds: nil,
},
{
name: "spk-consumed",
creds: credentials{
sshPrivateKey: []sshPrivateKey{
{
raw: staticSshPrivateKey,
consumed: true,
},
},
},
wantCreds: nil,
},
{
name: "spk",
creds: credentials{
sshPrivateKey: []sshPrivateKey{
{
raw: staticSshPrivateKey,
},
},
},
wantCreds: []*targets.SessionCredential{staticSshPrivateKey},
},
{
name: "up",
creds: credentials{
usernamePassword: []usernamePassword{
{
raw: vaultUsernamePassword,
},
},
},
wantCreds: []*targets.SessionCredential{vaultUsernamePassword},
},
{
name: "up-consumed",
creds: credentials{
usernamePassword: []usernamePassword{
{
raw: vaultUsernamePassword,
consumed: true,
},
},
},
wantCreds: nil,
},
{
name: "unspecified",
creds: credentials{
unspecified: []*targets.SessionCredential{unspecifiedCred},
},
wantCreds: []*targets.SessionCredential{unspecifiedCred},
},
{
name: "mixed",
creds: credentials{
sshPrivateKey: []sshPrivateKey{
{
raw: staticSshPrivateKey,
consumed: true,
},
{
raw: vaultSshPrivateKey,
},
{
raw: typedSshPrivateKey,
},
},
usernamePassword: []usernamePassword{
{
raw: staticUsernamePassword,
consumed: true,
},
{
raw: vaultUsernamePassword,
},
{
raw: typedUsernamePassword,
consumed: true,
},
},
unspecified: []*targets.SessionCredential{unspecifiedCred, unspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
vaultSshPrivateKey, typedSshPrivateKey, vaultUsernamePassword, unspecifiedCred, unspecifiedCred1,
},
},
{
name: "mixed-all-consumed",
creds: credentials{
sshPrivateKey: []sshPrivateKey{
{
raw: staticSshPrivateKey,
consumed: true,
},
{
raw: vaultSshPrivateKey,
consumed: true,
},
{
raw: typedSshPrivateKey,
consumed: true,
},
},
usernamePassword: []usernamePassword{
{
raw: staticUsernamePassword,
consumed: true,
},
{
raw: vaultUsernamePassword,
consumed: true,
},
{
raw: typedUsernamePassword,
consumed: true,
},
},
unspecified: []*targets.SessionCredential{unspecifiedCred, unspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
unspecifiedCred1, unspecifiedCred,
},
},
{
name: "mixed-all-unconsumed",
creds: credentials{
sshPrivateKey: []sshPrivateKey{
{
raw: staticSshPrivateKey,
},
{
raw: vaultSshPrivateKey,
},
{
raw: typedSshPrivateKey,
},
},
usernamePassword: []usernamePassword{
{
raw: staticUsernamePassword,
},
{
raw: vaultUsernamePassword,
},
{
raw: typedUsernamePassword,
},
},
unspecified: []*targets.SessionCredential{unspecifiedCred, unspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
staticSshPrivateKey, unspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
unspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
creds := tt.creds.unconsumedSessionCredentials()
assert.ElementsMatch(tt.wantCreds, creds)
})
}
}
+9 -8
View File
@@ -8,6 +8,7 @@ import (
"os"
"strings"
"github.com/hashicorp/boundary/api/proxy"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/posener/complete"
)
@@ -53,17 +54,17 @@ func (p *postgresFlags) defaultExec() string {
return strings.ToLower(p.flagPostgresStyle)
}
func (p *postgresFlags) buildArgs(c *Command, port, ip, _ string, creds credentials) (args, envs []string, retCreds credentials, retErr error) {
func (p *postgresFlags) buildArgs(c *Command, port, ip, _ string, creds proxy.Credentials) (args, envs []string, retCreds proxy.Credentials, retErr error) {
var username, password string
retCreds = creds
if len(retCreds.usernamePassword) > 0 {
if len(retCreds.UsernamePassword) > 0 {
// Mark credential as consumed so it is not printed to user
retCreds.usernamePassword[0].consumed = true
retCreds.UsernamePassword[0].Consumed = true
// For now just grab the first username password credential brokered
username = retCreds.usernamePassword[0].Username
password = retCreds.usernamePassword[0].Password
username = retCreds.UsernamePassword[0].Username
password = retCreds.UsernamePassword[0].Password
}
switch p.flagPostgresStyle {
@@ -84,7 +85,7 @@ func (p *postgresFlags) buildArgs(c *Command, port, ip, _ string, creds credenti
if password != "" {
passfile, err := os.CreateTemp("", "*")
if err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error saving postgres password to tmp file: %w", err)
return nil, nil, proxy.Credentials{}, fmt.Errorf("Error saving postgres password to tmp file: %w", err)
}
c.cleanupFuncs = append(c.cleanupFuncs, func() error {
if err := os.Remove(passfile.Name()); err != nil {
@@ -94,10 +95,10 @@ func (p *postgresFlags) buildArgs(c *Command, port, ip, _ string, creds credenti
})
_, err = passfile.WriteString(fmt.Sprintf("*:*:*:*:%s", password))
if err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error writing password file to %s: %w", passfile.Name(), err)
return nil, nil, proxy.Credentials{}, fmt.Errorf("Error writing password file to %s: %w", passfile.Name(), err)
}
if err := passfile.Close(); err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error closing password file after writing to %s: %w", passfile.Name(), err)
return nil, nil, proxy.Credentials{}, fmt.Errorf("Error closing password file after writing to %s: %w", passfile.Name(), err)
}
envs = append(envs, fmt.Sprintf("PGPASSFILE=%s", passfile.Name()))
+20 -19
View File
@@ -9,6 +9,7 @@ import (
"os"
"strings"
apiproxy "github.com/hashicorp/boundary/api/proxy"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/target"
"github.com/posener/complete"
@@ -54,7 +55,7 @@ func (s *sshFlags) defaultExec() string {
return strings.ToLower(s.flagSshStyle)
}
func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds credentials) (args, envs []string, retCreds credentials, retErr error) {
func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds apiproxy.Credentials) (args, envs []string, retCreds apiproxy.Credentials, retErr error) {
var username string
retCreds = creds
@@ -89,20 +90,20 @@ func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds credentials)
case "sshpass":
if !tryConsume {
return nil, nil, credentials{}, errors.New("Credentials must be consumed when using sshpass")
return nil, nil, apiproxy.Credentials{}, errors.New("Credentials must be consumed when using sshpass")
}
var password string
if len(retCreds.usernamePassword) > 0 {
if len(retCreds.UsernamePassword) > 0 {
// For now just grab the first username password credential brokered
// Mark credential as consumed so that it is not printed to user
retCreds.usernamePassword[0].consumed = true
retCreds.UsernamePassword[0].Consumed = true
username = retCreds.usernamePassword[0].Username
password = retCreds.usernamePassword[0].Password
username = retCreds.UsernamePassword[0].Username
password = retCreds.UsernamePassword[0].Password
}
if password == "" {
return nil, nil, credentials{}, errors.New("Password is required when using sshpass")
return nil, nil, apiproxy.Credentials{}, errors.New("Password is required when using sshpass")
}
// sshpass requires that the password is passed as env-var "SSHPASS"
@@ -130,24 +131,24 @@ func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds credentials)
// Do nothing
// If we want to consume check if we have a private key available first
case len(creds.sshPrivateKey) > 0:
case len(creds.SshPrivateKey) > 0:
// For now just grab the first ssh private key credential brokered
cred := retCreds.sshPrivateKey[0]
cred := retCreds.SshPrivateKey[0]
username = cred.Username
privateKey := cred.PrivateKey
cred.consumed = true
cred.Consumed = true
if cred.Passphrase != "" {
// Don't re-print everything, but print the passphrase they'll need
cred.consumed = false
delete(cred.raw.Credential, "username")
delete(cred.raw.Credential, "private_key")
cred.Consumed = false
delete(cred.Raw.Credential, "username")
delete(cred.Raw.Credential, "private_key")
}
retCreds.sshPrivateKey[0] = cred
retCreds.SshPrivateKey[0] = cred
pkFile, err := os.CreateTemp("", "*")
if err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error saving ssh private key to tmp file: %w", err)
return nil, nil, apiproxy.Credentials{}, fmt.Errorf("Error saving ssh private key to tmp file: %w", err)
}
c.cleanupFuncs = append(c.cleanupFuncs, func() error {
if err := os.Remove(pkFile.Name()); err != nil {
@@ -163,15 +164,15 @@ func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds credentials)
}
_, err = pkFile.WriteString(privateKey)
if err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error writing private key file to %s: %w", pkFile.Name(), err)
return nil, nil, apiproxy.Credentials{}, fmt.Errorf("Error writing private key file to %s: %w", pkFile.Name(), err)
}
if err := pkFile.Close(); err != nil {
return nil, nil, credentials{}, fmt.Errorf("Error closing private key file after writing to %s: %w", pkFile.Name(), err)
return nil, nil, apiproxy.Credentials{}, fmt.Errorf("Error closing private key file after writing to %s: %w", pkFile.Name(), err)
}
args = append(args, "-i", pkFile.Name())
// Next check if we have a username password credential
case len(creds.usernamePassword) > 0:
case len(creds.UsernamePassword) > 0:
// We cannot use the password of the credential outside of sshpass, but we
// can use the username.
// N.B. Do not mark credential as consumed, as user will still need enter
@@ -180,7 +181,7 @@ func (s *sshFlags) buildArgs(c *Command, port, ip, _ string, creds credentials)
if c.flagUsername == "" {
// If the user did not actively provide a username flag set the
// username to that of the first credential we got.
username = retCreds.usernamePassword[0].Username
username = retCreds.UsernamePassword[0].Username
}
}
}
@@ -1083,6 +1083,8 @@ func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSession
TargetId: t.GetPublicId(),
Scope: authResults.Scope,
CreatedTime: sess.CreateTime.GetTimestamp(),
Expiration: sess.ExpirationTime.GetTimestamp(),
EndpointPort: t.GetDefaultPort(),
Type: t.GetType().String(),
Certificate: sess.Certificate,
PrivateKey: sess.CertificatePrivateKey,
@@ -1103,6 +1105,8 @@ func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSession
TargetId: t.GetPublicId(),
Scope: authResults.Scope,
CreatedTime: sess.CreateTime.GetTimestamp(),
Expiration: sess.ExpirationTime.GetTimestamp(),
EndpointPort: t.GetDefaultPort(),
Type: t.GetType().String(),
AuthorizationToken: encodedMarshaledSad,
UserId: authResults.UserId,
@@ -2652,15 +2652,18 @@ func TestAuthorizeSession(t *testing.T) {
HostId: wantedHostId,
Type: "tcp",
Endpoint: fmt.Sprintf("tcp://%s", tc.wantedEndpoint),
Credentials: []*pb.SessionCredential{{
CredentialSource: &pb.CredentialSource{
Id: clsResp.GetItem().GetId(),
Name: clsResp.GetItem().GetName().GetValue(),
Description: clsResp.GetItem().GetDescription().GetValue(),
CredentialStoreId: vaultStore.GetPublicId(),
Type: vault.GenericLibrarySubtype.String(),
Credentials: []*pb.SessionCredential{
{
CredentialSource: &pb.CredentialSource{
Id: clsResp.GetItem().GetId(),
Name: clsResp.GetItem().GetName().GetValue(),
Description: clsResp.GetItem().GetDescription().GetValue(),
CredentialStoreId: vaultStore.GetPublicId(),
Type: vault.GenericLibrarySubtype.String(),
},
},
}},
},
EndpointPort: uint32(defaultPort),
// TODO: validate the contents of the authorization token is what is expected
}
wantSecret := map[string]any{
@@ -2697,7 +2700,7 @@ func TestAuthorizeSession(t *testing.T) {
gotCred.Secret = nil
got.AuthorizationToken, got.SessionId, got.CreatedTime = "", "", nil
assert.Empty(t, cmp.Diff(got, want, protocmp.Transform()))
assert.Empty(t, cmp.Diff(got, want, protocmp.Transform(), protocmp.IgnoreFields(&pb.SessionAuthorization{}, "expiration")))
})
}
}
@@ -3269,13 +3272,15 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
Description: proj.GetDescription(),
ParentScopeId: proj.GetParentId(),
},
TargetId: tar.GetPublicId(),
UserId: at.GetIamUserId(),
HostSetId: tc.hostSourceId,
HostId: tc.wantedHostId,
Type: "tcp",
Endpoint: fmt.Sprintf("tcp://%s:%d", tc.wantedEndpoint, defaultPort),
Credentials: []*pb.SessionCredential{tc.wantedCred},
TargetId: tar.GetPublicId(),
UserId: at.GetIamUserId(),
HostSetId: tc.hostSourceId,
HostId: tc.wantedHostId,
Type: "tcp",
Endpoint: fmt.Sprintf("tcp://%s:%d", tc.wantedEndpoint, defaultPort),
Credentials: []*pb.SessionCredential{tc.wantedCred},
EndpointPort: uint32(defaultPort),
Expiration: asRes.Item.Expiration,
// TODO: validate the contents of the authorization token is what is expected
}
got := asRes.GetItem()
+1 -1
View File
@@ -22,8 +22,8 @@ import (
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/event"
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
"github.com/hashicorp/boundary/internal/proxy"
"github.com/hashicorp/boundary/internal/util"
"github.com/hashicorp/boundary/sdk/pbs/proxy"
"github.com/hashicorp/go-secure-stdlib/listenerutil"
"github.com/hashicorp/nodeenrollment"
"github.com/hashicorp/nodeenrollment/types"
+21 -14
View File
@@ -33,23 +33,30 @@ func TestDeleteConnectedWorkers(t *testing.T) {
serverRepo, err := c.Controller().ServersRepoFn()
require.NoError(t, err)
workers, err := serverRepo.ListWorkers(ctx, []string{"global"}, server.WithLiveness(-1))
require.NoError(t, err)
workerTimeoutCtx, workerTimeoutCancel := context.WithTimeout(ctx, 5*time.Minute)
defer workerTimeoutCancel()
var pkiWorker, childPkiWorker, childKmsWorker *server.Worker
for _, w := range workers {
if w.Type == "pki" && w.GetAddress() == multiHoppedPkiWorker.ProxyAddrs()[0] {
childPkiWorker = w
}
if w.Type == "pki" && w.GetAddress() == multiHoppedKmsWorker.ProxyAddrs()[0] {
childKmsWorker = w
}
if w.Type == "pki" && w.GetAddress() == directPkiWorker.ProxyAddrs()[0] {
pkiWorker = w
for pkiWorker == nil || childPkiWorker == nil || childKmsWorker == nil {
time.Sleep(time.Second)
select {
case <-workerTimeoutCtx.Done():
require.FailNow(t, "timeout waiting for all workers to connect")
default:
workers, err := serverRepo.ListWorkers(workerTimeoutCtx, []string{"global"}, server.WithLiveness(-1))
require.NoError(t, err)
for _, w := range workers {
if w.Type == "pki" && w.GetAddress() == multiHoppedPkiWorker.ProxyAddrs()[0] {
childPkiWorker = w
}
if w.Type == "pki" && w.GetAddress() == multiHoppedKmsWorker.ProxyAddrs()[0] {
childKmsWorker = w
}
if w.Type == "pki" && w.GetAddress() == directPkiWorker.ProxyAddrs()[0] {
pkiWorker = w
}
}
}
}
require.NotNil(t, childKmsWorker)
require.NotNil(t, childPkiWorker)
require.NotNil(t, pkiWorker)
cases := []struct {
name string
+12
View File
@@ -6433,6 +6433,18 @@
"description": "Output only. The endpoint address that the worker will connect to, useful for setting TLS parameters.",
"readOnly": true
},
"endpoint_port": {
"type": "integer",
"format": "int64",
"description": "Output only. The endpoint port that will be connected to, either from a\nport directly on the target or from a service definition.",
"readOnly": true
},
"expiration": {
"type": "string",
"format": "date-time",
"description": "Output only. The expiration time of the session.",
"readOnly": true
},
"credentials": {
"type": "array",
"items": {
@@ -295,7 +295,8 @@ message WorkerInfo {
string address = 10; // @gotags: `class:"public"`
}
// SessionAuthorizationData contains the fields needed by the proxy command to connect to a worker. It is marshaled inside the SessionAuthorization message.
// SessionAuthorizationData contains the fields needed by the proxy command to
// connect to a worker. It is marshaled inside the SessionAuthorization message.
message SessionAuthorizationData {
// Output only. The ID of the session.
string session_id = 10 [json_name = "session_id"]; // @gotags: `class:"public" eventstream:"observation"`
@@ -315,6 +316,13 @@ message SessionAuthorizationData {
// Output only. The connection limit being applied to this session. -1 means unlimited. This is not actually enforced on the client side but it provides for better listener handling by including it.
int32 connection_limit = 90 [json_name = "connection_limit"];
// Output only. The endpoint port that will be connected to, either from a
// port directly on the target or from a service definition.
uint32 endpoint_port = 102 [json_name = "endpoint_port"]; // @gotags: `class:"public" eventstream:"observation"`
// Output only. The expiration time of the session.
google.protobuf.Timestamp expiration = 105; // @gotags: `class:"public" eventstream:"observation"`
// Output only. The certificate to use when connecting. Raw DER bytes.
bytes certificate = 120; // @gotags: `class:"sensitive"`
@@ -366,6 +374,13 @@ message SessionAuthorization {
// Output only. The endpoint address that the worker will connect to, useful for setting TLS parameters.
string endpoint = 100; // @gotags: `class:"public"`
// Output only. The endpoint port that will be connected to, either from a
// port directly on the target or from a service definition.
uint32 endpoint_port = 102 [json_name = "endpoint_port"]; // @gotags: `class:"public" eventstream:"observation"`
// Output only. The expiration time of the session.
google.protobuf.Timestamp expiration = 105; // @gotags: `class:"public" eventstream:"observation"`
// Output only. The credentials for this session.
repeated SessionCredential credentials = 110 [json_name = "credentials"];
}
@@ -0,0 +1,8 @@
schema_version = 1
project {
license = "MPL-2.0"
copyright_year = 2020
header_ignore = []
}
+2 -2
View File
@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: MPL-2.0
syntax = "proto3";
@@ -7,7 +7,7 @@ package worker.proxy.v1;
import "google/protobuf/timestamp.proto";
option go_package = "github.com/hashicorp/boundary/internal/proxy;proxy";
option go_package = "github.com/hashicorp/boundary/sdk/pbs/proxy;proxy";
enum HANDSHAKECOMMAND {
// Note: Unspecified is the desired zero value based on protolint, but for
-310
View File
@@ -1,310 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: worker/proxy/v1/proxy.proto
package proxy
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type HANDSHAKECOMMAND int32
const (
// Note: Unspecified is the desired zero value based on protolint, but for
// our purposes it simply means a normal connection.
HANDSHAKECOMMAND_HANDSHAKECOMMAND_UNSPECIFIED HANDSHAKECOMMAND = 0
HANDSHAKECOMMAND_HANDSHAKECOMMAND_SESSION_CANCEL HANDSHAKECOMMAND = 1
)
// Enum value maps for HANDSHAKECOMMAND.
var (
HANDSHAKECOMMAND_name = map[int32]string{
0: "HANDSHAKECOMMAND_UNSPECIFIED",
1: "HANDSHAKECOMMAND_SESSION_CANCEL",
}
HANDSHAKECOMMAND_value = map[string]int32{
"HANDSHAKECOMMAND_UNSPECIFIED": 0,
"HANDSHAKECOMMAND_SESSION_CANCEL": 1,
}
)
func (x HANDSHAKECOMMAND) Enum() *HANDSHAKECOMMAND {
p := new(HANDSHAKECOMMAND)
*p = x
return p
}
func (x HANDSHAKECOMMAND) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (HANDSHAKECOMMAND) Descriptor() protoreflect.EnumDescriptor {
return file_worker_proxy_v1_proxy_proto_enumTypes[0].Descriptor()
}
func (HANDSHAKECOMMAND) Type() protoreflect.EnumType {
return &file_worker_proxy_v1_proxy_proto_enumTypes[0]
}
func (x HANDSHAKECOMMAND) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use HANDSHAKECOMMAND.Descriptor instead.
func (HANDSHAKECOMMAND) EnumDescriptor() ([]byte, []int) {
return file_worker_proxy_v1_proxy_proto_rawDescGZIP(), []int{0}
}
type ClientHandshake struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TofuToken string `protobuf:"bytes,10,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"`
Command HANDSHAKECOMMAND `protobuf:"varint,20,opt,name=command,proto3,enum=worker.proxy.v1.HANDSHAKECOMMAND" json:"command,omitempty"`
}
func (x *ClientHandshake) Reset() {
*x = ClientHandshake{}
if protoimpl.UnsafeEnabled {
mi := &file_worker_proxy_v1_proxy_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClientHandshake) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientHandshake) ProtoMessage() {}
func (x *ClientHandshake) ProtoReflect() protoreflect.Message {
mi := &file_worker_proxy_v1_proxy_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientHandshake.ProtoReflect.Descriptor instead.
func (*ClientHandshake) Descriptor() ([]byte, []int) {
return file_worker_proxy_v1_proxy_proto_rawDescGZIP(), []int{0}
}
func (x *ClientHandshake) GetTofuToken() string {
if x != nil {
return x.TofuToken
}
return ""
}
func (x *ClientHandshake) GetCommand() HANDSHAKECOMMAND {
if x != nil {
return x.Command
}
return HANDSHAKECOMMAND_HANDSHAKECOMMAND_UNSPECIFIED
}
type HandshakeResult struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Expiration *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=expiration,proto3" json:"expiration,omitempty"`
ConnectionLimit int32 `protobuf:"varint,20,opt,name=connection_limit,json=connectionLimit,proto3" json:"connection_limit,omitempty"`
ConnectionsLeft int32 `protobuf:"varint,30,opt,name=connections_left,json=connectionsLeft,proto3" json:"connections_left,omitempty"`
}
func (x *HandshakeResult) Reset() {
*x = HandshakeResult{}
if protoimpl.UnsafeEnabled {
mi := &file_worker_proxy_v1_proxy_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HandshakeResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HandshakeResult) ProtoMessage() {}
func (x *HandshakeResult) ProtoReflect() protoreflect.Message {
mi := &file_worker_proxy_v1_proxy_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HandshakeResult.ProtoReflect.Descriptor instead.
func (*HandshakeResult) Descriptor() ([]byte, []int) {
return file_worker_proxy_v1_proxy_proto_rawDescGZIP(), []int{1}
}
func (x *HandshakeResult) GetExpiration() *timestamppb.Timestamp {
if x != nil {
return x.Expiration
}
return nil
}
func (x *HandshakeResult) GetConnectionLimit() int32 {
if x != nil {
return x.ConnectionLimit
}
return 0
}
func (x *HandshakeResult) GetConnectionsLeft() int32 {
if x != nil {
return x.ConnectionsLeft
}
return 0
}
var File_worker_proxy_v1_proxy_proto protoreflect.FileDescriptor
var file_worker_proxy_v1_proxy_proto_rawDesc = []byte{
0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76,
0x31, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x77,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x1f,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x6d, 0x0a, 0x0f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61,
0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x12, 0x3b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x14, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x21, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78,
0x79, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x41, 0x4e, 0x44, 0x53, 0x48, 0x41, 0x4b, 0x45, 0x43, 0x4f,
0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xa3,
0x01, 0x0a, 0x0f, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x75,
0x6c, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29,
0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x1e, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x4c, 0x65, 0x66, 0x74, 0x2a, 0x59, 0x0a, 0x10, 0x48, 0x41, 0x4e, 0x44, 0x53, 0x48, 0x41, 0x4b,
0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x12, 0x20, 0x0a, 0x1c, 0x48, 0x41, 0x4e, 0x44,
0x53, 0x48, 0x41, 0x4b, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53,
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x48, 0x41,
0x4e, 0x44, 0x53, 0x48, 0x41, 0x4b, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x53,
0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x01, 0x42,
0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x3b,
0x70, 0x72, 0x6f, 0x78, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_worker_proxy_v1_proxy_proto_rawDescOnce sync.Once
file_worker_proxy_v1_proxy_proto_rawDescData = file_worker_proxy_v1_proxy_proto_rawDesc
)
func file_worker_proxy_v1_proxy_proto_rawDescGZIP() []byte {
file_worker_proxy_v1_proxy_proto_rawDescOnce.Do(func() {
file_worker_proxy_v1_proxy_proto_rawDescData = protoimpl.X.CompressGZIP(file_worker_proxy_v1_proxy_proto_rawDescData)
})
return file_worker_proxy_v1_proxy_proto_rawDescData
}
var file_worker_proxy_v1_proxy_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_worker_proxy_v1_proxy_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_worker_proxy_v1_proxy_proto_goTypes = []interface{}{
(HANDSHAKECOMMAND)(0), // 0: worker.proxy.v1.HANDSHAKECOMMAND
(*ClientHandshake)(nil), // 1: worker.proxy.v1.ClientHandshake
(*HandshakeResult)(nil), // 2: worker.proxy.v1.HandshakeResult
(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
}
var file_worker_proxy_v1_proxy_proto_depIdxs = []int32{
0, // 0: worker.proxy.v1.ClientHandshake.command:type_name -> worker.proxy.v1.HANDSHAKECOMMAND
3, // 1: worker.proxy.v1.HandshakeResult.expiration:type_name -> google.protobuf.Timestamp
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_worker_proxy_v1_proxy_proto_init() }
func file_worker_proxy_v1_proxy_proto_init() {
if File_worker_proxy_v1_proxy_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_worker_proxy_v1_proxy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClientHandshake); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_worker_proxy_v1_proxy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HandshakeResult); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_worker_proxy_v1_proxy_proto_rawDesc,
NumEnums: 1,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_worker_proxy_v1_proxy_proto_goTypes,
DependencyIndexes: file_worker_proxy_v1_proxy_proto_depIdxs,
EnumInfos: file_worker_proxy_v1_proxy_proto_enumTypes,
MessageInfos: file_worker_proxy_v1_proxy_proto_msgTypes,
}.Build()
File_worker_proxy_v1_proxy_proto = out.File
file_worker_proxy_v1_proxy_proto_rawDesc = nil
file_worker_proxy_v1_proxy_proto_goTypes = nil
file_worker_proxy_v1_proxy_proto_depIdxs = nil
}
@@ -495,7 +495,7 @@ func TestUpdateAfterKeyRotation(t *testing.T) {
// Should start asynchronous rewrapping of the encrypted JSON credential
assert.Equal("pending", result.State)
ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, 3*time.Minute)
defer cancel()
for {
jobs, err := scopesClient.ListKeyVersionDestructionJobs(ctx, proj.PublicId)
+3 -3
View File
@@ -22,9 +22,9 @@ import (
"github.com/hashicorp/boundary/internal/cmd/commands/connect"
"github.com/hashicorp/boundary/internal/daemon/controller/common"
"github.com/hashicorp/boundary/internal/daemon/worker"
"github.com/hashicorp/boundary/internal/proxy"
"github.com/hashicorp/boundary/internal/session"
targetspb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
"github.com/hashicorp/boundary/sdk/pbs/proxy"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-secure-stdlib/base62"
"github.com/mr-tron/base58"
@@ -333,8 +333,8 @@ type TestSessionConnection struct {
}
// Close a test connection
func (t *TestSessionConnection) Close() error {
return t.conn.Close()
func (c *TestSessionConnection) Close() error {
return c.conn.Close()
}
// Connect returns a TestSessionConnection for a TestSession. Check