mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
![Samuel Karp](/assets/img/avatar_default.png)
AWS recently launched a new version of the EC2 Instance Metadata Service, which is used to provide credentials to the awslogs driver when running on Amazon EC2. This new version of the IMDS adds defense-in-depth mechanisms against open firewalls, reverse proxies, and SSRF vulnerabilities and is generally an improvement over the previous version. An updated version of the AWS SDK is able to handle the both the previous version and the new version of the IMDS and functions when either is enabled. More information about IMDSv2 is available at the following links: * https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/ * https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html Closes https://github.com/moby/moby/issues/40422 Signed-off-by: Samuel Karp <skarp@amazon.com>
284 lines
5 KiB
Go
284 lines
5 KiB
Go
package ini
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// getStringValue will return a quoted string and the amount
|
|
// of bytes read
|
|
//
|
|
// an error will be returned if the string is not properly formatted
|
|
func getStringValue(b []rune) (int, error) {
|
|
if b[0] != '"' {
|
|
return 0, NewParseError("strings must start with '\"'")
|
|
}
|
|
|
|
endQuote := false
|
|
i := 1
|
|
|
|
for ; i < len(b) && !endQuote; i++ {
|
|
if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
|
|
endQuote = true
|
|
break
|
|
} else if escaped {
|
|
/*c, err := getEscapedByte(b[i])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
b[i-1] = c
|
|
b = append(b[:i], b[i+1:]...)
|
|
i--*/
|
|
|
|
continue
|
|
}
|
|
}
|
|
|
|
if !endQuote {
|
|
return 0, NewParseError("missing '\"' in string value")
|
|
}
|
|
|
|
return i + 1, nil
|
|
}
|
|
|
|
// getBoolValue will return a boolean and the amount
|
|
// of bytes read
|
|
//
|
|
// an error will be returned if the boolean is not of a correct
|
|
// value
|
|
func getBoolValue(b []rune) (int, error) {
|
|
if len(b) < 4 {
|
|
return 0, NewParseError("invalid boolean value")
|
|
}
|
|
|
|
n := 0
|
|
for _, lv := range literalValues {
|
|
if len(lv) > len(b) {
|
|
continue
|
|
}
|
|
|
|
if isLitValue(lv, b) {
|
|
n = len(lv)
|
|
}
|
|
}
|
|
|
|
if n == 0 {
|
|
return 0, NewParseError("invalid boolean value")
|
|
}
|
|
|
|
return n, nil
|
|
}
|
|
|
|
// getNumericalValue will return a numerical string, the amount
|
|
// of bytes read, and the base of the number
|
|
//
|
|
// an error will be returned if the number is not of a correct
|
|
// value
|
|
func getNumericalValue(b []rune) (int, int, error) {
|
|
if !isDigit(b[0]) {
|
|
return 0, 0, NewParseError("invalid digit value")
|
|
}
|
|
|
|
i := 0
|
|
helper := numberHelper{}
|
|
|
|
loop:
|
|
for negativeIndex := 0; i < len(b); i++ {
|
|
negativeIndex++
|
|
|
|
if !isDigit(b[i]) {
|
|
switch b[i] {
|
|
case '-':
|
|
if helper.IsNegative() || negativeIndex != 1 {
|
|
return 0, 0, NewParseError("parse error '-'")
|
|
}
|
|
|
|
n := getNegativeNumber(b[i:])
|
|
i += (n - 1)
|
|
helper.Determine(b[i])
|
|
continue
|
|
case '.':
|
|
if err := helper.Determine(b[i]); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
case 'e', 'E':
|
|
if err := helper.Determine(b[i]); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
negativeIndex = 0
|
|
case 'b':
|
|
if helper.numberFormat == hex {
|
|
break
|
|
}
|
|
fallthrough
|
|
case 'o', 'x':
|
|
if i == 0 && b[i] != '0' {
|
|
return 0, 0, NewParseError("incorrect base format, expected leading '0'")
|
|
}
|
|
|
|
if i != 1 {
|
|
return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
|
|
}
|
|
|
|
if err := helper.Determine(b[i]); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
default:
|
|
if isWhitespace(b[i]) {
|
|
break loop
|
|
}
|
|
|
|
if isNewline(b[i:]) {
|
|
break loop
|
|
}
|
|
|
|
if !(helper.numberFormat == hex && isHexByte(b[i])) {
|
|
if i+2 < len(b) && !isNewline(b[i:i+2]) {
|
|
return 0, 0, NewParseError("invalid numerical character")
|
|
} else if !isNewline([]rune{b[i]}) {
|
|
return 0, 0, NewParseError("invalid numerical character")
|
|
}
|
|
|
|
break loop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return helper.Base(), i, nil
|
|
}
|
|
|
|
// isDigit will return whether or not something is an integer
|
|
func isDigit(b rune) bool {
|
|
return b >= '0' && b <= '9'
|
|
}
|
|
|
|
func hasExponent(v []rune) bool {
|
|
return contains(v, 'e') || contains(v, 'E')
|
|
}
|
|
|
|
func isBinaryByte(b rune) bool {
|
|
switch b {
|
|
case '0', '1':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func isOctalByte(b rune) bool {
|
|
switch b {
|
|
case '0', '1', '2', '3', '4', '5', '6', '7':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func isHexByte(b rune) bool {
|
|
if isDigit(b) {
|
|
return true
|
|
}
|
|
return (b >= 'A' && b <= 'F') ||
|
|
(b >= 'a' && b <= 'f')
|
|
}
|
|
|
|
func getValue(b []rune) (int, error) {
|
|
i := 0
|
|
|
|
for i < len(b) {
|
|
if isNewline(b[i:]) {
|
|
break
|
|
}
|
|
|
|
if isOp(b[i:]) {
|
|
break
|
|
}
|
|
|
|
valid, n, err := isValid(b[i:])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if !valid {
|
|
break
|
|
}
|
|
|
|
i += n
|
|
}
|
|
|
|
return i, nil
|
|
}
|
|
|
|
// getNegativeNumber will return a negative number from a
|
|
// byte slice. This will iterate through all characters until
|
|
// a non-digit has been found.
|
|
func getNegativeNumber(b []rune) int {
|
|
if b[0] != '-' {
|
|
return 0
|
|
}
|
|
|
|
i := 1
|
|
for ; i < len(b); i++ {
|
|
if !isDigit(b[i]) {
|
|
return i
|
|
}
|
|
}
|
|
|
|
return i
|
|
}
|
|
|
|
// isEscaped will return whether or not the character is an escaped
|
|
// character.
|
|
func isEscaped(value []rune, b rune) bool {
|
|
if len(value) == 0 {
|
|
return false
|
|
}
|
|
|
|
switch b {
|
|
case '\'': // single quote
|
|
case '"': // quote
|
|
case 'n': // newline
|
|
case 't': // tab
|
|
case '\\': // backslash
|
|
default:
|
|
return false
|
|
}
|
|
|
|
return value[len(value)-1] == '\\'
|
|
}
|
|
|
|
func getEscapedByte(b rune) (rune, error) {
|
|
switch b {
|
|
case '\'': // single quote
|
|
return '\'', nil
|
|
case '"': // quote
|
|
return '"', nil
|
|
case 'n': // newline
|
|
return '\n', nil
|
|
case 't': // table
|
|
return '\t', nil
|
|
case '\\': // backslash
|
|
return '\\', nil
|
|
default:
|
|
return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
|
|
}
|
|
}
|
|
|
|
func removeEscapedCharacters(b []rune) []rune {
|
|
for i := 0; i < len(b); i++ {
|
|
if isEscaped(b[:i], b[i]) {
|
|
c, err := getEscapedByte(b[i])
|
|
if err != nil {
|
|
return b
|
|
}
|
|
|
|
b[i-1] = c
|
|
b = append(b[:i], b[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
|
|
return b
|
|
}
|