carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package rootaws
2
3import (
4 "bytes"
5 "fmt"
6 "strings"
7
8 "github.com/aws/aws-sdk-go-v2/aws"
9)
10
11const MaxCredentialsSize = 64 << 10
12
13// ParseStaticCredentials accepts only one default profile with literal keys.
14// Errors never include credential values or executable configuration text.
15func ParseStaticCredentials(body []byte) (aws.Credentials, error) {
16 var empty aws.Credentials
17 if len(body) > MaxCredentialsSize || bytes.IndexByte(body, 0) >= 0 {
18 return empty, fmt.Errorf("invalid credentials size or encoding")
19 }
20 profile := false
21 values := make(map[string]string)
22 for _, line := range strings.Split(string(body), "\n") {
23 line = strings.TrimSpace(line)
24 if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
25 continue
26 }
27 if strings.HasPrefix(line, "[") {
28 if line != "[default]" || profile {
29 return empty, fmt.Errorf("credentials require one default profile")
30 }
31 profile = true
32 continue
33 }
34 // Same order as the SDK: cut the inline comment, then trim, then
35 // remove one matching pair of quotes.
36 key, value, found := strings.Cut(trimInlineComment(line), "=")
37 key, value = strings.TrimSpace(key), unquote(strings.TrimSpace(value))
38 if !profile || !found || value == "" {
39 return empty, fmt.Errorf("invalid static credentials entry")
40 }
41 switch key {
42 case "aws_access_key_id", "aws_secret_access_key", "aws_session_token":
43 default:
44 return empty, fmt.Errorf("unsupported credentials key")
45 }
46 if _, exists := values[key]; exists || strings.ContainsAny(value, "\r\t ") {
47 return empty, fmt.Errorf("duplicate or invalid static credentials entry")
48 }
49 values[key] = value
50 }
51 if values["aws_access_key_id"] == "" || values["aws_secret_access_key"] == "" {
52 return empty, fmt.Errorf("credentials require access and secret keys")
53 }
54 return aws.Credentials{AccessKeyID: values["aws_access_key_id"], SecretAccessKey: values["aws_secret_access_key"], SessionToken: values["aws_session_token"], Source: "CarlosStaticCredentials"}, nil
55}
56
57// trimInlineComment matches the SDK's property comments: only a # or ; after
58// a space or tab starts one, so values may contain either character.
59func trimInlineComment(s string) string {
60 for _, marker := range []string{" #", " ;", "\t#", "\t;"} {
61 s, _, _ = strings.Cut(s, marker)
62 }
63 return s
64}
65
66func unquote(s string) string {
67 if len(s) >= 2 && (s[0] == '"' && s[len(s)-1] == '"' || s[0] == '\'' && s[len(s)-1] == '\'') {
68 return s[1 : len(s)-1]
69 }
70 return s
71}
72