1use anyhow::{bail, ensure, Context, Result};
12use serde_json::{json, Map, Value};
13use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt};
14
15pub const MAX_MESSAGE_BYTES: usize = 1 << 20;
17pub const MAX_DEPTH: usize = 32;
22pub const MAX_AUTH_LINE: usize = 16 * 1024;
24pub const MAX_AUTH_LINES: usize = 32;
25
26pub const METHOD_CALL: u8 = 1;
27pub const METHOD_RETURN: u8 = 2;
28pub const ERROR: u8 = 3;
29pub const SIGNAL: u8 = 4;
30pub const NO_REPLY_EXPECTED: u8 = 0x1;
31
32pub const BUS_NAME: &str = "org.freedesktop.DBus";
33pub const BUS_PATH: &str = "/org/freedesktop/DBus";
34
35pub fn type_name(kind: u8) -> &'static str {
36 match kind {
37 METHOD_CALL => "method_call",
38 METHOD_RETURN => "method_return",
39 ERROR => "error",
40 SIGNAL => "signal",
41 _ => "unknown",
42 }
43}
44
45#[derive(Debug, Clone, PartialEq)]
47pub enum Ty {
48 Byte,
49 Bool,
50 I16,
51 U16,
52 I32,
53 U32,
54 I64,
55 U64,
56 Double,
57 Str,
58 Path,
59 Sig,
60 Fd,
61 Var,
62 Array(Box<Ty>),
63 Dict(Box<Ty>, Box<Ty>),
64 Struct(Vec<Ty>),
65}
66
67impl Ty {
68 fn align(&self) -> usize {
69 match self {
70 Ty::Byte | Ty::Sig | Ty::Var => 1,
71 Ty::I16 | Ty::U16 => 2,
72 Ty::Bool
73 | Ty::I32
74 | Ty::U32
75 | Ty::Str
76 | Ty::Path
77 | Ty::Fd
78 | Ty::Array(_)
79 | Ty::Dict(..) => 4,
80 Ty::I64 | Ty::U64 | Ty::Double | Ty::Struct(_) => 8,
81 }
82 }
83
84 fn is_basic(&self) -> bool {
85 !matches!(self, Ty::Var | Ty::Array(_) | Ty::Dict(..) | Ty::Struct(_))
86 }
87
88 pub fn signature(&self) -> String {
89 match self {
90 Ty::Byte => "y".into(),
91 Ty::Bool => "b".into(),
92 Ty::I16 => "n".into(),
93 Ty::U16 => "q".into(),
94 Ty::I32 => "i".into(),
95 Ty::U32 => "u".into(),
96 Ty::I64 => "x".into(),
97 Ty::U64 => "t".into(),
98 Ty::Double => "d".into(),
99 Ty::Str => "s".into(),
100 Ty::Path => "o".into(),
101 Ty::Sig => "g".into(),
102 Ty::Fd => "h".into(),
103 Ty::Var => "v".into(),
104 Ty::Array(t) => format!("a{}", t.signature()),
105 Ty::Dict(k, v) => format!("a{{{}{}}}", k.signature(), v.signature()),
106 Ty::Struct(ts) => format!("({})", ts.iter().map(Ty::signature).collect::<String>()),
107 }
108 }
109}
110
111pub fn parse_signature(sig: &str) -> Result<Vec<Ty>> {
114 ensure!(sig.len() <= 255, "a signature is at most 255 bytes");
115 let bytes = sig.as_bytes();
116 let mut pos = 0;
117 let mut out = Vec::new();
118 while pos < bytes.len() {
119 out.push(parse_one(bytes, &mut pos, 0, 0)?);
120 }
121 Ok(out)
122}
123
124fn parse_one(b: &[u8], pos: &mut usize, arrays: usize, structs: usize) -> Result<Ty> {
125 let c = *b.get(*pos).context("the signature ends inside a type")?;
126 *pos += 1;
127 Ok(match c {
128 b'y' => Ty::Byte,
129 b'b' => Ty::Bool,
130 b'n' => Ty::I16,
131 b'q' => Ty::U16,
132 b'i' => Ty::I32,
133 b'u' => Ty::U32,
134 b'x' => Ty::I64,
135 b't' => Ty::U64,
136 b'd' => Ty::Double,
137 b's' => Ty::Str,
138 b'o' => Ty::Path,
139 b'g' => Ty::Sig,
140 b'h' => Ty::Fd,
141 b'v' => Ty::Var,
142 b'a' => {
143 ensure!(
144 arrays < 32,
145 "arrays nest more than 32 deep in the signature"
146 );
147 if b.get(*pos) == Some(&b'{') {
148 *pos += 1;
149 let k = parse_one(b, pos, arrays + 1, structs)?;
150 ensure!(k.is_basic(), "a dict key must be a basic type");
151 let v = parse_one(b, pos, arrays + 1, structs)?;
152 ensure!(
153 b.get(*pos) == Some(&b'}'),
154 "a dict entry has exactly two types"
155 );
156 *pos += 1;
157 Ty::Dict(Box::new(k), Box::new(v))
158 } else {
159 Ty::Array(Box::new(parse_one(b, pos, arrays + 1, structs)?))
160 }
161 }
162 b'(' => {
163 ensure!(
164 structs < 32,
165 "structs nest more than 32 deep in the signature"
166 );
167 let mut fields = Vec::new();
168 while b.get(*pos) != Some(&b')') {
169 fields.push(parse_one(b, pos, arrays, structs + 1)?);
170 }
171 *pos += 1;
172 ensure!(!fields.is_empty(), "a struct has at least one field");
173 Ty::Struct(fields)
174 }
175 other => bail!("{:?} is not a D-Bus type code", other as char),
176 })
177}
178
179pub fn valid_object_path(p: &str) -> bool {
180 p == "/"
181 || (p.starts_with('/')
182 && !p.ends_with('/')
183 && p[1..].split('/').all(|e| {
184 !e.is_empty() && e.bytes().all(|c| c.is_ascii_alphanumeric() || c == b'_')
185 }))
186}
187
188pub fn valid_member(m: &str) -> bool {
189 !m.is_empty()
190 && m.len() <= 255
191 && !m.as_bytes()[0].is_ascii_digit()
192 && m.bytes().all(|c| c.is_ascii_alphanumeric() || c == b'_')
193}
194
195pub fn valid_interface(i: &str) -> bool {
196 i.len() <= 255
197 && i.split('.').count() >= 2
198 && i.split('.').all(|e| {
199 !e.is_empty()
200 && !e.as_bytes()[0].is_ascii_digit()
201 && e.bytes().all(|c| c.is_ascii_alphanumeric() || c == b'_')
202 })
203}
204
205pub fn valid_bus_name(n: &str) -> bool {
206 if n.len() > 255 || n.split('.').count() < 2 {
207 return false;
208 }
209 let unique = n.starts_with(':');
210 let body = n.strip_prefix(':').unwrap_or(n);
211 body.split('.').all(|e| {
212 !e.is_empty()
213 && (unique || !e.as_bytes()[0].is_ascii_digit())
214 && e.bytes()
215 .all(|c| c.is_ascii_alphanumeric() || c == b'_' || c == b'-')
216 })
217}
218
219struct W {
220 buf: Vec<u8>,
221}
222
223impl W {
224 fn pad(&mut self, a: usize) {
225 while !self.buf.len().is_multiple_of(a) {
226 self.buf.push(0);
227 }
228 }
229
230 fn u32(&mut self, v: u32) {
231 self.pad(4);
232 self.buf.extend(v.to_le_bytes());
233 }
234
235 fn string(&mut self, s: &str) -> Result<()> {
236 ensure!(!s.contains('\0'), "a D-Bus string cannot contain NUL");
237 self.u32(s.len() as u32);
238 self.buf.extend(s.as_bytes());
239 self.buf.push(0);
240 Ok(())
241 }
242
243 fn sig(&mut self, s: &str) -> Result<()> {
244 ensure!(s.len() <= 255, "a signature is at most 255 bytes");
245 self.buf.push(s.len() as u8);
246 self.buf.extend(s.as_bytes());
247 self.buf.push(0);
248 Ok(())
249 }
250
251 fn put(&mut self, ty: &Ty, v: &Value, depth: usize) -> Result<()> {
252 ensure!(depth <= MAX_DEPTH, "values nest more than {MAX_DEPTH} deep");
253 ensure!(
254 self.buf.len() <= MAX_MESSAGE_BYTES,
255 "the message exceeds {MAX_MESSAGE_BYTES} bytes"
256 );
257 let int = |lo: i128, hi: i128| -> Result<i128> {
258 let n = v
259 .as_i64()
260 .map(i128::from)
261 .or_else(|| v.as_u64().map(i128::from))
262 .or_else(|| v.as_str().and_then(|s| s.parse::<i128>().ok()))
263 .with_context(|| format!("{v} is not a whole number for {}", ty.signature()))?;
264 ensure!(
265 (lo..=hi).contains(&n),
266 "{n} does not fit D-Bus type {}",
267 ty.signature()
268 );
269 Ok(n)
270 };
271 let text = || {
272 v.as_str()
273 .with_context(|| format!("{v} is not a string for {}", ty.signature()))
274 };
275 match ty {
276 Ty::Byte => self.buf.push(int(0, 255)? as u8),
277 Ty::Bool => {
278 let b = v
279 .as_bool()
280 .or_else(|| v.as_u64().filter(|n| *n <= 1).map(|n| n == 1));
281 self.u32(u32::from(
282 b.with_context(|| format!("{v} is not a boolean"))?,
283 ));
284 }
285 Ty::I16 => {
286 self.pad(2);
287 self.buf
288 .extend((int(i16::MIN.into(), i16::MAX.into())? as i16).to_le_bytes());
289 }
290 Ty::U16 => {
291 self.pad(2);
292 self.buf
293 .extend((int(0, u16::MAX.into())? as u16).to_le_bytes());
294 }
295 Ty::I32 => self.u32(int(i32::MIN.into(), i32::MAX.into())? as i32 as u32),
296 Ty::U32 => self.u32(int(0, u32::MAX.into())? as u32),
297 Ty::I64 => {
298 self.pad(8);
299 self.buf
300 .extend((int(i64::MIN.into(), i64::MAX.into())? as i64).to_le_bytes());
301 }
302 Ty::U64 => {
303 self.pad(8);
304 self.buf
305 .extend((int(0, u64::MAX.into())? as u64).to_le_bytes());
306 }
307 Ty::Double => {
308 self.pad(8);
309 let d = v.as_f64().with_context(|| format!("{v} is not a number"))?;
310 self.buf.extend(d.to_le_bytes());
311 }
312 Ty::Str => self.string(text()?)?,
313 Ty::Path => {
314 let p = text()?;
315 ensure!(valid_object_path(p), "{p:?} is not a D-Bus object path");
316 self.string(p)?;
317 }
318 Ty::Sig => {
319 let s = text()?;
320 parse_signature(s)?;
321 self.sig(s)?;
322 }
323 Ty::Fd => bail!("NetGet does not pass Unix file descriptors"),
324 Ty::Var => {
325 let (inner, value) = variant_parts(v)?;
326 let tys = parse_signature(&inner)?;
327 ensure!(
328 tys.len() == 1,
329 "a variant holds exactly one complete type, not {inner:?}"
330 );
331 self.sig(&inner)?;
332 self.put(&tys[0], &value, depth + 1)?;
333 }
334 Ty::Array(elem) => {
335 let items = v
336 .as_array()
337 .with_context(|| format!("{v} is not an array for {}", ty.signature()))?;
338 self.container(elem.align(), |w| {
339 for item in items {
340 w.put(elem, item, depth + 1)?;
341 }
342 Ok(())
343 })?;
344 }
345 Ty::Dict(k, val) => {
346 let entries: Vec<(Value, Value)> = match v {
347 Value::Object(map) => map
348 .iter()
349 .map(|(key, x)| (key_value(k, key), x.clone()))
350 .collect(),
351 Value::Array(pairs) => pairs
352 .iter()
353 .map(|p| match p.as_array().map(Vec::as_slice) {
354 Some([a, b]) => Ok((a.clone(), b.clone())),
355 _ => bail!("a dict given as an array holds [key, value] pairs"),
356 })
357 .collect::<Result<_>>()?,
358 _ => bail!("{v} is not an object for {}", ty.signature()),
359 };
360 self.container(8, |w| {
361 for (key, x) in &entries {
362 w.pad(8);
363 w.put(k, key, depth + 1)?;
364 w.put(val, x, depth + 1)?;
365 }
366 Ok(())
367 })?;
368 }
369 Ty::Struct(fields) => {
370 let items = v.as_array().with_context(|| {
371 format!("{v} is not an array for struct {}", ty.signature())
372 })?;
373 ensure!(
374 items.len() == fields.len(),
375 "struct {} takes {} values, not {}",
376 ty.signature(),
377 fields.len(),
378 items.len()
379 );
380 self.pad(8);
381 for (f, item) in fields.iter().zip(items) {
382 self.put(f, item, depth + 1)?;
383 }
384 }
385 }
386 Ok(())
387 }
388
389 fn container(
391 &mut self,
392 elem_align: usize,
393 body: impl FnOnce(&mut W) -> Result<()>,
394 ) -> Result<()> {
395 self.u32(0);
396 let len_at = self.buf.len() - 4;
397 self.pad(elem_align);
398 let start = self.buf.len();
399 body(self)?;
400 let len = (self.buf.len() - start) as u32;
401 self.buf[len_at..len_at + 4].copy_from_slice(&len.to_le_bytes());
402 Ok(())
403 }
404}
405
406fn key_value(k: &Ty, key: &str) -> Value {
408 match k {
409 Ty::Str | Ty::Path | Ty::Sig => json!(key),
410 Ty::Bool => json!(key == "true"),
411 Ty::Double => key.parse::<f64>().map_or(json!(key), |d| json!(d)),
412 _ => key
413 .parse::<i64>()
414 .map(|n| json!(n))
415 .or_else(|_| key.parse::<u64>().map(|n| json!(n)))
416 .unwrap_or_else(|_| json!(key)),
417 }
418}
419
420pub fn variant_parts(v: &Value) -> Result<(String, Value)> {
424 if let Some(map) = v.as_object() {
425 if map.len() == 2 {
426 if let (Some(Value::String(s)), Some(inner)) = (map.get("signature"), map.get("value"))
427 {
428 return Ok((s.clone(), inner.clone()));
429 }
430 }
431 }
432 Ok((infer_signature(v)?, v.clone()))
433}
434
435pub fn infer_signature(v: &Value) -> Result<String> {
436 Ok(match v {
437 Value::Null => {
438 bail!("null has no D-Bus type; give the variant as {{\"signature\", \"value\"}}")
439 }
440 Value::Bool(_) => "b".into(),
441 Value::Number(n) if n.is_i64() => {
442 if i32::try_from(n.as_i64().unwrap_or_default()).is_ok() {
443 "i".into()
444 } else {
445 "x".into()
446 }
447 }
448 Value::Number(n) if n.is_u64() => "t".into(),
449 Value::Number(_) => "d".into(),
450 Value::String(_) => "s".into(),
451 Value::Array(items) if !items.is_empty() && items.iter().all(Value::is_string) => {
452 "as".into()
453 }
454 Value::Array(_) => "av".into(),
455 Value::Object(_) => "a{sv}".into(),
456 })
457}
458
459pub fn marshal(signature: &str, values: &[Value]) -> Result<Vec<u8>> {
461 let tys = parse_signature(signature)?;
462 ensure!(
463 tys.len() == values.len(),
464 "signature {signature:?} has {} values, {} were given",
465 tys.len(),
466 values.len()
467 );
468 let mut w = W { buf: Vec::new() };
469 for (t, v) in tys.iter().zip(values) {
470 w.put(t, v, 0)?;
471 }
472 ensure!(
473 w.buf.len() <= MAX_MESSAGE_BYTES,
474 "the body exceeds {MAX_MESSAGE_BYTES} bytes"
475 );
476 Ok(w.buf)
477}
478
479struct R<'a> {
480 b: &'a [u8],
481 pos: usize,
482 big: bool,
483}
484
485impl R<'_> {
486 fn align(&mut self, a: usize) -> Result<()> {
487 let to = self.pos.div_ceil(a) * a;
488 ensure!(to <= self.b.len(), "the message ends inside padding");
489 self.pos = to;
490 Ok(())
491 }
492
493 fn take(&mut self, n: usize) -> Result<&[u8]> {
494 let end = self
495 .pos
496 .checked_add(n)
497 .filter(|e| *e <= self.b.len())
498 .context("the message ends inside a value")?;
499 let s = &self.b[self.pos..end];
500 self.pos = end;
501 Ok(s)
502 }
503
504 fn u32(&mut self) -> Result<u32> {
505 let big = self.big;
506 self.align(4)?;
507 let s = self.take(4)?;
508 let a = [s[0], s[1], s[2], s[3]];
509 Ok(if big {
510 u32::from_be_bytes(a)
511 } else {
512 u32::from_le_bytes(a)
513 })
514 }
515
516 fn u16(&mut self) -> Result<u16> {
517 let big = self.big;
518 self.align(2)?;
519 let s = self.take(2)?;
520 Ok(if big {
521 u16::from_be_bytes([s[0], s[1]])
522 } else {
523 u16::from_le_bytes([s[0], s[1]])
524 })
525 }
526
527 fn u64(&mut self) -> Result<u64> {
528 let big = self.big;
529 self.align(8)?;
530 let s = self.take(8)?;
531 let mut a = [0u8; 8];
532 a.copy_from_slice(s);
533 Ok(if big {
534 u64::from_be_bytes(a)
535 } else {
536 u64::from_le_bytes(a)
537 })
538 }
539
540 fn string(&mut self) -> Result<String> {
541 let len = self.u32()? as usize;
542 let s = self.take(len)?.to_vec();
543 ensure!(self.take(1)? == [0], "a string is not NUL-terminated");
544 String::from_utf8(s).context("a string is not valid UTF-8")
545 }
546
547 fn sig(&mut self) -> Result<String> {
548 let len = self.take(1)?[0] as usize;
549 let s = self.take(len)?.to_vec();
550 ensure!(self.take(1)? == [0], "a signature is not NUL-terminated");
551 String::from_utf8(s).context("a signature is not ASCII")
552 }
553
554 fn get(&mut self, ty: &Ty, depth: usize) -> Result<Value> {
555 ensure!(depth <= MAX_DEPTH, "values nest more than {MAX_DEPTH} deep");
556 Ok(match ty {
557 Ty::Byte => json!(self.take(1)?[0]),
558 Ty::Bool => {
559 let n = self.u32()?;
560 ensure!(n <= 1, "a boolean is {n}");
561 json!(n == 1)
562 }
563 Ty::I16 => json!(self.u16()? as i16),
564 Ty::U16 => json!(self.u16()?),
565 Ty::I32 => json!(self.u32()? as i32),
566 Ty::U32 | Ty::Fd => json!(self.u32()?),
567 Ty::I64 => json!(self.u64()? as i64),
568 Ty::U64 => json!(self.u64()?),
569 Ty::Double => json!(f64::from_bits(self.u64()?)),
570 Ty::Str => json!(self.string()?),
571 Ty::Path => {
572 let p = self.string()?;
573 ensure!(valid_object_path(&p), "{p:?} is not an object path");
574 json!(p)
575 }
576 Ty::Sig => {
577 let s = self.sig()?;
578 parse_signature(&s)?;
579 json!(s)
580 }
581 Ty::Var => {
582 let s = self.sig()?;
583 let tys = parse_signature(&s)?;
584 ensure!(
585 tys.len() == 1,
586 "a variant holds one complete type, not {s:?}"
587 );
588 json!({"signature": s, "value": self.get(&tys[0], depth + 1)?})
589 }
590 Ty::Array(elem) => {
591 let end = self.array_end(elem.align())?;
592 let mut items = Vec::new();
593 while self.pos < end {
594 items.push(self.get(elem, depth + 1)?);
595 }
596 ensure!(self.pos == end, "an array's elements overrun its length");
597 Value::Array(items)
598 }
599 Ty::Dict(k, v) => {
600 let end = self.array_end(8)?;
601 let mut map = Map::new();
602 while self.pos < end {
603 self.align(8)?;
604 let key = match self.get(k, depth + 1)? {
605 Value::String(s) => s,
606 other => other.to_string(),
607 };
608 let value = self.get(v, depth + 1)?;
609 map.insert(key, value);
610 }
611 ensure!(self.pos == end, "a dict's entries overrun its length");
612 Value::Object(map)
613 }
614 Ty::Struct(fields) => {
615 self.align(8)?;
616 let mut items = Vec::with_capacity(fields.len());
617 for f in fields {
618 items.push(self.get(f, depth + 1)?);
619 }
620 Value::Array(items)
621 }
622 })
623 }
624
625 fn array_end(&mut self, elem_align: usize) -> Result<usize> {
626 let len = self.u32()? as usize;
627 ensure!(
628 len <= 64 << 20,
629 "an array of {len} bytes exceeds the specification's 64 MiB"
630 );
631 self.align(elem_align)?;
632 self.pos
633 .checked_add(len)
634 .filter(|e| *e <= self.b.len())
635 .context("an array's length overruns the message")
636 }
637}
638
639#[derive(Debug, Clone, Default, PartialEq)]
640pub struct Message {
641 pub kind: u8,
642 pub flags: u8,
643 pub serial: u32,
644 pub path: Option<String>,
645 pub interface: Option<String>,
646 pub member: Option<String>,
647 pub error_name: Option<String>,
648 pub reply_serial: Option<u32>,
649 pub destination: Option<String>,
650 pub sender: Option<String>,
651 pub signature: String,
652 pub body: Vec<Value>,
654}
655
656impl Message {
657 pub fn call(path: &str, interface: Option<&str>, member: &str) -> Self {
658 Message {
659 kind: METHOD_CALL,
660 path: Some(path.into()),
661 interface: interface.map(Into::into),
662 member: Some(member.into()),
663 ..Default::default()
664 }
665 }
666
667 pub fn reply_to(call: &Message, signature: &str, body: Vec<Value>) -> Self {
669 Message {
670 kind: METHOD_RETURN,
671 reply_serial: Some(call.serial),
672 destination: call.sender.clone(),
673 sender: call.destination.clone(),
674 signature: signature.into(),
675 body,
676 ..Default::default()
677 }
678 }
679
680 pub fn error_to(call: &Message, name: &str, message: &str) -> Self {
681 Message {
682 kind: ERROR,
683 reply_serial: Some(call.serial),
684 error_name: Some(name.into()),
685 destination: call.sender.clone(),
686 sender: call.destination.clone(),
687 signature: "s".into(),
688 body: vec![json!(message)],
689 ..Default::default()
690 }
691 }
692
693 pub fn expects_reply(&self) -> bool {
694 self.kind == METHOD_CALL && self.flags & NO_REPLY_EXPECTED == 0
695 }
696
697 pub fn first_string(&self) -> Option<&str> {
699 self.body.first().and_then(Value::as_str)
700 }
701
702 pub fn encode(&self) -> Result<Vec<u8>> {
703 ensure!(self.serial != 0, "a message's serial is never 0");
704 let body = marshal(&self.signature, &self.body)?;
705 let mut w = W {
706 buf: vec![b'l', self.kind, self.flags, 1],
707 };
708 w.u32(body.len() as u32);
709 w.u32(self.serial);
710 let field = |w: &mut W, code: u8, sig: &str, v: &Value| -> Result<()> {
711 w.pad(8);
712 w.buf.push(code);
713 w.sig(sig)?;
714 w.put(&parse_signature(sig)?[0], v, 1)
715 };
716 w.container(8, |w| {
717 if let Some(p) = &self.path {
718 field(w, 1, "o", &json!(p))?;
719 }
720 if let Some(i) = &self.interface {
721 ensure!(valid_interface(i), "{i:?} is not a D-Bus interface name");
722 field(w, 2, "s", &json!(i))?;
723 }
724 if let Some(m) = &self.member {
725 ensure!(valid_member(m), "{m:?} is not a D-Bus member name");
726 field(w, 3, "s", &json!(m))?;
727 }
728 if let Some(e) = &self.error_name {
729 ensure!(valid_interface(e), "{e:?} is not a D-Bus error name");
730 field(w, 4, "s", &json!(e))?;
731 }
732 if let Some(r) = self.reply_serial {
733 field(w, 5, "u", &json!(r))?;
734 }
735 if let Some(d) = &self.destination {
736 ensure!(valid_bus_name(d), "{d:?} is not a D-Bus bus name");
737 field(w, 6, "s", &json!(d))?;
738 }
739 if let Some(s) = &self.sender {
740 field(w, 7, "s", &json!(s))?;
741 }
742 if !self.signature.is_empty() {
743 field(w, 8, "g", &json!(self.signature))?;
744 }
745 Ok(())
746 })?;
747 w.pad(8);
748 w.buf.extend(body);
749 ensure!(
750 w.buf.len() <= MAX_MESSAGE_BYTES,
751 "the message exceeds {MAX_MESSAGE_BYTES} bytes"
752 );
753 Ok(w.buf)
754 }
755}
756
757pub async fn read_message<Rd: AsyncRead + Unpin>(r: &mut Rd) -> Result<Option<Message>> {
760 let mut head = [0u8; 16];
761 match r.read_exact(&mut head).await {
762 Ok(_) => {}
763 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(None),
764 Err(e) => return Err(e.into()),
765 }
766 let big = match head[0] {
767 b'l' => false,
768 b'B' => true,
769 other => bail!("{other:#04x} is not a D-Bus byte-order mark"),
770 };
771 ensure!(head[3] == 1, "D-Bus protocol version {} is not 1", head[3]);
772 let word = |at: usize| {
773 let a = [head[at], head[at + 1], head[at + 2], head[at + 3]];
774 (if big {
775 u32::from_be_bytes(a)
776 } else {
777 u32::from_le_bytes(a)
778 }) as usize
779 };
780 let (body_len, fields_len) = (word(4), word(12));
781 let total = 16usize.saturating_add(fields_len).saturating_add(7) / 8 * 8;
782 let total = total.saturating_add(body_len);
783 ensure!(
784 total <= MAX_MESSAGE_BYTES,
785 "the peer announced a {total}-byte message; the bound is {MAX_MESSAGE_BYTES}"
786 );
787 let mut buf = head.to_vec();
788 buf.resize(total, 0);
789 r.read_exact(&mut buf[16..]).await?;
790 decode(&buf).map(Some)
791}
792
793pub fn decode(buf: &[u8]) -> Result<Message> {
794 let big = buf[0] == b'B';
795 let mut r = R {
796 b: buf,
797 pos: 4,
798 big,
799 };
800 let body_len = r.u32()? as usize;
801 let serial = r.u32()?;
802 ensure!(serial != 0, "a message's serial is never 0");
803 let mut m = Message {
804 kind: buf[1],
805 flags: buf[2],
806 serial,
807 ..Default::default()
808 };
809 let fields_end = r.array_end(8)?;
810 while r.pos < fields_end {
811 r.align(8)?;
812 let code = r.take(1)?[0];
813 let sig = r.sig()?;
814 let tys = parse_signature(&sig)?;
815 ensure!(tys.len() == 1, "a header field holds one complete type");
816 let v = r.get(&tys[0], 1)?;
817 let s = || {
818 v.as_str()
819 .map(str::to_string)
820 .context("a header field has the wrong type")
821 };
822 match (code, sig.as_str()) {
823 (1, "o") => m.path = Some(s()?),
824 (2, "s") => m.interface = Some(s()?),
825 (3, "s") => m.member = Some(s()?),
826 (4, "s") => m.error_name = Some(s()?),
827 (5, "u") => m.reply_serial = v.as_u64().map(|n| n as u32),
828 (6, "s") => m.destination = Some(s()?),
829 (7, "s") => m.sender = Some(s()?),
830 (8, "g") => m.signature = s()?,
831 (9, "u") => ensure!(
832 v.as_u64() == Some(0),
833 "NetGet does not accept Unix file descriptors"
834 ),
835 (1..=9, other) => bail!("header field {code} has type {other:?}"),
836 _ => {} }
838 }
839 ensure!(
840 r.pos == fields_end,
841 "the header fields overrun their length"
842 );
843 r.align(8)?;
844 ensure!(
845 buf.len() - r.pos == body_len,
846 "the body is not the announced {body_len} bytes"
847 );
848 match m.kind {
849 METHOD_CALL => ensure!(
850 m.path.is_some() && m.member.is_some(),
851 "a method call needs a path and a member"
852 ),
853 METHOD_RETURN => ensure!(
854 m.reply_serial.is_some(),
855 "a method return needs a reply serial"
856 ),
857 ERROR => ensure!(
858 m.error_name.is_some() && m.reply_serial.is_some(),
859 "an error needs a name and a reply serial"
860 ),
861 SIGNAL => ensure!(
862 m.path.is_some() && m.interface.is_some() && m.member.is_some(),
863 "a signal needs a path, an interface and a member"
864 ),
865 _ => {} }
867 for ty in parse_signature(&m.signature)? {
868 m.body.push(r.get(&ty, 0)?);
869 }
870 ensure!(
871 r.pos == buf.len(),
872 "the body has bytes its signature does not account for"
873 );
874 Ok(m)
875}
876
877pub async fn read_auth_line<B: AsyncBufRead + Unpin>(r: &mut B) -> Result<String> {
879 let mut line = Vec::new();
880 loop {
881 let chunk = r.fill_buf().await?;
882 ensure!(
883 !chunk.is_empty(),
884 "the peer closed the connection during authentication"
885 );
886 match chunk.iter().position(|b| *b == b'\n') {
887 Some(i) => {
888 line.extend(&chunk[..=i]);
889 r.consume(i + 1);
890 break;
891 }
892 None => {
893 let n = chunk.len();
894 line.extend_from_slice(chunk);
895 r.consume(n);
896 }
897 }
898 ensure!(
899 line.len() <= MAX_AUTH_LINE,
900 "an authentication line exceeds {MAX_AUTH_LINE} bytes"
901 );
902 }
903 ensure!(
904 line.len() <= MAX_AUTH_LINE,
905 "an authentication line exceeds {MAX_AUTH_LINE} bytes"
906 );
907 let text = String::from_utf8(line).context("an authentication line is not ASCII")?;
908 Ok(text.trim_end_matches(['\r', '\n']).to_string())
909}
910
911pub fn hex_ascii(s: &str) -> String {
913 hex::encode(s.as_bytes())
914}
915
916pub fn random_guid() -> String {
917 hex::encode(rand::random::<[u8; 16]>())
918}