1 package log
2
3 import (
4 "bytes"
5 "encoding/json"
6 "errors"
7 "sync/atomic"
8
9 hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
10 )
11
12
13
14 type genMap = map[string]interface{}
15 type scrubberFunc func(genMap) error
16
17 const _scrubbedReplacement = "<scrubbed>"
18
19 var (
20 ErrUnknownType = errors.New("encoded object is of unknown type")
21
22
23 _scrubKeywords = [][]byte{[]byte("env"), []byte("Environment")}
24
25 _scrub int32
26 )
27
28
29 func SetScrubbing(enable bool) {
30 v := int32(0)
31 if enable {
32 v = 1
33 }
34 atomic.StoreInt32(&_scrub, v)
35 }
36
37
38 func IsScrubbingEnabled() bool {
39 v := atomic.LoadInt32(&_scrub)
40 return v != 0
41 }
42
43
44
45 func ScrubProcessParameters(s string) (string, error) {
46
47 b := []byte(s)
48 if !IsScrubbingEnabled() || !hasKeywords(b) || !json.Valid(b) {
49 return s, nil
50 }
51
52 pp := hcsschema.ProcessParameters{}
53 if err := json.Unmarshal(b, &pp); err != nil {
54 return "", err
55 }
56 pp.Environment = map[string]string{_scrubbedReplacement: _scrubbedReplacement}
57
58 b, err := encodeBuffer(bytes.NewBuffer(b[:0]), pp)
59 if err != nil {
60 return "", err
61 }
62 return string(b), nil
63 }
64
65
66
67 func ScrubBridgeCreate(b []byte) ([]byte, error) {
68 return scrubBytes(b, scrubBridgeCreate)
69 }
70
71 func scrubBridgeCreate(m genMap) error {
72 if !isRequestBase(m) {
73 return ErrUnknownType
74 }
75 if ss, ok := m["ContainerConfig"]; ok {
76
77 s, ok := ss.(string)
78 if !ok {
79 return ErrUnknownType
80 }
81 b, err := scrubBytes([]byte(s), scrubLinuxHostedSystem)
82 if err != nil {
83 return err
84 }
85 m["ContainerConfig"] = string(b)
86 return nil
87 }
88 return ErrUnknownType
89 }
90
91 func scrubLinuxHostedSystem(m genMap) error {
92 if m, ok := index(m, "OciSpecification"); ok {
93 if _, ok := m["annotations"]; ok {
94 m["annotations"] = map[string]string{_scrubbedReplacement: _scrubbedReplacement}
95 }
96 if m, ok := index(m, "process"); ok {
97 if _, ok := m["env"]; ok {
98 m["env"] = []string{_scrubbedReplacement}
99 return nil
100 }
101 }
102 }
103 return ErrUnknownType
104 }
105
106
107
108 func ScrubBridgeExecProcess(b []byte) ([]byte, error) {
109 return scrubBytes(b, scrubExecuteProcess)
110 }
111
112 func scrubExecuteProcess(m genMap) error {
113 if !isRequestBase(m) {
114 return ErrUnknownType
115 }
116 if m, ok := index(m, "Settings"); ok {
117 if ss, ok := m["ProcessParameters"]; ok {
118
119 s, ok := ss.(string)
120 if !ok {
121 return ErrUnknownType
122 }
123
124 s, err := ScrubProcessParameters(s)
125 if err != nil {
126 return err
127 }
128
129 m["ProcessParameters"] = s
130 return nil
131 }
132 }
133 return ErrUnknownType
134 }
135
136 func scrubBytes(b []byte, scrub scrubberFunc) ([]byte, error) {
137 if !IsScrubbingEnabled() || !hasKeywords(b) || !json.Valid(b) {
138 return b, nil
139 }
140
141 m := make(genMap)
142 if err := json.Unmarshal(b, &m); err != nil {
143 return nil, err
144 }
145
146
147
148 if err := scrub(m); err != nil {
149 return nil, err
150 }
151
152 b, err := encode(m)
153 if err != nil {
154 return nil, err
155 }
156
157 return b, nil
158 }
159
160 func isRequestBase(m genMap) bool {
161
162 _, a := m["ActivityId"]
163 _, c := m["ContainerId"]
164 return a && c
165 }
166
167
168 func index(m genMap, s string) (genMap, bool) {
169 if m, ok := m[s]; ok {
170 mm, ok := m.(genMap)
171 return mm, ok
172 }
173
174 return m, false
175 }
176
177 func hasKeywords(b []byte) bool {
178 for _, bb := range _scrubKeywords {
179 if bytes.Contains(b, bb) {
180 return true
181 }
182 }
183 return false
184 }
185
View as plain text