go-tg-screenshot-bot

Форк
0
390 строк · 9.7 Кб
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
// Flags represents the possible flags of a D-Bus message.
15
type Flags byte
16

17
const (
18
	// FlagNoReplyExpected signals that the message is not expected to generate
19
	// a reply. If this flag is set on outgoing messages, any possible reply
20
	// will be discarded.
21
	FlagNoReplyExpected Flags = 1 << iota
22
	// FlagNoAutoStart signals that the message bus should not automatically
23
	// start an application when handling this message.
24
	FlagNoAutoStart
25
	// FlagAllowInteractiveAuthorization may be set on a method call
26
	// message to inform the receiving side that the caller is prepared
27
	// to wait for interactive authorization, which might take a
28
	// considerable time to complete. For instance, if this flag is set,
29
	// it would be appropriate to query the user for passwords or
30
	// confirmation via Polkit or a similar framework.
31
	FlagAllowInteractiveAuthorization
32
)
33

34
// Type represents the possible types of a D-Bus message.
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
// HeaderField represents the possible byte codes for the headers
60
// of a D-Bus message.
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
// An InvalidMessageError describes the reason why a D-Bus message is regarded as
77
// invalid.
78
type InvalidMessageError string
79

80
func (e InvalidMessageError) Error() string {
81
	return "dbus: invalid message: " + string(e)
82
}
83

84
// fieldType are the types of the various header fields.
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
// requiredFields lists the header fields that are required by the different
98
// message types.
99
var requiredFields = [typeMax][]HeaderField{
100
	TypeMethodCall:  {FieldPath, FieldMember},
101
	TypeMethodReply: {FieldReplySerial},
102
	TypeError:       {FieldErrorName, FieldReplySerial},
103
	TypeSignal:      {FieldPath, FieldInterface, FieldMember},
104
}
105

106
// Message represents a single D-Bus message.
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
	// get the header length separately because we need it later
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
// DecodeMessage tries to decode a single message in the D-Bus wire format
207
// from the given reader. The byte order is figured out from the first byte.
208
// The possibly returned error can be an error of the underlying reader, an
209
// InvalidMessageError or a FormatError.
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
// EncodeTo encodes and sends a message to the given writer. The byte order must
279
// be either binary.LittleEndian or binary.BigEndian. If the message is not
280
// valid or an error occurs when writing, an error is returned.
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
// IsValid checks whether msg is a valid message and returns an
287
// InvalidMessageError or FormatError if it is not.
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
// Serial returns the message's serial number. The returned value is only valid
343
// for messages received by eavesdropping.
344
func (msg *Message) Serial() uint32 {
345
	return msg.serial
346
}
347

348
// String returns a string representation of a message similar to the format of
349
// dbus-monitor.
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.