message.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. package dbus
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "io"
  7. "reflect"
  8. "strconv"
  9. )
  10. const protoVersion byte = 1
  11. // Flags represents the possible flags of a D-Bus message.
  12. type Flags byte
  13. const (
  14. // FlagNoReplyExpected signals that the message is not expected to generate
  15. // a reply. If this flag is set on outgoing messages, any possible reply
  16. // will be discarded.
  17. FlagNoReplyExpected Flags = 1 << iota
  18. // FlagNoAutoStart signals that the message bus should not automatically
  19. // start an application when handling this message.
  20. FlagNoAutoStart
  21. // FlagAllowInteractiveAuthorization may be set on a method call
  22. // message to inform the receiving side that the caller is prepared
  23. // to wait for interactive authorization, which might take a
  24. // considerable time to complete. For instance, if this flag is set,
  25. // it would be appropriate to query the user for passwords or
  26. // confirmation via Polkit or a similar framework.
  27. FlagAllowInteractiveAuthorization
  28. )
  29. // Type represents the possible types of a D-Bus message.
  30. type Type byte
  31. const (
  32. TypeMethodCall Type = 1 + iota
  33. TypeMethodReply
  34. TypeError
  35. TypeSignal
  36. typeMax
  37. )
  38. func (t Type) String() string {
  39. switch t {
  40. case TypeMethodCall:
  41. return "method call"
  42. case TypeMethodReply:
  43. return "reply"
  44. case TypeError:
  45. return "error"
  46. case TypeSignal:
  47. return "signal"
  48. }
  49. return "invalid"
  50. }
  51. // HeaderField represents the possible byte codes for the headers
  52. // of a D-Bus message.
  53. type HeaderField byte
  54. const (
  55. FieldPath HeaderField = 1 + iota
  56. FieldInterface
  57. FieldMember
  58. FieldErrorName
  59. FieldReplySerial
  60. FieldDestination
  61. FieldSender
  62. FieldSignature
  63. FieldUnixFDs
  64. fieldMax
  65. )
  66. // An InvalidMessageError describes the reason why a D-Bus message is regarded as
  67. // invalid.
  68. type InvalidMessageError string
  69. func (e InvalidMessageError) Error() string {
  70. return "dbus: invalid message: " + string(e)
  71. }
  72. // fieldType are the types of the various header fields.
  73. var fieldTypes = [fieldMax]reflect.Type{
  74. FieldPath: objectPathType,
  75. FieldInterface: stringType,
  76. FieldMember: stringType,
  77. FieldErrorName: stringType,
  78. FieldReplySerial: uint32Type,
  79. FieldDestination: stringType,
  80. FieldSender: stringType,
  81. FieldSignature: signatureType,
  82. FieldUnixFDs: uint32Type,
  83. }
  84. // requiredFields lists the header fields that are required by the different
  85. // message types.
  86. var requiredFields = [typeMax][]HeaderField{
  87. TypeMethodCall: {FieldPath, FieldMember},
  88. TypeMethodReply: {FieldReplySerial},
  89. TypeError: {FieldErrorName, FieldReplySerial},
  90. TypeSignal: {FieldPath, FieldInterface, FieldMember},
  91. }
  92. // Message represents a single D-Bus message.
  93. type Message struct {
  94. Type
  95. Flags
  96. Headers map[HeaderField]Variant
  97. Body []interface{}
  98. serial uint32
  99. }
  100. type header struct {
  101. Field byte
  102. Variant
  103. }
  104. func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
  105. var order binary.ByteOrder
  106. var hlength, length uint32
  107. var typ, flags, proto byte
  108. var headers []header
  109. b := make([]byte, 1)
  110. _, err = rd.Read(b)
  111. if err != nil {
  112. return
  113. }
  114. switch b[0] {
  115. case 'l':
  116. order = binary.LittleEndian
  117. case 'B':
  118. order = binary.BigEndian
  119. default:
  120. return nil, InvalidMessageError("invalid byte order")
  121. }
  122. dec := newDecoder(rd, order, fds)
  123. dec.pos = 1
  124. msg = new(Message)
  125. vs, err := dec.Decode(Signature{"yyyuu"})
  126. if err != nil {
  127. return nil, err
  128. }
  129. if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
  130. return nil, err
  131. }
  132. msg.Type = Type(typ)
  133. msg.Flags = Flags(flags)
  134. // get the header length separately because we need it later
  135. b = make([]byte, 4)
  136. _, err = io.ReadFull(rd, b)
  137. if err != nil {
  138. return nil, err
  139. }
  140. binary.Read(bytes.NewBuffer(b), order, &hlength)
  141. if hlength+length+16 > 1<<27 {
  142. return nil, InvalidMessageError("message is too long")
  143. }
  144. dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
  145. dec.pos = 12
  146. vs, err = dec.Decode(Signature{"a(yv)"})
  147. if err != nil {
  148. return nil, err
  149. }
  150. if err = Store(vs, &headers); err != nil {
  151. return nil, err
  152. }
  153. msg.Headers = make(map[HeaderField]Variant)
  154. for _, v := range headers {
  155. msg.Headers[HeaderField(v.Field)] = v.Variant
  156. }
  157. dec.align(8)
  158. body := make([]byte, int(length))
  159. if length != 0 {
  160. _, err := io.ReadFull(rd, body)
  161. if err != nil {
  162. return nil, err
  163. }
  164. }
  165. if err = msg.IsValid(); err != nil {
  166. return nil, err
  167. }
  168. sig, _ := msg.Headers[FieldSignature].value.(Signature)
  169. if sig.str != "" {
  170. buf := bytes.NewBuffer(body)
  171. dec = newDecoder(buf, order, fds)
  172. vs, err := dec.Decode(sig)
  173. if err != nil {
  174. return nil, err
  175. }
  176. msg.Body = vs
  177. }
  178. return
  179. }
  180. // DecodeMessage tries to decode a single message in the D-Bus wire format
  181. // from the given reader. The byte order is figured out from the first byte.
  182. // The possibly returned error can be an error of the underlying reader, an
  183. // InvalidMessageError or a FormatError.
  184. func DecodeMessage(rd io.Reader) (msg *Message, err error) {
  185. return DecodeMessageWithFDs(rd, make([]int, 0))
  186. }
  187. type nullwriter struct{}
  188. func (nullwriter) Write(p []byte) (cnt int, err error) {
  189. return len(p), nil
  190. }
  191. func (msg *Message) CountFds() (int, error) {
  192. if len(msg.Body) == 0 {
  193. return 0, nil
  194. }
  195. enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
  196. err := enc.Encode(msg.Body...)
  197. return len(enc.fds), err
  198. }
  199. func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
  200. if err := msg.validateHeader(); err != nil {
  201. return nil, err
  202. }
  203. var vs [7]interface{}
  204. switch order {
  205. case binary.LittleEndian:
  206. vs[0] = byte('l')
  207. case binary.BigEndian:
  208. vs[0] = byte('B')
  209. default:
  210. return nil, errors.New("dbus: invalid byte order")
  211. }
  212. body := new(bytes.Buffer)
  213. fds = make([]int, 0)
  214. enc := newEncoder(body, order, fds)
  215. if len(msg.Body) != 0 {
  216. err = enc.Encode(msg.Body...)
  217. if err != nil {
  218. return
  219. }
  220. }
  221. vs[1] = msg.Type
  222. vs[2] = msg.Flags
  223. vs[3] = protoVersion
  224. vs[4] = uint32(len(body.Bytes()))
  225. vs[5] = msg.serial
  226. headers := make([]header, 0, len(msg.Headers))
  227. for k, v := range msg.Headers {
  228. headers = append(headers, header{byte(k), v})
  229. }
  230. vs[6] = headers
  231. var buf bytes.Buffer
  232. enc = newEncoder(&buf, order, enc.fds)
  233. err = enc.Encode(vs[:]...)
  234. if err != nil {
  235. return
  236. }
  237. enc.align(8)
  238. body.WriteTo(&buf)
  239. if buf.Len() > 1<<27 {
  240. return make([]int, 0), InvalidMessageError("message is too long")
  241. }
  242. if _, err := buf.WriteTo(out); err != nil {
  243. return make([]int, 0), err
  244. }
  245. return enc.fds, nil
  246. }
  247. // EncodeTo encodes and sends a message to the given writer. The byte order must
  248. // be either binary.LittleEndian or binary.BigEndian. If the message is not
  249. // valid or an error occurs when writing, an error is returned.
  250. func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
  251. _, err = msg.EncodeToWithFDs(out, order)
  252. return err
  253. }
  254. // IsValid checks whether msg is a valid message and returns an
  255. // InvalidMessageError or FormatError if it is not.
  256. func (msg *Message) IsValid() error {
  257. var b bytes.Buffer
  258. return msg.EncodeTo(&b, nativeEndian)
  259. }
  260. func (msg *Message) validateHeader() error {
  261. if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected|FlagAllowInteractiveAuthorization) != 0 {
  262. return InvalidMessageError("invalid flags")
  263. }
  264. if msg.Type == 0 || msg.Type >= typeMax {
  265. return InvalidMessageError("invalid message type")
  266. }
  267. for k, v := range msg.Headers {
  268. if k == 0 || k >= fieldMax {
  269. return InvalidMessageError("invalid header")
  270. }
  271. if reflect.TypeOf(v.value) != fieldTypes[k] {
  272. return InvalidMessageError("invalid type of header field")
  273. }
  274. }
  275. for _, v := range requiredFields[msg.Type] {
  276. if _, ok := msg.Headers[v]; !ok {
  277. return InvalidMessageError("missing required header")
  278. }
  279. }
  280. if path, ok := msg.Headers[FieldPath]; ok {
  281. if !path.value.(ObjectPath).IsValid() {
  282. return InvalidMessageError("invalid path name")
  283. }
  284. }
  285. if iface, ok := msg.Headers[FieldInterface]; ok {
  286. if !isValidInterface(iface.value.(string)) {
  287. return InvalidMessageError("invalid interface name")
  288. }
  289. }
  290. if member, ok := msg.Headers[FieldMember]; ok {
  291. if !isValidMember(member.value.(string)) {
  292. return InvalidMessageError("invalid member name")
  293. }
  294. }
  295. if errname, ok := msg.Headers[FieldErrorName]; ok {
  296. if !isValidInterface(errname.value.(string)) {
  297. return InvalidMessageError("invalid error name")
  298. }
  299. }
  300. if len(msg.Body) != 0 {
  301. if _, ok := msg.Headers[FieldSignature]; !ok {
  302. return InvalidMessageError("missing signature")
  303. }
  304. }
  305. return nil
  306. }
  307. // Serial returns the message's serial number. The returned value is only valid
  308. // for messages received by eavesdropping.
  309. func (msg *Message) Serial() uint32 {
  310. return msg.serial
  311. }
  312. // String returns a string representation of a message similar to the format of
  313. // dbus-monitor.
  314. func (msg *Message) String() string {
  315. if err := msg.IsValid(); err != nil {
  316. return "<invalid>"
  317. }
  318. s := msg.Type.String()
  319. if v, ok := msg.Headers[FieldSender]; ok {
  320. s += " from " + v.value.(string)
  321. }
  322. if v, ok := msg.Headers[FieldDestination]; ok {
  323. s += " to " + v.value.(string)
  324. }
  325. s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
  326. if v, ok := msg.Headers[FieldReplySerial]; ok {
  327. s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
  328. }
  329. if v, ok := msg.Headers[FieldUnixFDs]; ok {
  330. s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
  331. }
  332. if v, ok := msg.Headers[FieldPath]; ok {
  333. s += " path " + string(v.value.(ObjectPath))
  334. }
  335. if v, ok := msg.Headers[FieldInterface]; ok {
  336. s += " interface " + v.value.(string)
  337. }
  338. if v, ok := msg.Headers[FieldErrorName]; ok {
  339. s += " error " + v.value.(string)
  340. }
  341. if v, ok := msg.Headers[FieldMember]; ok {
  342. s += " member " + v.value.(string)
  343. }
  344. if len(msg.Body) != 0 {
  345. s += "\n"
  346. }
  347. for i, v := range msg.Body {
  348. s += " " + MakeVariant(v).String()
  349. if i != len(msg.Body)-1 {
  350. s += "\n"
  351. }
  352. }
  353. return s
  354. }