1 package dbus
2
3 import (
4 "bytes"
5 "encoding/binary"
6 "errors"
7 "io"
8 "reflect"
9 "strconv"
10 )
11
12 const protoVersion byte = 1
13
14
15 type Flags byte
16
17 const (
18
19
20
21 FlagNoReplyExpected Flags = 1 << iota
22
23
24 FlagNoAutoStart
25
26
27
28
29
30
31 FlagAllowInteractiveAuthorization
32 )
33
34
35 type Type byte
36
37 const (
38 TypeMethodCall Type = 1 + iota
39 TypeMethodReply
40 TypeError
41 TypeSignal
42 typeMax
43 )
44
45 func (t Type) String() string {
46 switch t {
47 case TypeMethodCall:
48 return "method call"
49 case TypeMethodReply:
50 return "reply"
51 case TypeError:
52 return "error"
53 case TypeSignal:
54 return "signal"
55 }
56 return "invalid"
57 }
58
59
60
61 type HeaderField byte
62
63 const (
64 FieldPath HeaderField = 1 + iota
65 FieldInterface
66 FieldMember
67 FieldErrorName
68 FieldReplySerial
69 FieldDestination
70 FieldSender
71 FieldSignature
72 FieldUnixFDs
73 fieldMax
74 )
75
76
77
78 type InvalidMessageError string
79
80 func (e InvalidMessageError) Error() string {
81 return "dbus: invalid message: " + string(e)
82 }
83
84
85 var fieldTypes = [fieldMax]reflect.Type{
86 FieldPath: objectPathType,
87 FieldInterface: stringType,
88 FieldMember: stringType,
89 FieldErrorName: stringType,
90 FieldReplySerial: uint32Type,
91 FieldDestination: stringType,
92 FieldSender: stringType,
93 FieldSignature: signatureType,
94 FieldUnixFDs: uint32Type,
95 }
96
97
98
99 var requiredFields = [typeMax][]HeaderField{
100 TypeMethodCall: {FieldPath, FieldMember},
101 TypeMethodReply: {FieldReplySerial},
102 TypeError: {FieldErrorName, FieldReplySerial},
103 TypeSignal: {FieldPath, FieldInterface, FieldMember},
104 }
105
106
107 type Message struct {
108 Type
109 Flags
110 Headers map[HeaderField]Variant
111 Body []interface{}
112
113 serial uint32
114 }
115
116 type header struct {
117 Field byte
118 Variant
119 }
120
121 func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
122 var order binary.ByteOrder
123 var hlength, length uint32
124 var typ, flags, proto byte
125 var headers []header
126
127 b := make([]byte, 1)
128 _, err = rd.Read(b)
129 if err != nil {
130 return
131 }
132 switch b[0] {
133 case 'l':
134 order = binary.LittleEndian
135 case 'B':
136 order = binary.BigEndian
137 default:
138 return nil, InvalidMessageError("invalid byte order")
139 }
140
141 dec := newDecoder(rd, order, fds)
142 dec.pos = 1
143
144 msg = new(Message)
145 vs, err := dec.Decode(Signature{"yyyuu"})
146 if err != nil {
147 return nil, err
148 }
149 if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
150 return nil, err
151 }
152 msg.Type = Type(typ)
153 msg.Flags = Flags(flags)
154
155
156 b = make([]byte, 4)
157 _, err = io.ReadFull(rd, b)
158 if err != nil {
159 return nil, err
160 }
161 binary.Read(bytes.NewBuffer(b), order, &hlength)
162 if hlength+length+16 > 1<<27 {
163 return nil, InvalidMessageError("message is too long")
164 }
165 dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
166 dec.pos = 12
167 vs, err = dec.Decode(Signature{"a(yv)"})
168 if err != nil {
169 return nil, err
170 }
171 if err = Store(vs, &headers); err != nil {
172 return nil, err
173 }
174
175 msg.Headers = make(map[HeaderField]Variant)
176 for _, v := range headers {
177 msg.Headers[HeaderField(v.Field)] = v.Variant
178 }
179
180 dec.align(8)
181 body := make([]byte, int(length))
182 if length != 0 {
183 _, err := io.ReadFull(rd, body)
184 if err != nil {
185 return nil, err
186 }
187 }
188
189 if err = msg.IsValid(); err != nil {
190 return nil, err
191 }
192 sig, _ := msg.Headers[FieldSignature].value.(Signature)
193 if sig.str != "" {
194 buf := bytes.NewBuffer(body)
195 dec = newDecoder(buf, order, fds)
196 vs, err := dec.Decode(sig)
197 if err != nil {
198 return nil, err
199 }
200 msg.Body = vs
201 }
202
203 return
204 }
205
206
207
208
209
210 func DecodeMessage(rd io.Reader) (msg *Message, err error) {
211 return DecodeMessageWithFDs(rd, make([]int, 0))
212 }
213
214 type nullwriter struct{}
215
216 func (nullwriter) Write(p []byte) (cnt int, err error) {
217 return len(p), nil
218 }
219
220 func (msg *Message) CountFds() (int, error) {
221 if len(msg.Body) == 0 {
222 return 0, nil
223 }
224 enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
225 err := enc.Encode(msg.Body...)
226 return len(enc.fds), err
227 }
228
229 func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
230 if err := msg.validateHeader(); err != nil {
231 return nil, err
232 }
233 var vs [7]interface{}
234 switch order {
235 case binary.LittleEndian:
236 vs[0] = byte('l')
237 case binary.BigEndian:
238 vs[0] = byte('B')
239 default:
240 return nil, errors.New("dbus: invalid byte order")
241 }
242 body := new(bytes.Buffer)
243 fds = make([]int, 0)
244 enc := newEncoder(body, order, fds)
245 if len(msg.Body) != 0 {
246 err = enc.Encode(msg.Body...)
247 if err != nil {
248 return
249 }
250 }
251 vs[1] = msg.Type
252 vs[2] = msg.Flags
253 vs[3] = protoVersion
254 vs[4] = uint32(len(body.Bytes()))
255 vs[5] = msg.serial
256 headers := make([]header, 0, len(msg.Headers))
257 for k, v := range msg.Headers {
258 headers = append(headers, header{byte(k), v})
259 }
260 vs[6] = headers
261 var buf bytes.Buffer
262 enc = newEncoder(&buf, order, enc.fds)
263 err = enc.Encode(vs[:]...)
264 if err != nil {
265 return
266 }
267 enc.align(8)
268 body.WriteTo(&buf)
269 if buf.Len() > 1<<27 {
270 return make([]int, 0), InvalidMessageError("message is too long")
271 }
272 if _, err := buf.WriteTo(out); err != nil {
273 return make([]int, 0), err
274 }
275 return enc.fds, nil
276 }
277
278
279
280
281 func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
282 _, err = msg.EncodeToWithFDs(out, order)
283 return err
284 }
285
286
287
288 func (msg *Message) IsValid() error {
289 var b bytes.Buffer
290 return msg.EncodeTo(&b, nativeEndian)
291 }
292
293 func (msg *Message) validateHeader() error {
294 if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected|FlagAllowInteractiveAuthorization) != 0 {
295 return InvalidMessageError("invalid flags")
296 }
297 if msg.Type == 0 || msg.Type >= typeMax {
298 return InvalidMessageError("invalid message type")
299 }
300 for k, v := range msg.Headers {
301 if k == 0 || k >= fieldMax {
302 return InvalidMessageError("invalid header")
303 }
304 if reflect.TypeOf(v.value) != fieldTypes[k] {
305 return InvalidMessageError("invalid type of header field")
306 }
307 }
308 for _, v := range requiredFields[msg.Type] {
309 if _, ok := msg.Headers[v]; !ok {
310 return InvalidMessageError("missing required header")
311 }
312 }
313 if path, ok := msg.Headers[FieldPath]; ok {
314 if !path.value.(ObjectPath).IsValid() {
315 return InvalidMessageError("invalid path name")
316 }
317 }
318 if iface, ok := msg.Headers[FieldInterface]; ok {
319 if !isValidInterface(iface.value.(string)) {
320 return InvalidMessageError("invalid interface name")
321 }
322 }
323 if member, ok := msg.Headers[FieldMember]; ok {
324 if !isValidMember(member.value.(string)) {
325 return InvalidMessageError("invalid member name")
326 }
327 }
328 if errname, ok := msg.Headers[FieldErrorName]; ok {
329 if !isValidInterface(errname.value.(string)) {
330 return InvalidMessageError("invalid error name")
331 }
332 }
333 if len(msg.Body) != 0 {
334 if _, ok := msg.Headers[FieldSignature]; !ok {
335 return InvalidMessageError("missing signature")
336 }
337 }
338
339 return nil
340 }
341
342
343
344 func (msg *Message) Serial() uint32 {
345 return msg.serial
346 }
347
348
349
350 func (msg *Message) String() string {
351 if err := msg.IsValid(); err != nil {
352 return "<invalid>"
353 }
354 s := msg.Type.String()
355 if v, ok := msg.Headers[FieldSender]; ok {
356 s += " from " + v.value.(string)
357 }
358 if v, ok := msg.Headers[FieldDestination]; ok {
359 s += " to " + v.value.(string)
360 }
361 s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
362 if v, ok := msg.Headers[FieldReplySerial]; ok {
363 s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
364 }
365 if v, ok := msg.Headers[FieldUnixFDs]; ok {
366 s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
367 }
368 if v, ok := msg.Headers[FieldPath]; ok {
369 s += " path " + string(v.value.(ObjectPath))
370 }
371 if v, ok := msg.Headers[FieldInterface]; ok {
372 s += " interface " + v.value.(string)
373 }
374 if v, ok := msg.Headers[FieldErrorName]; ok {
375 s += " error " + v.value.(string)
376 }
377 if v, ok := msg.Headers[FieldMember]; ok {
378 s += " member " + v.value.(string)
379 }
380 if len(msg.Body) != 0 {
381 s += "\n"
382 }
383 for i, v := range msg.Body {
384 s += " " + MakeVariant(v).String()
385 if i != len(msg.Body)-1 {
386 s += "\n"
387 }
388 }
389 return s
390 }
391
View as plain text