2014-02-21 20:22:33 +04:00
|
|
|
package s3gof3r
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2014-06-16 01:07:37 +04:00
|
|
|
"fmt"
|
2014-02-21 20:22:33 +04:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
2014-04-03 23:28:52 +04:00
|
|
|
"time"
|
2021-09-13 15:13:35 +03:00
|
|
|
|
|
|
|
"github.com/github/s3gof3r/internal/s3client"
|
2014-02-21 20:22:33 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
// Keys for an Amazon Web Services account.
|
|
|
|
// Used for signing http requests.
|
|
|
|
type Keys struct {
|
|
|
|
AccessKey string
|
|
|
|
SecretKey string
|
|
|
|
SecurityToken string
|
|
|
|
}
|
|
|
|
|
|
|
|
type mdCreds struct {
|
|
|
|
Code string
|
|
|
|
LastUpdated string
|
|
|
|
Type string
|
2015-11-03 04:06:33 +03:00
|
|
|
AccessKeyID string `xml:"AccessKeyId"`
|
2014-02-21 20:22:33 +04:00
|
|
|
SecretAccessKey string
|
|
|
|
Token string
|
|
|
|
Expiration string
|
|
|
|
}
|
|
|
|
|
2014-06-24 01:40:29 +04:00
|
|
|
// InstanceKeys Requests the AWS keys from the instance-based metadata on EC2
|
2014-02-23 22:02:11 +04:00
|
|
|
// Assumes only one IAM role.
|
2021-09-06 18:38:16 +03:00
|
|
|
func InstanceKeys() (Keys, error) {
|
2014-02-21 20:22:33 +04:00
|
|
|
rolePath := "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
|
|
|
|
var creds mdCreds
|
|
|
|
|
|
|
|
// request the role name for the instance
|
|
|
|
// assumes there is only one
|
2014-04-03 23:28:52 +04:00
|
|
|
resp, err := ClientWithTimeout(2 * time.Second).Get(rolePath)
|
2014-02-21 20:22:33 +04:00
|
|
|
if err != nil {
|
2021-09-06 18:38:16 +03:00
|
|
|
return Keys{}, err
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
2021-09-13 15:13:35 +03:00
|
|
|
return Keys{}, s3client.NewRespError(resp)
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:17:18 +03:00
|
|
|
role, err := ioutil.ReadAll(resp.Body)
|
2021-09-06 18:38:16 +03:00
|
|
|
closeErr := resp.Body.Close()
|
2014-02-21 20:22:33 +04:00
|
|
|
if err != nil {
|
2021-09-06 18:38:16 +03:00
|
|
|
return Keys{}, err
|
|
|
|
}
|
|
|
|
if closeErr != nil {
|
|
|
|
return Keys{}, closeErr
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// request the credential metadata for the role
|
|
|
|
resp, err = http.Get(rolePath + string(role))
|
|
|
|
if err != nil {
|
2021-09-06 18:38:16 +03:00
|
|
|
return Keys{}, err
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
2021-09-13 15:13:35 +03:00
|
|
|
return Keys{}, s3client.NewRespError(resp)
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
2021-09-06 14:17:18 +03:00
|
|
|
|
2014-02-21 20:22:33 +04:00
|
|
|
metadata, err := ioutil.ReadAll(resp.Body)
|
2021-09-06 18:38:16 +03:00
|
|
|
closeErr = resp.Body.Close()
|
2014-02-21 20:22:33 +04:00
|
|
|
if err != nil {
|
2021-09-06 18:38:16 +03:00
|
|
|
return Keys{}, err
|
|
|
|
}
|
|
|
|
if closeErr != nil {
|
|
|
|
return Keys{}, closeErr
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
|
2014-04-01 01:27:33 +04:00
|
|
|
if err = json.Unmarshal([]byte(metadata), &creds); err != nil {
|
2021-09-06 18:38:16 +03:00
|
|
|
return Keys{}, err
|
2014-04-01 01:27:33 +04:00
|
|
|
}
|
2021-09-06 18:38:16 +03:00
|
|
|
|
|
|
|
return Keys{
|
2015-11-03 04:06:33 +03:00
|
|
|
AccessKey: creds.AccessKeyID,
|
2014-02-21 20:22:33 +04:00
|
|
|
SecretKey: creds.SecretAccessKey,
|
|
|
|
SecurityToken: creds.Token,
|
2021-09-06 18:38:16 +03:00
|
|
|
}, nil
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
|
2014-06-24 01:40:29 +04:00
|
|
|
// EnvKeys Reads the AWS keys from the environment
|
2014-02-21 20:22:33 +04:00
|
|
|
func EnvKeys() (keys Keys, err error) {
|
2016-02-10 04:28:59 +03:00
|
|
|
keys = Keys{
|
|
|
|
AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"),
|
|
|
|
SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
|
|
|
|
SecurityToken: os.Getenv("AWS_SECURITY_TOKEN"),
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
if keys.AccessKey == "" || keys.SecretKey == "" {
|
2014-06-24 01:40:29 +04:00
|
|
|
err = fmt.Errorf("keys not set in environment: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY")
|
2014-02-21 20:22:33 +04:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|