in aws_signing_helper/serve.go [151:271]
func AllIssuesHandlers(cred *RefreshableCred, roleName string, opts *CredentialsOpts, signer Signer, signatureAlgorithm string) (http.HandlerFunc, http.HandlerFunc, http.HandlerFunc) {
// Handles PUT requests to /latest/api/token/
putTokenHandler := func(w http.ResponseWriter, r *http.Request) {
if r.Method != "PUT" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// Check for the presence of the X-Forwarded-For header
xForwardedForHeader := r.Header.Get(X_FORWARDED_FOR_HEADER) // canonicalized headers are used (casing doesn't matter)
if xForwardedForHeader != "" {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "unable to process requests with X-Forwarded-For header")
return
}
// Obtain the token TTL
tokenTTLStr := r.Header.Get(EC2_METADATA_TOKEN_TTL_HEADER)
if tokenTTLStr == "" {
tokenTTLStr = DEFAULT_TOKEN_TTL_SECONDS
}
tokenTTL, err := strconv.Atoi(tokenTTLStr)
if err != nil || tokenTTL < 1 || tokenTTL > 21600 {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "invalid token TTL")
return
}
// Generate token and insert it into map
token, err := GenerateToken(100)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, "unable to generate token")
return
}
expirationTime := time.Now().Add(time.Second * time.Duration(tokenTTL))
InsertToken(token, expirationTime)
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTLStr)
io.WriteString(w, token) // nosemgrep
}
// Handles requests to /latest/meta-data/iam/security-credentials/
getRoleNameHandler := func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
err := CheckValidToken(w, r)
if err != nil {
return
}
tokenTTL, err := FindTokenTTLSeconds(r)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTL)
io.WriteString(w, roleName) // nosemgrep
}
// Handles GET requests to /latest/meta-data/iam/security-credentials/<ROLE_NAME>
getCredentialsHandler := func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
err := CheckValidToken(w, r)
if err != nil {
log.Printf("Token validation received error: %s\n", err)
return
}
var nextRefreshTime = cred.Expiration.Add(-RefreshTime)
if time.Until(nextRefreshTime) < RefreshTime {
if Debug {
log.Println("Generating credentials")
}
credentialProcessOutput, gcErr := GenerateCredentials(opts, signer, signatureAlgorithm)
if gcErr != nil {
log.Printf("Error generating credentials: %s\n", gcErr)
}
cred.AccessKeyId = credentialProcessOutput.AccessKeyId
cred.SecretAccessKey = credentialProcessOutput.SecretAccessKey
cred.Token = credentialProcessOutput.SessionToken
cred.Expiration, _ = time.Parse(time.RFC3339, credentialProcessOutput.Expiration)
cred.Code = REFRESHABLE_CRED_CODE
cred.LastUpdated = time.Now()
cred.Type = REFRESHABLE_CRED_TYPE
err := json.NewEncoder(w).Encode(cred)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, "failed to encode credentials")
return
}
} else {
if Debug {
log.Println("Using previously obtained credentials")
}
err := json.NewEncoder(w).Encode(cred)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, "failed to encode credentials")
return
}
}
tokenTTL, err := FindTokenTTLSeconds(r)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.Header().Set(EC2_METADATA_TOKEN_TTL_HEADER, tokenTTL)
}
return putTokenHandler, getRoleNameHandler, getCredentialsHandler
}