Skip to content

Commit 6f08015

Browse files
authored
Merge pull request #22 from aws/fix/RolesAnywhere-3788
RolesAnywhere-3788: Include token TTL header in token API response
2 parents 0d7625b + 67cfd99 commit 6f08015

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=1.0.3
1+
VERSION=1.0.4
22

33
release:
44
go build -buildmode=pie -ldflags "-X 'main.Version=${VERSION}' -linkmode=external -w -s" -trimpath -o build/bin/aws_signing_helper cmd/aws_signing_helper/main.go

aws_signing_helper/serve.go

+48
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ type RefreshableCred struct {
2828
AccessKeyId string
2929
SecretAccessKey string
3030
Token string
31+
Code string
32+
Type string
3133
Expiration time.Time
34+
LastUpdated time.Time
3235
}
3336

3437
type Endpoint struct {
@@ -50,6 +53,9 @@ const DEFAULT_TOKEN_TTL_SECONDS = "21600"
5053

5154
const X_FORWARDED_FOR_HEADER = "X-Forwarded-For"
5255

56+
const REFRESHABLE_CRED_TYPE = "AWS-HMAC"
57+
const REFRESHABLE_CRED_CODE = "Success"
58+
5359
const MAX_TOKENS = 256
5460

5561
var mutex sync.Mutex
@@ -120,6 +126,27 @@ func CheckValidToken(w http.ResponseWriter, r *http.Request) error {
120126
return nil
121127
}
122128

129+
// Helper function that finds a token's TTL in seconds
130+
func FindTokenTTLSeconds(r *http.Request) (string, error) {
131+
token := r.Header.Get(EC2_METADATA_TOKEN_HEADER)
132+
if token == "" {
133+
msg := "no token provided"
134+
return "", errors.New(msg)
135+
}
136+
137+
mutex.Lock()
138+
expiration, ok := tokenMap[token]
139+
mutex.Unlock()
140+
if ok {
141+
tokenTTLFloat := expiration.Sub(time.Now()).Seconds()
142+
tokenTTLInt64 := int64(tokenTTLFloat)
143+
return strconv.FormatInt(tokenTTLInt64, 10), nil
144+
} else {
145+
msg := "invalid token provided"
146+
return "", errors.New(msg)
147+
}
148+
}
149+
123150
func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *CredentialsOpts) (http.HandlerFunc, http.HandlerFunc, http.HandlerFunc) {
124151
// Handles PUT requests to /latest/api/token/
125152
putTokenHandler := func(w http.ResponseWriter, r *http.Request) {
@@ -158,6 +185,7 @@ func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *Credentials
158185
expirationTime := time.Now().Add(time.Second * time.Duration(tokenTTL))
159186
InsertToken(token, expirationTime)
160187

188+
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTLStr)
161189
io.WriteString(w, token) // nosemgrep
162190
}
163191

@@ -173,6 +201,12 @@ func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *Credentials
173201
return
174202
}
175203

204+
tokenTTL, err := FindTokenTTLSeconds(r)
205+
if err != nil {
206+
w.WriteHeader(http.StatusUnauthorized)
207+
return
208+
}
209+
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTL)
176210
io.WriteString(w, roleName) // nosemgrep
177211
}
178212

@@ -195,7 +229,11 @@ func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *Credentials
195229
cred.SecretAccessKey = credentialProcessOutput.SecretAccessKey
196230
cred.Token = credentialProcessOutput.SessionToken
197231
cred.Expiration, _ = time.Parse(time.RFC3339, credentialProcessOutput.Expiration)
232+
cred.Code = REFRESHABLE_CRED_CODE
233+
cred.LastUpdated = time.Now()
234+
cred.Type = REFRESHABLE_CRED_TYPE
198235
err := json.NewEncoder(w).Encode(cred)
236+
199237
if err != nil {
200238
w.WriteHeader(http.StatusInternalServerError)
201239
io.WriteString(w, "failed to encode credentials")
@@ -209,6 +247,13 @@ func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *Credentials
209247
return
210248
}
211249
}
250+
251+
tokenTTL, err := FindTokenTTLSeconds(r)
252+
if err != nil {
253+
w.WriteHeader(http.StatusUnauthorized)
254+
return
255+
}
256+
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTL)
212257
}
213258

214259
return putTokenHandler, getRoleNameHandler, getCredentialsHandler
@@ -228,6 +273,9 @@ func Serve(port int, credentialsOptions CredentialsOpts) {
228273
refreshableCred.SecretAccessKey = credentialProcessOutput.SecretAccessKey
229274
refreshableCred.Token = credentialProcessOutput.SessionToken
230275
refreshableCred.Expiration, _ = time.Parse(time.RFC3339, credentialProcessOutput.Expiration)
276+
refreshableCred.Code = REFRESHABLE_CRED_CODE
277+
refreshableCred.LastUpdated = time.Now()
278+
refreshableCred.Type = REFRESHABLE_CRED_TYPE
231279
endpoint := &Endpoint{PortNum: port, TmpCred: refreshableCred}
232280
endpoint.Server = &http.Server{}
233281
roleResourceParts := strings.Split(roleArn.Resource, "/")

0 commit comments

Comments
 (0)