From eb221b3ad7364ff038204891f27d0e10fd0be540 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 11 Sep 2020 20:51:31 +1000 Subject: [PATCH] Add a function to format times compatible with aws sdks --- cli/exec.go | 10 +++++----- iso8601/iso8601.go | 9 +++++++++ iso8601/iso8601_test.go | 24 ++++++++++++++++++++++++ server/ec2server.go | 5 +++-- server/ecsserver.go | 4 ++-- 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 iso8601/iso8601.go create mode 100644 iso8601/iso8601_test.go diff --git a/cli/exec.go b/cli/exec.go index 5f521a6e1..244938c38 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -12,6 +12,7 @@ import ( "syscall" "time" + "github.com/99designs/aws-vault/v6/iso8601" "github.com/99designs/aws-vault/v6/server" "github.com/99designs/aws-vault/v6/vault" "github.com/99designs/keyring" @@ -229,12 +230,11 @@ func execCredentialHelper(input ExecCommandInput, config *vault.Config, creds *c Version: 1, AccessKeyID: val.AccessKeyID, SecretAccessKey: val.SecretAccessKey, + SessionToken: val.SessionToken, } - if val.SessionToken != "" { - credentialData.SessionToken = val.SessionToken - } + if credsExpiresAt, err := creds.ExpiresAt(); err == nil { - credentialData.Expiration = credsExpiresAt.Format(time.RFC3339) + credentialData.Expiration = credsExpiresAt.UTC().Format(time.RFC3339) } json, err := json.Marshal(&credentialData) @@ -267,7 +267,7 @@ func execEnvironment(input ExecCommandInput, config *vault.Config, creds *creden } if expiration, err := creds.ExpiresAt(); err == nil { log.Println("Setting subprocess env: AWS_SESSION_EXPIRATION") - env.Set("AWS_SESSION_EXPIRATION", expiration.Format(time.RFC3339)) + env.Set("AWS_SESSION_EXPIRATION", iso8601.Format(expiration)) } if !supportsExecSyscall() { diff --git a/iso8601/iso8601.go b/iso8601/iso8601.go new file mode 100644 index 000000000..e25aa15fa --- /dev/null +++ b/iso8601/iso8601.go @@ -0,0 +1,9 @@ +package iso8601 + +import "time" + +// Format outputs an ISO-8601 datetime string from the given time, +// in a format compatible with all of the AWS SDKs +func Format(t time.Time) string { + return t.UTC().Format(time.RFC3339) +} diff --git a/iso8601/iso8601_test.go b/iso8601/iso8601_test.go new file mode 100644 index 000000000..fbeba0778 --- /dev/null +++ b/iso8601/iso8601_test.go @@ -0,0 +1,24 @@ +package iso8601 + +import ( + "testing" + "time" +) + +func TestFormat(t *testing.T) { + input, _ := time.Parse(time.RFC3339, "2009-02-04T21:00:57-08:00") + want := "2009-02-05T05:00:57Z" + result := Format(input) + if result != want { + t.Errorf("expected %s for %q got %s", want, input, result) + } +} + +func TestFormatForIssue655(t *testing.T) { + input, _ := time.Parse(time.RFC3339, "2020-09-10T18:16:52+02:00") + want := "2020-09-10T16:16:52Z" + result := Format(input) + if result != want { + t.Errorf("expected %s for %q got %s", want, input, result) + } +} diff --git a/server/ec2server.go b/server/ec2server.go index 1a6d45d09..317bec2b9 100644 --- a/server/ec2server.go +++ b/server/ec2server.go @@ -8,6 +8,7 @@ import ( "net/http" "time" + "github.com/99designs/aws-vault/v6/iso8601" "github.com/aws/aws-sdk-go/aws/credentials" ) @@ -109,12 +110,12 @@ func credsHandler(creds *credentials.Credentials) http.HandlerFunc { err = json.NewEncoder(w).Encode(map[string]interface{}{ "Code": "Success", - "LastUpdated": time.Now().Format(time.RFC3339), + "LastUpdated": iso8601.Format(time.Now()), "Type": "AWS-HMAC", "AccessKeyId": val.AccessKeyID, "SecretAccessKey": val.SecretAccessKey, "Token": val.SessionToken, - "Expiration": credsExpiresAt.Format(time.RFC3339), + "Expiration": iso8601.Format(credsExpiresAt), }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/server/ecsserver.go b/server/ecsserver.go index 9ad7526e4..70019cf48 100644 --- a/server/ecsserver.go +++ b/server/ecsserver.go @@ -8,8 +8,8 @@ import ( "log" "net" "net/http" - "time" + "github.com/99designs/aws-vault/v6/iso8601" "github.com/aws/aws-sdk-go/aws/credentials" ) @@ -72,7 +72,7 @@ func ecsCredsHandler(creds *credentials.Credentials) http.HandlerFunc { "AccessKeyId": val.AccessKeyID, "SecretAccessKey": val.SecretAccessKey, "Token": val.SessionToken, - "Expiration": credsExpiresAt.Format(time.RFC3339), + "Expiration": iso8601.Format(credsExpiresAt), }) if err != nil { writeErrorMessage(w, err.Error(), http.StatusInternalServerError)