1
- use ironrdp_connector:: credssp:: { CredsspProcessGenerator , CredsspSequence , KerberosConfig } ;
1
+ use ironrdp_connector:: credssp:: { CredsspProcessGenerator , KerberosConfig } ;
2
2
use ironrdp_connector:: sspi:: credssp:: ClientState ;
3
3
use ironrdp_connector:: sspi:: generator:: GeneratorState ;
4
4
use ironrdp_connector:: {
5
- custom_err, general_err, ClientConnector , ClientConnectorState , ConnectionResult , ConnectorError , ConnectorResult ,
6
- ServerName , State as _ ,
5
+ custom_err, general_err, ClientConnector , ClientConnectorState , ConnectionResult , ConnectorCore , ConnectorError ,
6
+ ConnectorResult , SecurityConnector , ServerName ,
7
7
} ;
8
8
use ironrdp_core:: WriteBuf ;
9
9
@@ -14,7 +14,10 @@ use crate::{single_sequence_step, AsyncNetworkClient};
14
14
pub struct ShouldUpgrade ;
15
15
16
16
#[ instrument( skip_all) ]
17
- pub async fn connect_begin < S > ( framed : & mut Framed < S > , connector : & mut ClientConnector ) -> ConnectorResult < ShouldUpgrade >
17
+ pub async fn connect_begin < S > (
18
+ framed : & mut Framed < S > ,
19
+ connector : & mut dyn ConnectorCore ,
20
+ ) -> ConnectorResult < ShouldUpgrade >
18
21
where
19
22
S : Sync + FramedRead + FramedWrite ,
20
23
{
29
32
Ok ( ShouldUpgrade )
30
33
}
31
34
32
- pub fn skip_connect_begin ( connector : & mut ClientConnector ) -> ShouldUpgrade {
35
+ pub fn skip_connect_begin ( connector : & dyn SecurityConnector ) -> ShouldUpgrade {
33
36
assert ! ( connector. should_perform_security_upgrade( ) ) ;
34
37
ShouldUpgrade
35
38
}
@@ -38,22 +41,26 @@ pub fn skip_connect_begin(connector: &mut ClientConnector) -> ShouldUpgrade {
38
41
pub struct Upgraded ;
39
42
40
43
#[ instrument( skip_all) ]
41
- pub fn mark_as_upgraded ( _: ShouldUpgrade , connector : & mut ClientConnector ) -> Upgraded {
44
+ pub fn mark_as_upgraded ( _: ShouldUpgrade , connector : & mut dyn SecurityConnector ) -> Upgraded {
42
45
trace ! ( "Marked as upgraded" ) ;
43
46
connector. mark_security_upgrade_as_done ( ) ;
44
47
Upgraded
45
48
}
46
49
47
- #[ instrument( skip_all) ]
48
- pub async fn connect_finalize < S > (
50
+ #[ non_exhaustive]
51
+ pub struct CredSSPFinished {
52
+ pub ( crate ) write_buf : WriteBuf ,
53
+ }
54
+
55
+ pub async fn perform_credssp < S > (
49
56
_: Upgraded ,
57
+ connector : & mut dyn ConnectorCore ,
50
58
framed : & mut Framed < S > ,
51
- mut connector : ClientConnector ,
52
59
server_name : ServerName ,
53
60
server_public_key : Vec < u8 > ,
54
61
network_client : Option < & mut dyn AsyncNetworkClient > ,
55
62
kerberos_config : Option < KerberosConfig > ,
56
- ) -> ConnectorResult < ConnectionResult >
63
+ ) -> ConnectorResult < CredSSPFinished >
57
64
where
58
65
S : FramedRead + FramedWrite ,
59
66
{
62
69
if connector. should_perform_credssp ( ) {
63
70
perform_credssp_step (
64
71
framed,
65
- & mut connector,
72
+ connector,
66
73
& mut buf,
67
74
server_name,
68
75
server_public_key,
72
79
. await ?;
73
80
}
74
81
82
+ Ok ( CredSSPFinished { write_buf : buf } )
83
+ }
84
+
85
+ #[ instrument( skip_all) ]
86
+ pub async fn connect_finalize < S > (
87
+ CredSSPFinished { write_buf : mut buf } : CredSSPFinished ,
88
+ framed : & mut Framed < S > ,
89
+ mut connector : ClientConnector ,
90
+ ) -> ConnectorResult < ConnectionResult >
91
+ where
92
+ S : FramedRead + FramedWrite ,
93
+ {
94
+ buf. clear ( ) ;
75
95
let result = loop {
76
96
single_sequence_step ( framed, & mut connector, & mut buf) . await ?;
77
97
@@ -108,7 +128,7 @@ async fn resolve_generator(
108
128
#[ instrument( level = "trace" , skip_all) ]
109
129
async fn perform_credssp_step < S > (
110
130
framed : & mut Framed < S > ,
111
- connector : & mut ClientConnector ,
131
+ connector : & mut dyn ConnectorCore ,
112
132
buf : & mut WriteBuf ,
113
133
server_name : ServerName ,
114
134
server_public_key : Vec < u8 > ,
@@ -120,70 +140,70 @@ where
120
140
{
121
141
assert ! ( connector. should_perform_credssp( ) ) ;
122
142
123
- let selected_protocol = match connector. state {
124
- ClientConnectorState :: Credssp { selected_protocol, .. } => selected_protocol,
125
- _ => return Err ( general_err ! ( "invalid connector state for CredSSP sequence" ) ) ,
126
- } ;
127
-
128
- let ( mut sequence, mut ts_request) = CredsspSequence :: init (
129
- connector. config . credentials . clone ( ) ,
130
- connector. config . domain . as_deref ( ) ,
131
- selected_protocol,
132
- server_name,
133
- server_public_key,
134
- kerberos_config,
135
- ) ?;
136
-
137
- loop {
138
- let client_state = {
139
- let mut generator = sequence. process_ts_request ( ts_request) ;
143
+ let selected_protocol = connector
144
+ . selected_protocol ( )
145
+ . ok_or_else ( || general_err ! ( "CredSSP protocol not selected, cannot perform CredSSP step" ) ) ?;
140
146
141
- if let Some ( network_client_ref) = network_client. as_deref_mut ( ) {
142
- trace ! ( "resolving network" ) ;
143
- resolve_generator ( & mut generator, network_client_ref) . await ?
144
- } else {
145
- generator
146
- . resolve_to_result ( )
147
- . map_err ( |e| custom_err ! ( "resolve without network client" , e) ) ?
147
+ {
148
+ let ( mut sequence, mut ts_request) = connector. init_credssp (
149
+ connector. config ( ) . credentials . clone ( ) ,
150
+ connector. config ( ) . domain . as_deref ( ) ,
151
+ selected_protocol,
152
+ server_name,
153
+ server_public_key,
154
+ kerberos_config,
155
+ ) ?;
156
+
157
+ loop {
158
+ let client_state = {
159
+ let mut generator = sequence. process_ts_request ( ts_request) ;
160
+
161
+ if let Some ( network_client_ref) = network_client. as_deref_mut ( ) {
162
+ trace ! ( "resolving network" ) ;
163
+ resolve_generator ( & mut generator, network_client_ref) . await ?
164
+ } else {
165
+ generator
166
+ . resolve_to_result ( )
167
+ . map_err ( |e| custom_err ! ( "resolve without network client" , e) ) ?
168
+ }
169
+ } ; // drop generator
170
+
171
+ buf. clear ( ) ;
172
+ let written = sequence. handle_process_result ( client_state, buf) ?;
173
+
174
+ if let Some ( response_len) = written. size ( ) {
175
+ let response = & buf[ ..response_len] ;
176
+ trace ! ( response_len, "Send response" ) ;
177
+ framed
178
+ . write_all ( response)
179
+ . await
180
+ . map_err ( |e| ironrdp_connector:: custom_err!( "write all" , e) ) ?;
148
181
}
149
- } ; // drop generator
150
182
151
- buf. clear ( ) ;
152
- let written = sequence. handle_process_result ( client_state, buf) ?;
183
+ let Some ( next_pdu_hint) = sequence. next_pdu_hint ( ) else {
184
+ break ;
185
+ } ;
153
186
154
- if let Some ( response_len) = written. size ( ) {
155
- let response = & buf[ ..response_len] ;
156
- trace ! ( response_len, "Send response" ) ;
157
- framed
158
- . write_all ( response)
159
- . await
160
- . map_err ( |e| ironrdp_connector:: custom_err!( "write all" , e) ) ?;
161
- }
162
-
163
- let Some ( next_pdu_hint) = sequence. next_pdu_hint ( ) else {
164
- break ;
165
- } ;
166
-
167
- debug ! (
168
- connector. state = connector. state. name( ) ,
169
- hint = ?next_pdu_hint,
170
- "Wait for PDU"
171
- ) ;
187
+ debug ! (
188
+ connector. state = connector. state( ) . name( ) ,
189
+ hint = ?next_pdu_hint,
190
+ "Wait for PDU"
191
+ ) ;
172
192
173
- let pdu = framed
174
- . read_by_hint ( next_pdu_hint)
175
- . await
176
- . map_err ( |e| ironrdp_connector:: custom_err!( "read frame by hint" , e) ) ?;
193
+ let pdu = framed
194
+ . read_by_hint ( next_pdu_hint)
195
+ . await
196
+ . map_err ( |e| ironrdp_connector:: custom_err!( "read frame by hint" , e) ) ?;
177
197
178
- trace ! ( length = pdu. len( ) , "PDU received" ) ;
198
+ trace ! ( length = pdu. len( ) , "PDU received" ) ;
179
199
180
- if let Some ( next_request) = sequence. decode_server_message ( & pdu) ? {
181
- ts_request = next_request;
182
- } else {
183
- break ;
200
+ if let Some ( next_request) = sequence. decode_server_message ( & pdu) ? {
201
+ ts_request = next_request;
202
+ } else {
203
+ break ;
204
+ }
184
205
}
185
206
}
186
-
187
207
connector. mark_credssp_as_done ( ) ;
188
208
189
209
Ok ( ( ) )
0 commit comments