1#![doc = "Netlink protocol to request a transport layer security handshake\\."]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "handshake";
17pub const PROTONAME_CSTR: &CStr = c"handshake";
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum HandlerClass {
21 None = 0,
22 Tlshd = 1,
23 Max = 2,
24}
25impl HandlerClass {
26 pub fn from_value(value: u64) -> Option<Self> {
27 Some(match value {
28 0 => Self::None,
29 1 => Self::Tlshd,
30 2 => Self::Max,
31 _ => return None,
32 })
33 }
34}
35#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
36#[derive(Debug, Clone, Copy)]
37pub enum MsgType {
38 Unspec = 0,
39 Clienthello = 1,
40 Serverhello = 2,
41}
42impl MsgType {
43 pub fn from_value(value: u64) -> Option<Self> {
44 Some(match value {
45 0 => Self::Unspec,
46 1 => Self::Clienthello,
47 2 => Self::Serverhello,
48 _ => return None,
49 })
50 }
51}
52#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
53#[derive(Debug, Clone, Copy)]
54pub enum Auth {
55 Unspec = 0,
56 Unauth = 1,
57 Psk = 2,
58 X509 = 3,
59}
60impl Auth {
61 pub fn from_value(value: u64) -> Option<Self> {
62 Some(match value {
63 0 => Self::Unspec,
64 1 => Self::Unauth,
65 2 => Self::Psk,
66 3 => Self::X509,
67 _ => return None,
68 })
69 }
70}
71#[derive(Clone)]
72pub enum X509 {
73 Cert(i32),
74 Privkey(i32),
75}
76impl<'a> IterableX509<'a> {
77 pub fn get_cert(&self) -> Result<i32, ErrorContext> {
78 let mut iter = self.clone();
79 iter.pos = 0;
80 for attr in iter {
81 if let X509::Cert(val) = attr? {
82 return Ok(val);
83 }
84 }
85 Err(ErrorContext::new_missing(
86 "X509",
87 "Cert",
88 self.orig_loc,
89 self.buf.as_ptr() as usize,
90 ))
91 }
92 pub fn get_privkey(&self) -> Result<i32, ErrorContext> {
93 let mut iter = self.clone();
94 iter.pos = 0;
95 for attr in iter {
96 if let X509::Privkey(val) = attr? {
97 return Ok(val);
98 }
99 }
100 Err(ErrorContext::new_missing(
101 "X509",
102 "Privkey",
103 self.orig_loc,
104 self.buf.as_ptr() as usize,
105 ))
106 }
107}
108impl X509 {
109 pub fn new<'a>(buf: &'a [u8]) -> IterableX509<'a> {
110 IterableX509::with_loc(buf, buf.as_ptr() as usize)
111 }
112 fn attr_from_type(r#type: u16) -> Option<&'static str> {
113 let res = match r#type {
114 1u16 => "Cert",
115 2u16 => "Privkey",
116 _ => return None,
117 };
118 Some(res)
119 }
120}
121#[derive(Clone, Copy, Default)]
122pub struct IterableX509<'a> {
123 buf: &'a [u8],
124 pos: usize,
125 orig_loc: usize,
126}
127impl<'a> IterableX509<'a> {
128 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
129 Self {
130 buf,
131 pos: 0,
132 orig_loc,
133 }
134 }
135 pub fn get_buf(&self) -> &'a [u8] {
136 self.buf
137 }
138}
139impl<'a> Iterator for IterableX509<'a> {
140 type Item = Result<X509, ErrorContext>;
141 fn next(&mut self) -> Option<Self::Item> {
142 let pos = self.pos;
143 let mut r#type;
144 loop {
145 r#type = None;
146 if self.buf.len() == self.pos {
147 return None;
148 }
149 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
150 break;
151 };
152 r#type = Some(header.r#type);
153 let res = match header.r#type {
154 1u16 => X509::Cert({
155 let res = parse_i32(next);
156 let Some(val) = res else { break };
157 val
158 }),
159 2u16 => X509::Privkey({
160 let res = parse_i32(next);
161 let Some(val) = res else { break };
162 val
163 }),
164 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
165 n => continue,
166 };
167 return Some(Ok(res));
168 }
169 Some(Err(ErrorContext::new(
170 "X509",
171 r#type.and_then(|t| X509::attr_from_type(t)),
172 self.orig_loc,
173 self.buf.as_ptr().wrapping_add(pos) as usize,
174 )))
175 }
176}
177impl std::fmt::Debug for IterableX509<'_> {
178 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179 let mut fmt = f.debug_struct("X509");
180 for attr in self.clone() {
181 let attr = match attr {
182 Ok(a) => a,
183 Err(err) => {
184 fmt.finish()?;
185 f.write_str("Err(")?;
186 err.fmt(f)?;
187 return f.write_str(")");
188 }
189 };
190 match attr {
191 X509::Cert(val) => fmt.field("Cert", &val),
192 X509::Privkey(val) => fmt.field("Privkey", &val),
193 };
194 }
195 fmt.finish()
196 }
197}
198impl IterableX509<'_> {
199 pub fn lookup_attr(
200 &self,
201 offset: usize,
202 missing_type: Option<u16>,
203 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
204 let mut stack = Vec::new();
205 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
206 if missing_type.is_some() && cur == offset {
207 stack.push(("X509", offset));
208 return (stack, missing_type.and_then(|t| X509::attr_from_type(t)));
209 }
210 if cur > offset || cur + self.buf.len() < offset {
211 return (stack, None);
212 }
213 let mut attrs = self.clone();
214 let mut last_off = cur + attrs.pos;
215 while let Some(attr) = attrs.next() {
216 let Ok(attr) = attr else { break };
217 match attr {
218 X509::Cert(val) => {
219 if last_off == offset {
220 stack.push(("Cert", last_off));
221 break;
222 }
223 }
224 X509::Privkey(val) => {
225 if last_off == offset {
226 stack.push(("Privkey", last_off));
227 break;
228 }
229 }
230 _ => {}
231 };
232 last_off = cur + attrs.pos;
233 }
234 if !stack.is_empty() {
235 stack.push(("X509", cur));
236 }
237 (stack, None)
238 }
239}
240#[derive(Clone)]
241pub enum Accept<'a> {
242 Sockfd(i32),
243 #[doc = "Associated type: [`HandlerClass`] (enum)"]
244 HandlerClass(u32),
245 #[doc = "Associated type: [`MsgType`] (enum)"]
246 MessageType(u32),
247 Timeout(u32),
248 #[doc = "Associated type: [`Auth`] (enum)"]
249 AuthMode(u32),
250 #[doc = "Attribute may repeat multiple times (treat it as array)"]
251 PeerIdentity(u32),
252 #[doc = "Attribute may repeat multiple times (treat it as array)"]
253 Certificate(IterableX509<'a>),
254 Peername(&'a CStr),
255 Keyring(u32),
256}
257impl<'a> IterableAccept<'a> {
258 pub fn get_sockfd(&self) -> Result<i32, ErrorContext> {
259 let mut iter = self.clone();
260 iter.pos = 0;
261 for attr in iter {
262 if let Accept::Sockfd(val) = attr? {
263 return Ok(val);
264 }
265 }
266 Err(ErrorContext::new_missing(
267 "Accept",
268 "Sockfd",
269 self.orig_loc,
270 self.buf.as_ptr() as usize,
271 ))
272 }
273 #[doc = "Associated type: [`HandlerClass`] (enum)"]
274 pub fn get_handler_class(&self) -> Result<u32, ErrorContext> {
275 let mut iter = self.clone();
276 iter.pos = 0;
277 for attr in iter {
278 if let Accept::HandlerClass(val) = attr? {
279 return Ok(val);
280 }
281 }
282 Err(ErrorContext::new_missing(
283 "Accept",
284 "HandlerClass",
285 self.orig_loc,
286 self.buf.as_ptr() as usize,
287 ))
288 }
289 #[doc = "Associated type: [`MsgType`] (enum)"]
290 pub fn get_message_type(&self) -> Result<u32, ErrorContext> {
291 let mut iter = self.clone();
292 iter.pos = 0;
293 for attr in iter {
294 if let Accept::MessageType(val) = attr? {
295 return Ok(val);
296 }
297 }
298 Err(ErrorContext::new_missing(
299 "Accept",
300 "MessageType",
301 self.orig_loc,
302 self.buf.as_ptr() as usize,
303 ))
304 }
305 pub fn get_timeout(&self) -> Result<u32, ErrorContext> {
306 let mut iter = self.clone();
307 iter.pos = 0;
308 for attr in iter {
309 if let Accept::Timeout(val) = attr? {
310 return Ok(val);
311 }
312 }
313 Err(ErrorContext::new_missing(
314 "Accept",
315 "Timeout",
316 self.orig_loc,
317 self.buf.as_ptr() as usize,
318 ))
319 }
320 #[doc = "Associated type: [`Auth`] (enum)"]
321 pub fn get_auth_mode(&self) -> Result<u32, ErrorContext> {
322 let mut iter = self.clone();
323 iter.pos = 0;
324 for attr in iter {
325 if let Accept::AuthMode(val) = attr? {
326 return Ok(val);
327 }
328 }
329 Err(ErrorContext::new_missing(
330 "Accept",
331 "AuthMode",
332 self.orig_loc,
333 self.buf.as_ptr() as usize,
334 ))
335 }
336 #[doc = "Attribute may repeat multiple times (treat it as array)"]
337 pub fn get_peer_identity(&self) -> MultiAttrIterable<Self, Accept<'a>, u32> {
338 MultiAttrIterable::new(self.clone(), |variant| {
339 if let Accept::PeerIdentity(val) = variant {
340 Some(val)
341 } else {
342 None
343 }
344 })
345 }
346 #[doc = "Attribute may repeat multiple times (treat it as array)"]
347 pub fn get_certificate(&self) -> MultiAttrIterable<Self, Accept<'a>, IterableX509<'a>> {
348 MultiAttrIterable::new(self.clone(), |variant| {
349 if let Accept::Certificate(val) = variant {
350 Some(val)
351 } else {
352 None
353 }
354 })
355 }
356 pub fn get_peername(&self) -> Result<&'a CStr, ErrorContext> {
357 let mut iter = self.clone();
358 iter.pos = 0;
359 for attr in iter {
360 if let Accept::Peername(val) = attr? {
361 return Ok(val);
362 }
363 }
364 Err(ErrorContext::new_missing(
365 "Accept",
366 "Peername",
367 self.orig_loc,
368 self.buf.as_ptr() as usize,
369 ))
370 }
371 pub fn get_keyring(&self) -> Result<u32, ErrorContext> {
372 let mut iter = self.clone();
373 iter.pos = 0;
374 for attr in iter {
375 if let Accept::Keyring(val) = attr? {
376 return Ok(val);
377 }
378 }
379 Err(ErrorContext::new_missing(
380 "Accept",
381 "Keyring",
382 self.orig_loc,
383 self.buf.as_ptr() as usize,
384 ))
385 }
386}
387impl Accept<'_> {
388 pub fn new<'a>(buf: &'a [u8]) -> IterableAccept<'a> {
389 IterableAccept::with_loc(buf, buf.as_ptr() as usize)
390 }
391 fn attr_from_type(r#type: u16) -> Option<&'static str> {
392 let res = match r#type {
393 1u16 => "Sockfd",
394 2u16 => "HandlerClass",
395 3u16 => "MessageType",
396 4u16 => "Timeout",
397 5u16 => "AuthMode",
398 6u16 => "PeerIdentity",
399 7u16 => "Certificate",
400 8u16 => "Peername",
401 9u16 => "Keyring",
402 _ => return None,
403 };
404 Some(res)
405 }
406}
407#[derive(Clone, Copy, Default)]
408pub struct IterableAccept<'a> {
409 buf: &'a [u8],
410 pos: usize,
411 orig_loc: usize,
412}
413impl<'a> IterableAccept<'a> {
414 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
415 Self {
416 buf,
417 pos: 0,
418 orig_loc,
419 }
420 }
421 pub fn get_buf(&self) -> &'a [u8] {
422 self.buf
423 }
424}
425impl<'a> Iterator for IterableAccept<'a> {
426 type Item = Result<Accept<'a>, ErrorContext>;
427 fn next(&mut self) -> Option<Self::Item> {
428 let pos = self.pos;
429 let mut r#type;
430 loop {
431 r#type = None;
432 if self.buf.len() == self.pos {
433 return None;
434 }
435 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
436 break;
437 };
438 r#type = Some(header.r#type);
439 let res = match header.r#type {
440 1u16 => Accept::Sockfd({
441 let res = parse_i32(next);
442 let Some(val) = res else { break };
443 val
444 }),
445 2u16 => Accept::HandlerClass({
446 let res = parse_u32(next);
447 let Some(val) = res else { break };
448 val
449 }),
450 3u16 => Accept::MessageType({
451 let res = parse_u32(next);
452 let Some(val) = res else { break };
453 val
454 }),
455 4u16 => Accept::Timeout({
456 let res = parse_u32(next);
457 let Some(val) = res else { break };
458 val
459 }),
460 5u16 => Accept::AuthMode({
461 let res = parse_u32(next);
462 let Some(val) = res else { break };
463 val
464 }),
465 6u16 => Accept::PeerIdentity({
466 let res = parse_u32(next);
467 let Some(val) = res else { break };
468 val
469 }),
470 7u16 => Accept::Certificate({
471 let res = Some(IterableX509::with_loc(next, self.orig_loc));
472 let Some(val) = res else { break };
473 val
474 }),
475 8u16 => Accept::Peername({
476 let res = CStr::from_bytes_with_nul(next).ok();
477 let Some(val) = res else { break };
478 val
479 }),
480 9u16 => Accept::Keyring({
481 let res = parse_u32(next);
482 let Some(val) = res else { break };
483 val
484 }),
485 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
486 n => continue,
487 };
488 return Some(Ok(res));
489 }
490 Some(Err(ErrorContext::new(
491 "Accept",
492 r#type.and_then(|t| Accept::attr_from_type(t)),
493 self.orig_loc,
494 self.buf.as_ptr().wrapping_add(pos) as usize,
495 )))
496 }
497}
498impl<'a> std::fmt::Debug for IterableAccept<'_> {
499 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
500 let mut fmt = f.debug_struct("Accept");
501 for attr in self.clone() {
502 let attr = match attr {
503 Ok(a) => a,
504 Err(err) => {
505 fmt.finish()?;
506 f.write_str("Err(")?;
507 err.fmt(f)?;
508 return f.write_str(")");
509 }
510 };
511 match attr {
512 Accept::Sockfd(val) => fmt.field("Sockfd", &val),
513 Accept::HandlerClass(val) => fmt.field(
514 "HandlerClass",
515 &FormatEnum(val.into(), HandlerClass::from_value),
516 ),
517 Accept::MessageType(val) => {
518 fmt.field("MessageType", &FormatEnum(val.into(), MsgType::from_value))
519 }
520 Accept::Timeout(val) => fmt.field("Timeout", &val),
521 Accept::AuthMode(val) => {
522 fmt.field("AuthMode", &FormatEnum(val.into(), Auth::from_value))
523 }
524 Accept::PeerIdentity(val) => fmt.field("PeerIdentity", &val),
525 Accept::Certificate(val) => fmt.field("Certificate", &val),
526 Accept::Peername(val) => fmt.field("Peername", &val),
527 Accept::Keyring(val) => fmt.field("Keyring", &val),
528 };
529 }
530 fmt.finish()
531 }
532}
533impl IterableAccept<'_> {
534 pub fn lookup_attr(
535 &self,
536 offset: usize,
537 missing_type: Option<u16>,
538 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
539 let mut stack = Vec::new();
540 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
541 if missing_type.is_some() && cur == offset {
542 stack.push(("Accept", offset));
543 return (stack, missing_type.and_then(|t| Accept::attr_from_type(t)));
544 }
545 if cur > offset || cur + self.buf.len() < offset {
546 return (stack, None);
547 }
548 let mut attrs = self.clone();
549 let mut last_off = cur + attrs.pos;
550 let mut missing = None;
551 while let Some(attr) = attrs.next() {
552 let Ok(attr) = attr else { break };
553 match attr {
554 Accept::Sockfd(val) => {
555 if last_off == offset {
556 stack.push(("Sockfd", last_off));
557 break;
558 }
559 }
560 Accept::HandlerClass(val) => {
561 if last_off == offset {
562 stack.push(("HandlerClass", last_off));
563 break;
564 }
565 }
566 Accept::MessageType(val) => {
567 if last_off == offset {
568 stack.push(("MessageType", last_off));
569 break;
570 }
571 }
572 Accept::Timeout(val) => {
573 if last_off == offset {
574 stack.push(("Timeout", last_off));
575 break;
576 }
577 }
578 Accept::AuthMode(val) => {
579 if last_off == offset {
580 stack.push(("AuthMode", last_off));
581 break;
582 }
583 }
584 Accept::PeerIdentity(val) => {
585 if last_off == offset {
586 stack.push(("PeerIdentity", last_off));
587 break;
588 }
589 }
590 Accept::Certificate(val) => {
591 (stack, missing) = val.lookup_attr(offset, missing_type);
592 if !stack.is_empty() {
593 break;
594 }
595 }
596 Accept::Peername(val) => {
597 if last_off == offset {
598 stack.push(("Peername", last_off));
599 break;
600 }
601 }
602 Accept::Keyring(val) => {
603 if last_off == offset {
604 stack.push(("Keyring", last_off));
605 break;
606 }
607 }
608 _ => {}
609 };
610 last_off = cur + attrs.pos;
611 }
612 if !stack.is_empty() {
613 stack.push(("Accept", cur));
614 }
615 (stack, missing)
616 }
617}
618#[derive(Clone)]
619pub enum Done {
620 Status(u32),
621 Sockfd(i32),
622 #[doc = "Attribute may repeat multiple times (treat it as array)"]
623 RemoteAuth(u32),
624}
625impl<'a> IterableDone<'a> {
626 pub fn get_status(&self) -> Result<u32, ErrorContext> {
627 let mut iter = self.clone();
628 iter.pos = 0;
629 for attr in iter {
630 if let Done::Status(val) = attr? {
631 return Ok(val);
632 }
633 }
634 Err(ErrorContext::new_missing(
635 "Done",
636 "Status",
637 self.orig_loc,
638 self.buf.as_ptr() as usize,
639 ))
640 }
641 pub fn get_sockfd(&self) -> Result<i32, ErrorContext> {
642 let mut iter = self.clone();
643 iter.pos = 0;
644 for attr in iter {
645 if let Done::Sockfd(val) = attr? {
646 return Ok(val);
647 }
648 }
649 Err(ErrorContext::new_missing(
650 "Done",
651 "Sockfd",
652 self.orig_loc,
653 self.buf.as_ptr() as usize,
654 ))
655 }
656 #[doc = "Attribute may repeat multiple times (treat it as array)"]
657 pub fn get_remote_auth(&self) -> MultiAttrIterable<Self, Done, u32> {
658 MultiAttrIterable::new(self.clone(), |variant| {
659 if let Done::RemoteAuth(val) = variant {
660 Some(val)
661 } else {
662 None
663 }
664 })
665 }
666}
667impl Done {
668 pub fn new<'a>(buf: &'a [u8]) -> IterableDone<'a> {
669 IterableDone::with_loc(buf, buf.as_ptr() as usize)
670 }
671 fn attr_from_type(r#type: u16) -> Option<&'static str> {
672 let res = match r#type {
673 1u16 => "Status",
674 2u16 => "Sockfd",
675 3u16 => "RemoteAuth",
676 _ => return None,
677 };
678 Some(res)
679 }
680}
681#[derive(Clone, Copy, Default)]
682pub struct IterableDone<'a> {
683 buf: &'a [u8],
684 pos: usize,
685 orig_loc: usize,
686}
687impl<'a> IterableDone<'a> {
688 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
689 Self {
690 buf,
691 pos: 0,
692 orig_loc,
693 }
694 }
695 pub fn get_buf(&self) -> &'a [u8] {
696 self.buf
697 }
698}
699impl<'a> Iterator for IterableDone<'a> {
700 type Item = Result<Done, ErrorContext>;
701 fn next(&mut self) -> Option<Self::Item> {
702 let pos = self.pos;
703 let mut r#type;
704 loop {
705 r#type = None;
706 if self.buf.len() == self.pos {
707 return None;
708 }
709 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
710 break;
711 };
712 r#type = Some(header.r#type);
713 let res = match header.r#type {
714 1u16 => Done::Status({
715 let res = parse_u32(next);
716 let Some(val) = res else { break };
717 val
718 }),
719 2u16 => Done::Sockfd({
720 let res = parse_i32(next);
721 let Some(val) = res else { break };
722 val
723 }),
724 3u16 => Done::RemoteAuth({
725 let res = parse_u32(next);
726 let Some(val) = res else { break };
727 val
728 }),
729 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
730 n => continue,
731 };
732 return Some(Ok(res));
733 }
734 Some(Err(ErrorContext::new(
735 "Done",
736 r#type.and_then(|t| Done::attr_from_type(t)),
737 self.orig_loc,
738 self.buf.as_ptr().wrapping_add(pos) as usize,
739 )))
740 }
741}
742impl std::fmt::Debug for IterableDone<'_> {
743 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
744 let mut fmt = f.debug_struct("Done");
745 for attr in self.clone() {
746 let attr = match attr {
747 Ok(a) => a,
748 Err(err) => {
749 fmt.finish()?;
750 f.write_str("Err(")?;
751 err.fmt(f)?;
752 return f.write_str(")");
753 }
754 };
755 match attr {
756 Done::Status(val) => fmt.field("Status", &val),
757 Done::Sockfd(val) => fmt.field("Sockfd", &val),
758 Done::RemoteAuth(val) => fmt.field("RemoteAuth", &val),
759 };
760 }
761 fmt.finish()
762 }
763}
764impl IterableDone<'_> {
765 pub fn lookup_attr(
766 &self,
767 offset: usize,
768 missing_type: Option<u16>,
769 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
770 let mut stack = Vec::new();
771 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
772 if missing_type.is_some() && cur == offset {
773 stack.push(("Done", offset));
774 return (stack, missing_type.and_then(|t| Done::attr_from_type(t)));
775 }
776 if cur > offset || cur + self.buf.len() < offset {
777 return (stack, None);
778 }
779 let mut attrs = self.clone();
780 let mut last_off = cur + attrs.pos;
781 while let Some(attr) = attrs.next() {
782 let Ok(attr) = attr else { break };
783 match attr {
784 Done::Status(val) => {
785 if last_off == offset {
786 stack.push(("Status", last_off));
787 break;
788 }
789 }
790 Done::Sockfd(val) => {
791 if last_off == offset {
792 stack.push(("Sockfd", last_off));
793 break;
794 }
795 }
796 Done::RemoteAuth(val) => {
797 if last_off == offset {
798 stack.push(("RemoteAuth", last_off));
799 break;
800 }
801 }
802 _ => {}
803 };
804 last_off = cur + attrs.pos;
805 }
806 if !stack.is_empty() {
807 stack.push(("Done", cur));
808 }
809 (stack, None)
810 }
811}
812pub struct PushX509<Prev: Rec> {
813 pub(crate) prev: Option<Prev>,
814 pub(crate) header_offset: Option<usize>,
815}
816impl<Prev: Rec> Rec for PushX509<Prev> {
817 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
818 self.prev.as_mut().unwrap().as_rec_mut()
819 }
820 fn as_rec(&self) -> &Vec<u8> {
821 self.prev.as_ref().unwrap().as_rec()
822 }
823}
824impl<Prev: Rec> PushX509<Prev> {
825 pub fn new(prev: Prev) -> Self {
826 Self {
827 prev: Some(prev),
828 header_offset: None,
829 }
830 }
831 pub fn end_nested(mut self) -> Prev {
832 let mut prev = self.prev.take().unwrap();
833 if let Some(header_offset) = &self.header_offset {
834 finalize_nested_header(prev.as_rec_mut(), *header_offset);
835 }
836 prev
837 }
838 pub fn push_cert(mut self, value: i32) -> Self {
839 push_header(self.as_rec_mut(), 1u16, 4 as u16);
840 self.as_rec_mut().extend(value.to_ne_bytes());
841 self
842 }
843 pub fn push_privkey(mut self, value: i32) -> Self {
844 push_header(self.as_rec_mut(), 2u16, 4 as u16);
845 self.as_rec_mut().extend(value.to_ne_bytes());
846 self
847 }
848}
849impl<Prev: Rec> Drop for PushX509<Prev> {
850 fn drop(&mut self) {
851 if let Some(prev) = &mut self.prev {
852 if let Some(header_offset) = &self.header_offset {
853 finalize_nested_header(prev.as_rec_mut(), *header_offset);
854 }
855 }
856 }
857}
858pub struct PushAccept<Prev: Rec> {
859 pub(crate) prev: Option<Prev>,
860 pub(crate) header_offset: Option<usize>,
861}
862impl<Prev: Rec> Rec for PushAccept<Prev> {
863 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
864 self.prev.as_mut().unwrap().as_rec_mut()
865 }
866 fn as_rec(&self) -> &Vec<u8> {
867 self.prev.as_ref().unwrap().as_rec()
868 }
869}
870impl<Prev: Rec> PushAccept<Prev> {
871 pub fn new(prev: Prev) -> Self {
872 Self {
873 prev: Some(prev),
874 header_offset: None,
875 }
876 }
877 pub fn end_nested(mut self) -> Prev {
878 let mut prev = self.prev.take().unwrap();
879 if let Some(header_offset) = &self.header_offset {
880 finalize_nested_header(prev.as_rec_mut(), *header_offset);
881 }
882 prev
883 }
884 pub fn push_sockfd(mut self, value: i32) -> Self {
885 push_header(self.as_rec_mut(), 1u16, 4 as u16);
886 self.as_rec_mut().extend(value.to_ne_bytes());
887 self
888 }
889 #[doc = "Associated type: [`HandlerClass`] (enum)"]
890 pub fn push_handler_class(mut self, value: u32) -> Self {
891 push_header(self.as_rec_mut(), 2u16, 4 as u16);
892 self.as_rec_mut().extend(value.to_ne_bytes());
893 self
894 }
895 #[doc = "Associated type: [`MsgType`] (enum)"]
896 pub fn push_message_type(mut self, value: u32) -> Self {
897 push_header(self.as_rec_mut(), 3u16, 4 as u16);
898 self.as_rec_mut().extend(value.to_ne_bytes());
899 self
900 }
901 pub fn push_timeout(mut self, value: u32) -> Self {
902 push_header(self.as_rec_mut(), 4u16, 4 as u16);
903 self.as_rec_mut().extend(value.to_ne_bytes());
904 self
905 }
906 #[doc = "Associated type: [`Auth`] (enum)"]
907 pub fn push_auth_mode(mut self, value: u32) -> Self {
908 push_header(self.as_rec_mut(), 5u16, 4 as u16);
909 self.as_rec_mut().extend(value.to_ne_bytes());
910 self
911 }
912 #[doc = "Attribute may repeat multiple times (treat it as array)"]
913 pub fn push_peer_identity(mut self, value: u32) -> Self {
914 push_header(self.as_rec_mut(), 6u16, 4 as u16);
915 self.as_rec_mut().extend(value.to_ne_bytes());
916 self
917 }
918 #[doc = "Attribute may repeat multiple times (treat it as array)"]
919 pub fn nested_certificate(mut self) -> PushX509<Self> {
920 let header_offset = push_nested_header(self.as_rec_mut(), 7u16);
921 PushX509 {
922 prev: Some(self),
923 header_offset: Some(header_offset),
924 }
925 }
926 pub fn push_peername(mut self, value: &CStr) -> Self {
927 push_header(
928 self.as_rec_mut(),
929 8u16,
930 value.to_bytes_with_nul().len() as u16,
931 );
932 self.as_rec_mut().extend(value.to_bytes_with_nul());
933 self
934 }
935 pub fn push_peername_bytes(mut self, value: &[u8]) -> Self {
936 push_header(self.as_rec_mut(), 8u16, (value.len() + 1) as u16);
937 self.as_rec_mut().extend(value);
938 self.as_rec_mut().push(0);
939 self
940 }
941 pub fn push_keyring(mut self, value: u32) -> Self {
942 push_header(self.as_rec_mut(), 9u16, 4 as u16);
943 self.as_rec_mut().extend(value.to_ne_bytes());
944 self
945 }
946}
947impl<Prev: Rec> Drop for PushAccept<Prev> {
948 fn drop(&mut self) {
949 if let Some(prev) = &mut self.prev {
950 if let Some(header_offset) = &self.header_offset {
951 finalize_nested_header(prev.as_rec_mut(), *header_offset);
952 }
953 }
954 }
955}
956pub struct PushDone<Prev: Rec> {
957 pub(crate) prev: Option<Prev>,
958 pub(crate) header_offset: Option<usize>,
959}
960impl<Prev: Rec> Rec for PushDone<Prev> {
961 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
962 self.prev.as_mut().unwrap().as_rec_mut()
963 }
964 fn as_rec(&self) -> &Vec<u8> {
965 self.prev.as_ref().unwrap().as_rec()
966 }
967}
968impl<Prev: Rec> PushDone<Prev> {
969 pub fn new(prev: Prev) -> Self {
970 Self {
971 prev: Some(prev),
972 header_offset: None,
973 }
974 }
975 pub fn end_nested(mut self) -> Prev {
976 let mut prev = self.prev.take().unwrap();
977 if let Some(header_offset) = &self.header_offset {
978 finalize_nested_header(prev.as_rec_mut(), *header_offset);
979 }
980 prev
981 }
982 pub fn push_status(mut self, value: u32) -> Self {
983 push_header(self.as_rec_mut(), 1u16, 4 as u16);
984 self.as_rec_mut().extend(value.to_ne_bytes());
985 self
986 }
987 pub fn push_sockfd(mut self, value: i32) -> Self {
988 push_header(self.as_rec_mut(), 2u16, 4 as u16);
989 self.as_rec_mut().extend(value.to_ne_bytes());
990 self
991 }
992 #[doc = "Attribute may repeat multiple times (treat it as array)"]
993 pub fn push_remote_auth(mut self, value: u32) -> Self {
994 push_header(self.as_rec_mut(), 3u16, 4 as u16);
995 self.as_rec_mut().extend(value.to_ne_bytes());
996 self
997 }
998}
999impl<Prev: Rec> Drop for PushDone<Prev> {
1000 fn drop(&mut self) {
1001 if let Some(prev) = &mut self.prev {
1002 if let Some(header_offset) = &self.header_offset {
1003 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1004 }
1005 }
1006 }
1007}
1008pub struct NotifGroup;
1009impl NotifGroup {
1010 pub const NONE: &str = "none";
1011 pub const NONE_CSTR: &CStr = c"none";
1012 pub const TLSHD: &str = "tlshd";
1013 pub const TLSHD_CSTR: &CStr = c"tlshd";
1014}
1015#[doc = "Handler retrieves next queued handshake request\nFlags: admin-perm\nRequest attributes:\n- [.push_handler_class()](PushAccept::push_handler_class)\n\nReply attributes:\n- [.get_sockfd()](IterableAccept::get_sockfd)\n- [.get_message_type()](IterableAccept::get_message_type)\n- [.get_timeout()](IterableAccept::get_timeout)\n- [.get_auth_mode()](IterableAccept::get_auth_mode)\n- [.get_peer_identity()](IterableAccept::get_peer_identity)\n- [.get_certificate()](IterableAccept::get_certificate)\n- [.get_peername()](IterableAccept::get_peername)\n- [.get_keyring()](IterableAccept::get_keyring)\n"]
1016#[derive(Debug)]
1017pub struct OpAcceptDo<'r> {
1018 request: Request<'r>,
1019}
1020impl<'r> OpAcceptDo<'r> {
1021 pub fn new(mut request: Request<'r>) -> Self {
1022 Self::write_header(request.buf_mut());
1023 Self { request: request }
1024 }
1025 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushAccept<&'buf mut Vec<u8>> {
1026 Self::write_header(buf);
1027 PushAccept::new(buf)
1028 }
1029 pub fn encode(&mut self) -> PushAccept<&mut Vec<u8>> {
1030 PushAccept::new(self.request.buf_mut())
1031 }
1032 pub fn into_encoder(self) -> PushAccept<RequestBuf<'r>> {
1033 PushAccept::new(self.request.buf)
1034 }
1035 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableAccept<'a> {
1036 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1037 IterableAccept::with_loc(attrs, buf.as_ptr() as usize)
1038 }
1039 fn write_header<Prev: Rec>(prev: &mut Prev) {
1040 let mut header = BuiltinNfgenmsg::new();
1041 header.cmd = 2u8;
1042 header.version = 1u8;
1043 prev.as_rec_mut().extend(header.as_slice());
1044 }
1045}
1046impl NetlinkRequest for OpAcceptDo<'_> {
1047 fn protocol(&self) -> Protocol {
1048 Protocol::Generic("handshake".as_bytes())
1049 }
1050 fn flags(&self) -> u16 {
1051 self.request.flags
1052 }
1053 fn payload(&self) -> &[u8] {
1054 self.request.buf()
1055 }
1056 type ReplyType<'buf> = IterableAccept<'buf>;
1057 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1058 Self::decode_request(buf)
1059 }
1060 fn lookup(
1061 buf: &[u8],
1062 offset: usize,
1063 missing_type: Option<u16>,
1064 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1065 Self::decode_request(buf).lookup_attr(offset, missing_type)
1066 }
1067}
1068#[doc = "Handler reports handshake completion\nRequest attributes:\n- [.push_status()](PushDone::push_status)\n- [.push_sockfd()](PushDone::push_sockfd)\n- [.push_remote_auth()](PushDone::push_remote_auth)\n"]
1069#[derive(Debug)]
1070pub struct OpDoneDo<'r> {
1071 request: Request<'r>,
1072}
1073impl<'r> OpDoneDo<'r> {
1074 pub fn new(mut request: Request<'r>) -> Self {
1075 Self::write_header(request.buf_mut());
1076 Self { request: request }
1077 }
1078 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDone<&'buf mut Vec<u8>> {
1079 Self::write_header(buf);
1080 PushDone::new(buf)
1081 }
1082 pub fn encode(&mut self) -> PushDone<&mut Vec<u8>> {
1083 PushDone::new(self.request.buf_mut())
1084 }
1085 pub fn into_encoder(self) -> PushDone<RequestBuf<'r>> {
1086 PushDone::new(self.request.buf)
1087 }
1088 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDone<'a> {
1089 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1090 IterableDone::with_loc(attrs, buf.as_ptr() as usize)
1091 }
1092 fn write_header<Prev: Rec>(prev: &mut Prev) {
1093 let mut header = BuiltinNfgenmsg::new();
1094 header.cmd = 3u8;
1095 header.version = 1u8;
1096 prev.as_rec_mut().extend(header.as_slice());
1097 }
1098}
1099impl NetlinkRequest for OpDoneDo<'_> {
1100 fn protocol(&self) -> Protocol {
1101 Protocol::Generic("handshake".as_bytes())
1102 }
1103 fn flags(&self) -> u16 {
1104 self.request.flags
1105 }
1106 fn payload(&self) -> &[u8] {
1107 self.request.buf()
1108 }
1109 type ReplyType<'buf> = IterableDone<'buf>;
1110 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1111 Self::decode_request(buf)
1112 }
1113 fn lookup(
1114 buf: &[u8],
1115 offset: usize,
1116 missing_type: Option<u16>,
1117 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1118 Self::decode_request(buf).lookup_attr(offset, missing_type)
1119 }
1120}
1121use crate::traits::LookupFn;
1122use crate::utils::RequestBuf;
1123#[derive(Debug)]
1124pub struct Request<'buf> {
1125 buf: RequestBuf<'buf>,
1126 flags: u16,
1127 writeback: Option<&'buf mut Option<RequestInfo>>,
1128}
1129#[allow(unused)]
1130#[derive(Debug, Clone)]
1131pub struct RequestInfo {
1132 protocol: Protocol,
1133 flags: u16,
1134 name: &'static str,
1135 lookup: LookupFn,
1136}
1137impl Request<'static> {
1138 pub fn new() -> Self {
1139 Self::new_from_buf(Vec::new())
1140 }
1141 pub fn new_from_buf(buf: Vec<u8>) -> Self {
1142 Self {
1143 flags: 0,
1144 buf: RequestBuf::Own(buf),
1145 writeback: None,
1146 }
1147 }
1148 pub fn into_buf(self) -> Vec<u8> {
1149 match self.buf {
1150 RequestBuf::Own(buf) => buf,
1151 _ => unreachable!(),
1152 }
1153 }
1154}
1155impl<'buf> Request<'buf> {
1156 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1157 buf.clear();
1158 Self::new_extend(buf)
1159 }
1160 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1161 Self {
1162 flags: 0,
1163 buf: RequestBuf::Ref(buf),
1164 writeback: None,
1165 }
1166 }
1167 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1168 let Some(writeback) = &mut self.writeback else {
1169 return;
1170 };
1171 **writeback = Some(RequestInfo {
1172 protocol,
1173 flags: self.flags,
1174 name,
1175 lookup,
1176 })
1177 }
1178 pub fn buf(&self) -> &Vec<u8> {
1179 self.buf.buf()
1180 }
1181 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1182 self.buf.buf_mut()
1183 }
1184 #[doc = "Set `NLM_F_CREATE` flag"]
1185 pub fn set_create(mut self) -> Self {
1186 self.flags |= consts::NLM_F_CREATE as u16;
1187 self
1188 }
1189 #[doc = "Set `NLM_F_EXCL` flag"]
1190 pub fn set_excl(mut self) -> Self {
1191 self.flags |= consts::NLM_F_EXCL as u16;
1192 self
1193 }
1194 #[doc = "Set `NLM_F_REPLACE` flag"]
1195 pub fn set_replace(mut self) -> Self {
1196 self.flags |= consts::NLM_F_REPLACE as u16;
1197 self
1198 }
1199 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1200 pub fn set_change(self) -> Self {
1201 self.set_create().set_replace()
1202 }
1203 #[doc = "Set `NLM_F_APPEND` flag"]
1204 pub fn set_append(mut self) -> Self {
1205 self.flags |= consts::NLM_F_APPEND as u16;
1206 self
1207 }
1208 #[doc = "Set `self.flags |= flags`"]
1209 pub fn set_flags(mut self, flags: u16) -> Self {
1210 self.flags |= flags;
1211 self
1212 }
1213 #[doc = "Set `self.flags ^= self.flags & flags`"]
1214 pub fn unset_flags(mut self, flags: u16) -> Self {
1215 self.flags ^= self.flags & flags;
1216 self
1217 }
1218 #[doc = "Handler retrieves next queued handshake request\nFlags: admin-perm\nRequest attributes:\n- [.push_handler_class()](PushAccept::push_handler_class)\n\nReply attributes:\n- [.get_sockfd()](IterableAccept::get_sockfd)\n- [.get_message_type()](IterableAccept::get_message_type)\n- [.get_timeout()](IterableAccept::get_timeout)\n- [.get_auth_mode()](IterableAccept::get_auth_mode)\n- [.get_peer_identity()](IterableAccept::get_peer_identity)\n- [.get_certificate()](IterableAccept::get_certificate)\n- [.get_peername()](IterableAccept::get_peername)\n- [.get_keyring()](IterableAccept::get_keyring)\n"]
1219 pub fn op_accept_do(self) -> OpAcceptDo<'buf> {
1220 let mut res = OpAcceptDo::new(self);
1221 res.request
1222 .do_writeback(res.protocol(), "op-accept-do", OpAcceptDo::lookup);
1223 res
1224 }
1225 #[doc = "Handler reports handshake completion\nRequest attributes:\n- [.push_status()](PushDone::push_status)\n- [.push_sockfd()](PushDone::push_sockfd)\n- [.push_remote_auth()](PushDone::push_remote_auth)\n"]
1226 pub fn op_done_do(self) -> OpDoneDo<'buf> {
1227 let mut res = OpDoneDo::new(self);
1228 res.request
1229 .do_writeback(res.protocol(), "op-done-do", OpDoneDo::lookup);
1230 res
1231 }
1232}
1233#[cfg(test)]
1234mod generated_tests {
1235 use super::*;
1236 #[test]
1237 fn tests() {
1238 let _ = IterableAccept::get_auth_mode;
1239 let _ = IterableAccept::get_certificate;
1240 let _ = IterableAccept::get_keyring;
1241 let _ = IterableAccept::get_message_type;
1242 let _ = IterableAccept::get_peer_identity;
1243 let _ = IterableAccept::get_peername;
1244 let _ = IterableAccept::get_sockfd;
1245 let _ = IterableAccept::get_timeout;
1246 let _ = PushAccept::<&mut Vec<u8>>::push_handler_class;
1247 let _ = PushDone::<&mut Vec<u8>>::push_remote_auth;
1248 let _ = PushDone::<&mut Vec<u8>>::push_sockfd;
1249 let _ = PushDone::<&mut Vec<u8>>::push_status;
1250 }
1251}