ironrdp_acceptor/
connection.rs

1use core::mem;
2
3use ironrdp_connector::{
4    encode_x224_packet, general_err, reason_err, ConnectorError, ConnectorErrorExt as _, ConnectorResult, DesktopSize,
5    Sequence, State, Written,
6};
7use ironrdp_core::{decode, WriteBuf};
8use ironrdp_pdu as pdu;
9use ironrdp_pdu::nego::SecurityProtocol;
10use ironrdp_pdu::x224::X224;
11use ironrdp_svc::{StaticChannelSet, SvcServerProcessor};
12use pdu::rdp::capability_sets::CapabilitySet;
13use pdu::rdp::client_info::Credentials;
14use pdu::rdp::headers::ShareControlPdu;
15use pdu::rdp::server_error_info::{ErrorInfo, ProtocolIndependentCode, ServerSetErrorInfoPdu};
16use pdu::rdp::server_license::{LicensePdu, LicensingErrorMessage};
17use pdu::{gcc, mcs, nego, rdp};
18use tracing::{debug, warn};
19
20use super::channel_connection::ChannelConnectionSequence;
21use super::finalization::FinalizationSequence;
22use crate::util::{self, wrap_share_data};
23
24const IO_CHANNEL_ID: u16 = 1003;
25const USER_CHANNEL_ID: u16 = 1002;
26
27pub struct Acceptor {
28    pub(crate) state: AcceptorState,
29    security: SecurityProtocol,
30    io_channel_id: u16,
31    user_channel_id: u16,
32    desktop_size: DesktopSize,
33    server_capabilities: Vec<CapabilitySet>,
34    static_channels: StaticChannelSet,
35    saved_for_reactivation: AcceptorState,
36    pub(crate) creds: Option<Credentials>,
37    reactivation: bool,
38}
39
40#[derive(Debug)]
41pub struct AcceptorResult {
42    pub static_channels: StaticChannelSet,
43    pub capabilities: Vec<CapabilitySet>,
44    pub input_events: Vec<Vec<u8>>,
45    pub user_channel_id: u16,
46    pub io_channel_id: u16,
47    pub reactivation: bool,
48}
49
50impl Acceptor {
51    pub fn new(
52        security: SecurityProtocol,
53        desktop_size: DesktopSize,
54        capabilities: Vec<CapabilitySet>,
55        creds: Option<Credentials>,
56    ) -> Self {
57        Self {
58            security,
59            state: AcceptorState::InitiationWaitRequest,
60            user_channel_id: USER_CHANNEL_ID,
61            io_channel_id: IO_CHANNEL_ID,
62            desktop_size,
63            server_capabilities: capabilities,
64            static_channels: StaticChannelSet::new(),
65            saved_for_reactivation: Default::default(),
66            creds,
67            reactivation: false,
68        }
69    }
70
71    pub fn new_deactivation_reactivation(
72        mut consumed: Acceptor,
73        static_channels: StaticChannelSet,
74        desktop_size: DesktopSize,
75    ) -> ConnectorResult<Self> {
76        let AcceptorState::CapabilitiesSendServer {
77            early_capability,
78            channels,
79        } = consumed.saved_for_reactivation
80        else {
81            return Err(general_err!("invalid acceptor state"));
82        };
83
84        for cap in consumed.server_capabilities.iter_mut() {
85            if let CapabilitySet::Bitmap(cap) = cap {
86                cap.desktop_width = desktop_size.width;
87                cap.desktop_height = desktop_size.height;
88            }
89        }
90        let state = AcceptorState::CapabilitiesSendServer {
91            early_capability,
92            channels: channels.clone(),
93        };
94        let saved_for_reactivation = AcceptorState::CapabilitiesSendServer {
95            early_capability,
96            channels,
97        };
98        Ok(Self {
99            security: consumed.security,
100            state,
101            user_channel_id: consumed.user_channel_id,
102            io_channel_id: consumed.io_channel_id,
103            desktop_size,
104            server_capabilities: consumed.server_capabilities,
105            static_channels,
106            saved_for_reactivation,
107            creds: consumed.creds,
108            reactivation: true,
109        })
110    }
111
112    pub fn attach_static_channel<T>(&mut self, channel: T)
113    where
114        T: SvcServerProcessor + 'static,
115    {
116        self.static_channels.insert(channel);
117    }
118
119    pub fn reached_security_upgrade(&self) -> Option<SecurityProtocol> {
120        match self.state {
121            AcceptorState::SecurityUpgrade { .. } => Some(self.security),
122            _ => None,
123        }
124    }
125
126    pub fn mark_security_upgrade_as_done(&mut self) {
127        assert!(self.reached_security_upgrade().is_some());
128        self.step(&[], &mut WriteBuf::new()).expect("transition to next state");
129        debug_assert!(self.reached_security_upgrade().is_none());
130    }
131
132    pub fn should_perform_credssp(&self) -> bool {
133        matches!(self.state, AcceptorState::Credssp { .. })
134    }
135
136    pub fn mark_credssp_as_done(&mut self) {
137        assert!(self.should_perform_credssp());
138        let res = self.step(&[], &mut WriteBuf::new()).expect("transition to next state");
139        debug_assert!(!self.should_perform_credssp());
140        assert_eq!(res, Written::Nothing);
141    }
142
143    pub fn get_result(&mut self) -> Option<AcceptorResult> {
144        match mem::take(&mut self.state) {
145            AcceptorState::Accepted {
146                channels: _channels, // TODO: what about ChannelDef?
147                client_capabilities,
148                input_events,
149            } => Some(AcceptorResult {
150                static_channels: mem::take(&mut self.static_channels),
151                capabilities: client_capabilities,
152                input_events,
153                user_channel_id: self.user_channel_id,
154                io_channel_id: self.io_channel_id,
155                reactivation: self.reactivation,
156            }),
157            previous_state => {
158                self.state = previous_state;
159                None
160            }
161        }
162    }
163}
164
165#[derive(Default, Debug)]
166pub enum AcceptorState {
167    #[default]
168    Consumed,
169
170    InitiationWaitRequest,
171    InitiationSendConfirm {
172        requested_protocol: SecurityProtocol,
173    },
174    SecurityUpgrade {
175        requested_protocol: SecurityProtocol,
176        protocol: SecurityProtocol,
177    },
178    Credssp {
179        requested_protocol: SecurityProtocol,
180        protocol: SecurityProtocol,
181    },
182    BasicSettingsWaitInitial {
183        requested_protocol: SecurityProtocol,
184        protocol: SecurityProtocol,
185    },
186    BasicSettingsSendResponse {
187        requested_protocol: SecurityProtocol,
188        protocol: SecurityProtocol,
189        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
190        channels: Vec<(u16, Option<gcc::ChannelDef>)>,
191    },
192    ChannelConnection {
193        protocol: SecurityProtocol,
194        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
195        channels: Vec<(u16, gcc::ChannelDef)>,
196        connection: ChannelConnectionSequence,
197    },
198    RdpSecurityCommencement {
199        protocol: SecurityProtocol,
200        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
201        channels: Vec<(u16, gcc::ChannelDef)>,
202    },
203    SecureSettingsExchange {
204        protocol: SecurityProtocol,
205        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
206        channels: Vec<(u16, gcc::ChannelDef)>,
207    },
208    LicensingExchange {
209        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
210        channels: Vec<(u16, gcc::ChannelDef)>,
211    },
212    CapabilitiesSendServer {
213        early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
214        channels: Vec<(u16, gcc::ChannelDef)>,
215    },
216    MonitorLayoutSend {
217        channels: Vec<(u16, gcc::ChannelDef)>,
218    },
219    CapabilitiesWaitConfirm {
220        channels: Vec<(u16, gcc::ChannelDef)>,
221    },
222    ConnectionFinalization {
223        finalization: FinalizationSequence,
224        channels: Vec<(u16, gcc::ChannelDef)>,
225        client_capabilities: Vec<CapabilitySet>,
226    },
227    Accepted {
228        channels: Vec<(u16, gcc::ChannelDef)>,
229        client_capabilities: Vec<CapabilitySet>,
230        input_events: Vec<Vec<u8>>,
231    },
232}
233
234impl State for AcceptorState {
235    fn name(&self) -> &'static str {
236        match self {
237            Self::Consumed => "Consumed",
238            Self::InitiationWaitRequest => "InitiationWaitRequest",
239            Self::InitiationSendConfirm { .. } => "InitiationSendConfirm",
240            Self::SecurityUpgrade { .. } => "SecurityUpgrade",
241            Self::Credssp { .. } => "Credssp",
242            Self::BasicSettingsWaitInitial { .. } => "BasicSettingsWaitInitial",
243            Self::BasicSettingsSendResponse { .. } => "BasicSettingsSendResponse",
244            Self::ChannelConnection { .. } => "ChannelConnection",
245            Self::RdpSecurityCommencement { .. } => "RdpSecurityCommencement",
246            Self::SecureSettingsExchange { .. } => "SecureSettingsExchange",
247            Self::LicensingExchange { .. } => "LicensingExchange",
248            Self::CapabilitiesSendServer { .. } => "CapabilitiesSendServer",
249            Self::MonitorLayoutSend { .. } => "MonitorLayoutSend",
250            Self::CapabilitiesWaitConfirm { .. } => "CapabilitiesWaitConfirm",
251            Self::ConnectionFinalization { .. } => "ConnectionFinalization",
252            Self::Accepted { .. } => "Connected",
253        }
254    }
255
256    fn is_terminal(&self) -> bool {
257        matches!(self, Self::Accepted { .. })
258    }
259
260    fn as_any(&self) -> &dyn core::any::Any {
261        self
262    }
263}
264
265impl Sequence for Acceptor {
266    fn next_pdu_hint(&self) -> Option<&dyn pdu::PduHint> {
267        match &self.state {
268            AcceptorState::Consumed => None,
269            AcceptorState::InitiationWaitRequest => Some(&pdu::X224_HINT),
270            AcceptorState::InitiationSendConfirm { .. } => None,
271            AcceptorState::SecurityUpgrade { .. } => None,
272            AcceptorState::Credssp { .. } => None,
273            AcceptorState::BasicSettingsWaitInitial { .. } => Some(&pdu::X224_HINT),
274            AcceptorState::BasicSettingsSendResponse { .. } => None,
275            AcceptorState::ChannelConnection { connection, .. } => connection.next_pdu_hint(),
276            AcceptorState::RdpSecurityCommencement { .. } => None,
277            AcceptorState::SecureSettingsExchange { .. } => Some(&pdu::X224_HINT),
278            AcceptorState::LicensingExchange { .. } => None,
279            AcceptorState::CapabilitiesSendServer { .. } => None,
280            AcceptorState::MonitorLayoutSend { .. } => None,
281            AcceptorState::CapabilitiesWaitConfirm { .. } => Some(&pdu::X224_HINT),
282            AcceptorState::ConnectionFinalization { finalization, .. } => finalization.next_pdu_hint(),
283            AcceptorState::Accepted { .. } => None,
284        }
285    }
286
287    fn state(&self) -> &dyn State {
288        &self.state
289    }
290
291    fn step(&mut self, input: &[u8], output: &mut WriteBuf) -> ConnectorResult<Written> {
292        let prev_state = mem::take(&mut self.state);
293
294        let (written, next_state) = match prev_state {
295            AcceptorState::InitiationWaitRequest => {
296                let connection_request = decode::<X224<nego::ConnectionRequest>>(input)
297                    .map_err(ConnectorError::decode)
298                    .map(|p| p.0)?;
299
300                debug!(message = ?connection_request, "Received");
301
302                (
303                    Written::Nothing,
304                    AcceptorState::InitiationSendConfirm {
305                        requested_protocol: connection_request.protocol,
306                    },
307                )
308            }
309
310            AcceptorState::InitiationSendConfirm { requested_protocol } => {
311                let protocols = requested_protocol & self.security;
312                let protocol = if protocols.intersects(SecurityProtocol::HYBRID_EX) {
313                    SecurityProtocol::HYBRID_EX
314                } else if protocols.intersects(SecurityProtocol::HYBRID) {
315                    SecurityProtocol::HYBRID
316                } else if protocols.intersects(SecurityProtocol::SSL) {
317                    SecurityProtocol::SSL
318                } else if self.security.is_empty() {
319                    SecurityProtocol::empty()
320                } else {
321                    return Err(ConnectorError::general("failed to negotiate security protocol"));
322                };
323                let connection_confirm = nego::ConnectionConfirm::Response {
324                    flags: nego::ResponseFlags::empty(),
325                    protocol,
326                };
327
328                debug!(message = ?connection_confirm, "Send");
329
330                let written =
331                    ironrdp_core::encode_buf(&X224(connection_confirm), output).map_err(ConnectorError::encode)?;
332
333                (
334                    Written::from_size(written)?,
335                    AcceptorState::SecurityUpgrade {
336                        requested_protocol,
337                        protocol,
338                    },
339                )
340            }
341
342            AcceptorState::SecurityUpgrade {
343                requested_protocol,
344                protocol,
345            } => {
346                debug!(?requested_protocol);
347                let next_state = if protocol.intersects(SecurityProtocol::HYBRID | SecurityProtocol::HYBRID_EX) {
348                    AcceptorState::Credssp {
349                        requested_protocol,
350                        protocol,
351                    }
352                } else {
353                    AcceptorState::BasicSettingsWaitInitial {
354                        requested_protocol,
355                        protocol,
356                    }
357                };
358                (Written::Nothing, next_state)
359            }
360
361            AcceptorState::Credssp {
362                requested_protocol,
363                protocol,
364            } => (
365                Written::Nothing,
366                AcceptorState::BasicSettingsWaitInitial {
367                    requested_protocol,
368                    protocol,
369                },
370            ),
371
372            AcceptorState::BasicSettingsWaitInitial {
373                requested_protocol,
374                protocol,
375            } => {
376                let x224_payload = decode::<X224<pdu::x224::X224Data<'_>>>(input)
377                    .map_err(ConnectorError::decode)
378                    .map(|p| p.0)?;
379                let settings_initial =
380                    decode::<mcs::ConnectInitial>(x224_payload.data.as_ref()).map_err(ConnectorError::decode)?;
381
382                debug!(message = ?settings_initial, "Received");
383
384                let early_capability = settings_initial
385                    .conference_create_request
386                    .gcc_blocks
387                    .core
388                    .optional_data
389                    .early_capability_flags;
390
391                let joined: Vec<_> = settings_initial
392                    .conference_create_request
393                    .gcc_blocks
394                    .network
395                    .map(|network| {
396                        network
397                            .channels
398                            .into_iter()
399                            .map(|c| {
400                                self.static_channels
401                                    .get_by_channel_name(&c.name)
402                                    .map(|(type_id, _)| (type_id, c))
403                            })
404                            .collect()
405                    })
406                    .unwrap_or_default();
407
408                #[expect(clippy::arithmetic_side_effects)] // IO channel ID is not big enough for overflowing.
409                let channels = joined
410                    .into_iter()
411                    .enumerate()
412                    .map(|(i, channel)| {
413                        let channel_id = u16::try_from(i).unwrap() + self.io_channel_id + 1;
414                        if let Some((type_id, c)) = channel {
415                            self.static_channels.attach_channel_id(type_id, channel_id);
416                            (channel_id, Some(c))
417                        } else {
418                            (channel_id, None)
419                        }
420                    })
421                    .collect();
422
423                (
424                    Written::Nothing,
425                    AcceptorState::BasicSettingsSendResponse {
426                        requested_protocol,
427                        protocol,
428                        early_capability,
429                        channels,
430                    },
431                )
432            }
433
434            AcceptorState::BasicSettingsSendResponse {
435                requested_protocol,
436                protocol,
437                early_capability,
438                channels,
439            } => {
440                let channel_ids: Vec<u16> = channels.iter().map(|&(i, _)| i).collect();
441
442                let skip_channel_join = early_capability
443                    .is_some_and(|client| client.contains(gcc::ClientEarlyCapabilityFlags::SUPPORT_SKIP_CHANNELJOIN));
444
445                let server_blocks = create_gcc_blocks(
446                    self.io_channel_id,
447                    channel_ids.clone(),
448                    requested_protocol,
449                    skip_channel_join,
450                );
451
452                let settings_response = mcs::ConnectResponse {
453                    conference_create_response: gcc::ConferenceCreateResponse {
454                        user_id: self.user_channel_id,
455                        gcc_blocks: server_blocks,
456                    },
457                    called_connect_id: 1,
458                    domain_parameters: mcs::DomainParameters::target(),
459                };
460
461                debug!(message = ?settings_response, "Send");
462
463                let written = encode_x224_packet(&settings_response, output)?;
464                let channels = channels.into_iter().filter_map(|(i, c)| c.map(|c| (i, c))).collect();
465
466                (
467                    Written::from_size(written)?,
468                    AcceptorState::ChannelConnection {
469                        protocol,
470                        early_capability,
471                        channels,
472                        connection: if skip_channel_join {
473                            ChannelConnectionSequence::skip_channel_join(self.user_channel_id)
474                        } else {
475                            ChannelConnectionSequence::new(self.user_channel_id, self.io_channel_id, channel_ids)
476                        },
477                    },
478                )
479            }
480
481            AcceptorState::ChannelConnection {
482                protocol,
483                early_capability,
484                channels,
485                mut connection,
486            } => {
487                let written = connection.step(input, output)?;
488                let state = if connection.is_done() {
489                    AcceptorState::RdpSecurityCommencement {
490                        protocol,
491                        early_capability,
492                        channels,
493                    }
494                } else {
495                    AcceptorState::ChannelConnection {
496                        protocol,
497                        early_capability,
498                        channels,
499                        connection,
500                    }
501                };
502
503                (written, state)
504            }
505
506            AcceptorState::RdpSecurityCommencement {
507                protocol,
508                early_capability,
509                channels,
510                ..
511            } => (
512                Written::Nothing,
513                AcceptorState::SecureSettingsExchange {
514                    protocol,
515                    early_capability,
516                    channels,
517                },
518            ),
519
520            AcceptorState::SecureSettingsExchange {
521                protocol,
522                early_capability,
523                channels,
524            } => {
525                let data: X224<mcs::SendDataRequest<'_>> = decode(input).map_err(ConnectorError::decode)?;
526                let data = data.0;
527                let client_info: rdp::ClientInfoPdu =
528                    decode(data.user_data.as_ref()).map_err(ConnectorError::decode)?;
529
530                debug!(message = ?client_info, "Received");
531
532                if !protocol.intersects(SecurityProtocol::HYBRID | SecurityProtocol::HYBRID_EX) {
533                    let creds = client_info.client_info.credentials;
534
535                    if self.creds.as_ref() != Some(&creds) {
536                        // FIXME: How authorization should be denied with standard RDP security?
537                        // Since standard RDP security is not a priority, we just send a ServerDeniedConnection ServerSetErrorInfo PDU.
538                        let info = ServerSetErrorInfoPdu(ErrorInfo::ProtocolIndependentCode(
539                            ProtocolIndependentCode::ServerDeniedConnection,
540                        ));
541
542                        debug!(message = ?info, "Send");
543
544                        util::encode_send_data_indication(self.user_channel_id, self.io_channel_id, &info, output)?;
545
546                        return Err(ConnectorError::general("invalid credentials"));
547                    }
548                }
549
550                (
551                    Written::Nothing,
552                    AcceptorState::LicensingExchange {
553                        early_capability,
554                        channels,
555                    },
556                )
557            }
558
559            AcceptorState::LicensingExchange {
560                early_capability,
561                channels,
562            } => {
563                let license: LicensePdu = LicensingErrorMessage::new_valid_client()
564                    .map_err(ConnectorError::encode)?
565                    .into();
566
567                debug!(message = ?license, "Send");
568
569                let written =
570                    util::encode_send_data_indication(self.user_channel_id, self.io_channel_id, &license, output)?;
571
572                self.saved_for_reactivation = AcceptorState::CapabilitiesSendServer {
573                    early_capability,
574                    channels: channels.clone(),
575                };
576
577                (
578                    Written::from_size(written)?,
579                    AcceptorState::CapabilitiesSendServer {
580                        early_capability,
581                        channels,
582                    },
583                )
584            }
585
586            AcceptorState::CapabilitiesSendServer {
587                early_capability,
588                channels,
589            } => {
590                let demand_active = rdp::headers::ShareControlHeader {
591                    share_id: 0,
592                    pdu_source: self.io_channel_id,
593                    share_control_pdu: ShareControlPdu::ServerDemandActive(rdp::capability_sets::ServerDemandActive {
594                        pdu: rdp::capability_sets::DemandActive {
595                            source_descriptor: "".into(),
596                            capability_sets: self.server_capabilities.clone(),
597                        },
598                    }),
599                };
600
601                debug!(message = ?demand_active, "Send");
602
603                let written = util::encode_send_data_indication(
604                    self.user_channel_id,
605                    self.io_channel_id,
606                    &demand_active,
607                    output,
608                )?;
609
610                let layout_flag = gcc::ClientEarlyCapabilityFlags::SUPPORT_MONITOR_LAYOUT_PDU;
611                let next_state = if early_capability.is_some_and(|c| c.contains(layout_flag)) {
612                    AcceptorState::MonitorLayoutSend { channels }
613                } else {
614                    AcceptorState::CapabilitiesWaitConfirm { channels }
615                };
616
617                (Written::from_size(written)?, next_state)
618            }
619
620            AcceptorState::MonitorLayoutSend { channels } => {
621                let monitor_layout =
622                    rdp::headers::ShareDataPdu::MonitorLayout(rdp::finalization_messages::MonitorLayoutPdu {
623                        monitors: vec![gcc::Monitor {
624                            left: 0,
625                            top: 0,
626                            right: i32::from(self.desktop_size.width),
627                            bottom: i32::from(self.desktop_size.height),
628                            flags: gcc::MonitorFlags::PRIMARY,
629                        }],
630                    });
631
632                debug!(message = ?monitor_layout, "Send");
633
634                let share_data = wrap_share_data(monitor_layout, self.io_channel_id);
635
636                let written =
637                    util::encode_send_data_indication(self.user_channel_id, self.io_channel_id, &share_data, output)?;
638
639                (
640                    Written::from_size(written)?,
641                    AcceptorState::CapabilitiesWaitConfirm { channels },
642                )
643            }
644
645            AcceptorState::CapabilitiesWaitConfirm { ref channels } => {
646                let message = decode::<X224<mcs::McsMessage<'_>>>(input)
647                    .map_err(ConnectorError::decode)
648                    .map(|p| p.0);
649                let message = match message {
650                    Ok(msg) => msg,
651                    Err(e) => {
652                        if self.reactivation {
653                            debug!("Dropping unexpected PDU during reactivation");
654                            self.state = prev_state;
655                            return Ok(Written::Nothing);
656                        } else {
657                            return Err(e);
658                        }
659                    }
660                };
661                match message {
662                    mcs::McsMessage::SendDataRequest(data) => {
663                        let capabilities_confirm = decode::<rdp::headers::ShareControlHeader>(data.user_data.as_ref())
664                            .map_err(ConnectorError::decode);
665                        let capabilities_confirm = match capabilities_confirm {
666                            Ok(capabilities_confirm) => capabilities_confirm,
667                            Err(e) => {
668                                if self.reactivation {
669                                    debug!("Dropping unexpected PDU during reactivation");
670                                    self.state = prev_state;
671                                    return Ok(Written::Nothing);
672                                } else {
673                                    return Err(e);
674                                }
675                            }
676                        };
677
678                        debug!(message = ?capabilities_confirm, "Received");
679
680                        let ShareControlPdu::ClientConfirmActive(confirm) = capabilities_confirm.share_control_pdu
681                        else {
682                            return Err(ConnectorError::general("expected client confirm active"));
683                        };
684
685                        (
686                            Written::Nothing,
687                            AcceptorState::ConnectionFinalization {
688                                channels: channels.clone(),
689                                finalization: FinalizationSequence::new(self.user_channel_id, self.io_channel_id),
690                                client_capabilities: confirm.pdu.capability_sets,
691                            },
692                        )
693                    }
694
695                    mcs::McsMessage::DisconnectProviderUltimatum(ultimatum) => {
696                        return Err(reason_err!("received disconnect ultimatum", "{:?}", ultimatum.reason))
697                    }
698
699                    _ => {
700                        warn!(?message, "Unexpected MCS message received");
701
702                        (Written::Nothing, prev_state)
703                    }
704                }
705            }
706
707            AcceptorState::ConnectionFinalization {
708                mut finalization,
709                channels,
710                client_capabilities,
711            } => {
712                let written = finalization.step(input, output)?;
713
714                let state = if finalization.is_done() {
715                    AcceptorState::Accepted {
716                        channels,
717                        client_capabilities,
718                        input_events: finalization.input_events,
719                    }
720                } else {
721                    AcceptorState::ConnectionFinalization {
722                        finalization,
723                        channels,
724                        client_capabilities,
725                    }
726                };
727
728                (written, state)
729            }
730
731            _ => unreachable!(),
732        };
733
734        self.state = next_state;
735        Ok(written)
736    }
737}
738
739fn create_gcc_blocks(
740    io_channel: u16,
741    channel_ids: Vec<u16>,
742    requested: SecurityProtocol,
743    skip_channel_join: bool,
744) -> gcc::ServerGccBlocks {
745    gcc::ServerGccBlocks {
746        core: gcc::ServerCoreData {
747            version: gcc::RdpVersion::V5_PLUS,
748            optional_data: gcc::ServerCoreOptionalData {
749                client_requested_protocols: Some(requested),
750                early_capability_flags: skip_channel_join
751                    .then_some(gcc::ServerEarlyCapabilityFlags::SKIP_CHANNELJOIN_SUPPORTED),
752            },
753        },
754        security: gcc::ServerSecurityData::no_security(),
755        network: gcc::ServerNetworkData {
756            channel_ids,
757            io_channel,
758        },
759        message_channel: None,
760        multi_transport_channel: None,
761    }
762}