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>
166 lines
3.7 KiB
Go
166 lines
3.7 KiB
Go
package ini
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
// Visitor is an interface used by walkers that will
|
|
// traverse an array of ASTs.
|
|
type Visitor interface {
|
|
VisitExpr(AST) error
|
|
VisitStatement(AST) error
|
|
}
|
|
|
|
// DefaultVisitor is used to visit statements and expressions
|
|
// and ensure that they are both of the correct format.
|
|
// In addition, upon visiting this will build sections and populate
|
|
// the Sections field which can be used to retrieve profile
|
|
// configuration.
|
|
type DefaultVisitor struct {
|
|
scope string
|
|
Sections Sections
|
|
}
|
|
|
|
// NewDefaultVisitor return a DefaultVisitor
|
|
func NewDefaultVisitor() *DefaultVisitor {
|
|
return &DefaultVisitor{
|
|
Sections: Sections{
|
|
container: map[string]Section{},
|
|
},
|
|
}
|
|
}
|
|
|
|
// VisitExpr visits expressions...
|
|
func (v *DefaultVisitor) VisitExpr(expr AST) error {
|
|
t := v.Sections.container[v.scope]
|
|
if t.values == nil {
|
|
t.values = values{}
|
|
}
|
|
|
|
switch expr.Kind {
|
|
case ASTKindExprStatement:
|
|
opExpr := expr.GetRoot()
|
|
switch opExpr.Kind {
|
|
case ASTKindEqualExpr:
|
|
children := opExpr.GetChildren()
|
|
if len(children) <= 1 {
|
|
return NewParseError("unexpected token type")
|
|
}
|
|
|
|
rhs := children[1]
|
|
|
|
if rhs.Root.Type() != TokenLit {
|
|
return NewParseError("unexpected token type")
|
|
}
|
|
|
|
key := EqualExprKey(opExpr)
|
|
v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
t.values[key] = v
|
|
default:
|
|
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
|
|
}
|
|
default:
|
|
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
|
|
}
|
|
|
|
v.Sections.container[v.scope] = t
|
|
return nil
|
|
}
|
|
|
|
// VisitStatement visits statements...
|
|
func (v *DefaultVisitor) VisitStatement(stmt AST) error {
|
|
switch stmt.Kind {
|
|
case ASTKindCompletedSectionStatement:
|
|
child := stmt.GetRoot()
|
|
if child.Kind != ASTKindSectionStatement {
|
|
return NewParseError(fmt.Sprintf("unsupported child statement: %T", child))
|
|
}
|
|
|
|
name := string(child.Root.Raw())
|
|
v.Sections.container[name] = Section{}
|
|
v.scope = name
|
|
default:
|
|
return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Sections is a map of Section structures that represent
|
|
// a configuration.
|
|
type Sections struct {
|
|
container map[string]Section
|
|
}
|
|
|
|
// GetSection will return section p. If section p does not exist,
|
|
// false will be returned in the second parameter.
|
|
func (t Sections) GetSection(p string) (Section, bool) {
|
|
v, ok := t.container[p]
|
|
return v, ok
|
|
}
|
|
|
|
// values represents a map of union values.
|
|
type values map[string]Value
|
|
|
|
// List will return a list of all sections that were successfully
|
|
// parsed.
|
|
func (t Sections) List() []string {
|
|
keys := make([]string, len(t.container))
|
|
i := 0
|
|
for k := range t.container {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|
|
|
|
// Section contains a name and values. This represent
|
|
// a sectioned entry in a configuration file.
|
|
type Section struct {
|
|
Name string
|
|
values values
|
|
}
|
|
|
|
// Has will return whether or not an entry exists in a given section
|
|
func (t Section) Has(k string) bool {
|
|
_, ok := t.values[k]
|
|
return ok
|
|
}
|
|
|
|
// ValueType will returned what type the union is set to. If
|
|
// k was not found, the NoneType will be returned.
|
|
func (t Section) ValueType(k string) (ValueType, bool) {
|
|
v, ok := t.values[k]
|
|
return v.Type, ok
|
|
}
|
|
|
|
// Bool returns a bool value at k
|
|
func (t Section) Bool(k string) bool {
|
|
return t.values[k].BoolValue()
|
|
}
|
|
|
|
// Int returns an integer value at k
|
|
func (t Section) Int(k string) int64 {
|
|
return t.values[k].IntValue()
|
|
}
|
|
|
|
// Float64 returns a float value at k
|
|
func (t Section) Float64(k string) float64 {
|
|
return t.values[k].FloatValue()
|
|
}
|
|
|
|
// String returns the string value at k
|
|
func (t Section) String(k string) string {
|
|
_, ok := t.values[k]
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return t.values[k].StringValue()
|
|
}
|