package static_test import ( "context" "encoding/json" "fmt" "os" "strings" "testing" "github.com/hashicorp/boundary/api/credentials" "github.com/hashicorp/boundary/api/targets" "github.com/hashicorp/boundary/testing/internal/e2e" "github.com/hashicorp/boundary/testing/internal/e2e/boundary" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestConnectTargetWithAuthzTokenCli uses the boundary cli to connect to a target using the // `authz_token` option func TestConnectTargetWithAuthzTokenCli(t *testing.T) { e2e.MaybeSkipTest(t) c, err := loadConfig() require.NoError(t, err) boundary.AuthenticateAdminCli(t) newOrgId := boundary.CreateNewOrgCli(t) newProjectId := boundary.CreateNewProjectCli(t, newOrgId) newHostCatalogId := boundary.CreateNewHostCatalogCli(t, newProjectId) newHostSetId := boundary.CreateNewHostSetCli(t, newHostCatalogId) newHostId := boundary.CreateNewHostCli(t, newHostCatalogId, c.TargetIp) boundary.AddHostToHostSetCli(t, newHostSetId, newHostId) newTargetId := boundary.CreateNewTargetCli(t, newProjectId, c.TargetPort) boundary.AddHostSourceToTargetCli(t, newTargetId, newHostSetId) newCredentialStoreId := boundary.CreateNewCredentialStoreStaticCli(t, newProjectId) // Create credentials ctx := context.Background() output := e2e.RunCommand(ctx, "boundary", "credentials", "create", "ssh-private-key", "-credential-store-id", newCredentialStoreId, "-username", c.TargetSshUser, "-private-key", "file://"+c.TargetSshKeyPath, "-format", "json", ) require.NoError(t, output.Err, string(output.Stderr)) var newCredentialsResult credentials.CredentialCreateResult err = json.Unmarshal(output.Stdout, &newCredentialsResult) require.NoError(t, err) newCredentialsId := newCredentialsResult.Item.Id t.Logf("Created Credentials: %s", newCredentialsId) // Add credentials to target output = e2e.RunCommand(ctx, "boundary", "targets", "add-credential-sources", "-id", newTargetId, "-brokered-credential-source", newCredentialsId, ) require.NoError(t, output.Err, string(output.Stderr)) // Get credentials for target output = e2e.RunCommand(ctx, "boundary", "targets", "authorize-session", "-id", newTargetId, "-format", "json") require.NoError(t, output.Err, string(output.Stderr)) var newSessionAuthorizationResult targets.SessionAuthorizationResult err = json.Unmarshal(output.Stdout, &newSessionAuthorizationResult) require.NoError(t, err) newSessionAuthorization := newSessionAuthorizationResult.Item retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"]) retrievedKey := fmt.Sprintf("%s\n", newSessionAuthorization.Credentials[0].Credential["private_key"]) assert.Equal(t, c.TargetSshUser, retrievedUser) k, err := os.ReadFile(c.TargetSshKeyPath) require.NoError(t, err) require.Equal(t, string(k), retrievedKey) t.Log("Successfully retrieved credentials for target") // Get auth token for session newAuthToken := newSessionAuthorizationResult.Item.AuthorizationToken // Create key file retrievedKeyPath := fmt.Sprintf("%s/%s", t.TempDir(), "target_private_key.pem") f, err := os.Create(retrievedKeyPath) require.NoError(t, err) _, err = f.WriteString(retrievedKey) require.NoError(t, err) err = os.Chmod(retrievedKeyPath, 0o400) require.NoError(t, err) // Connect to target and print host's IP address using retrieved credentials output = e2e.RunCommand(ctx, "boundary", "connect", "-authz-token", newAuthToken, "-exec", "/usr/bin/ssh", "--", "-l", retrievedUser, "-i", retrievedKeyPath, "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "IdentitiesOnly=yes", // forces the use of the provided key "-p", "{{boundary.port}}", // this is provided by boundary "{{boundary.ip}}", "hostname", "-i", ) require.NoError(t, output.Err, string(output.Stderr)) parts := strings.Fields(string(output.Stdout)) hostIp := parts[len(parts)-1] require.Equal(t, c.TargetIp, hostIp, "SSH session did not return expected output") t.Log("Successfully connected to target") }