1313// limitations under the License.
1414
1515using NtApiDotNet . Ndr . Marshal ;
16- using NtApiDotNet . Utilities . Misc ;
1716using NtApiDotNet . Win32 . Rpc . Transport . PDU ;
1817using NtApiDotNet . Win32 . Security . Authentication ;
1918using System ;
@@ -47,6 +46,13 @@ protected RpcConnectedClientTransport(ushort max_recv_fragment, ushort max_send_
4746 _security_context = new Dictionary < int , RpcTransportSecurityContext > ( ) ;
4847 _current_security_context = new RpcTransportSecurityContext ( this , transport_security , _current_context_id ++ ) ;
4948 _security_context [ _current_security_context . ContextId ] = _current_security_context ;
49+ switch ( transport_security . AuthenticationLevel )
50+ {
51+ case RpcAuthenticationLevel . PacketIntegrity :
52+ case RpcAuthenticationLevel . PacketPrivacy :
53+ _auth_data_required = true ;
54+ break ;
55+ }
5056
5157 if ( DisableBindTimeFeatureNegotiation )
5258 _bind_time_features = BindTimeFeatureNegotiation . None ;
@@ -75,13 +81,14 @@ protected RpcConnectedClientTransport(ushort max_recv_fragment, ushort max_send_
7581 private ushort _max_recv_fragment ;
7682 private ushort _max_send_fragment ;
7783 private int _recv_sequence_no ;
78- private int _send_senqunce_no ;
84+ private int _send_sequence_no ;
7985 private BindTimeFeatureNegotiation ? _bind_time_features ;
8086 private bool _transport_bound ;
8187 private Guid _interface_id ;
8288 private Version _interface_version ;
8389 private Guid _transfer_syntax_id ;
8490 private Version _transfer_syntax_version ;
91+ private bool _auth_data_required ;
8592
8693 private PDUBase CheckFault ( PDUBase pdu )
8794 {
@@ -149,7 +156,7 @@ private Tuple<PDUBase, AuthData> SendReceivePDU(int call_id, PDUBase send_pdu, b
149156 RpcUtils . DumpBuffer ( true , $ "{ GetType ( ) . Name } Send Buffer", fragment ) ;
150157 if ( ! WriteFragment ( fragment ) )
151158 throw new RpcTransportException ( "Failed to write out PDU buffer." ) ;
152- _send_senqunce_no ++ ;
159+ _send_sequence_no ++ ;
153160 if ( ! receive_pdu )
154161 return null ;
155162
@@ -213,13 +220,11 @@ private byte[] SendReceiveRequestPDU(int proc_num, Guid objuuid, byte[] stub_dat
213220 int max_fragment = _max_send_fragment - request_pdu . HeaderLength ;
214221 int auth_data_length = 0 ;
215222
216- bool auth_required = false ;
217- if ( security_context . NeedAuthData )
223+ if ( _auth_data_required )
218224 {
219225 auth_data_length = security_context . AuthDataLength ;
220226 max_fragment -= ( auth_data_length + AuthData . PDU_AUTH_DATA_HEADER_SIZE ) ;
221227 max_fragment &= ~ 0xF ;
222- auth_required = true ;
223228 }
224229
225230 List < byte [ ] > fragments = PDURequest . DoFragment ( stub_data , max_fragment ) ;
@@ -246,7 +251,7 @@ private byte[] SendReceiveRequestPDU(int proc_num, Guid objuuid, byte[] stub_dat
246251 byte [ ] stub_fragment = fragments [ i ] ;
247252 byte [ ] auth_data = new byte [ 0 ] ;
248253 byte [ ] header = request_pdu . ToArray ( pdu_header , stub_fragment . Length , 0 ) ;
249- if ( auth_required )
254+ if ( _auth_data_required )
250255 {
251256 int auth_data_padding = 0 ;
252257 int auth_trailing_size = ( header . Length + stub_fragment . Length + AuthData . PDU_AUTH_DATA_HEADER_SIZE ) & 0xF ;
@@ -257,7 +262,7 @@ private byte[] SendReceiveRequestPDU(int proc_num, Guid objuuid, byte[] stub_dat
257262 }
258263
259264 header = request_pdu . ToArray ( pdu_header , stub_fragment . Length + AuthData . PDU_AUTH_DATA_HEADER_SIZE , auth_data_length ) ;
260- auth_data = security_context . ProtectPDU ( header , ref stub_fragment , auth_data_padding , _send_senqunce_no ) ;
265+ auth_data = security_context . ProtectPDU ( header , ref stub_fragment , auth_data_padding , _send_sequence_no ) ;
261266 }
262267
263268 MemoryStream send_stm = new MemoryStream ( ) ;
@@ -270,7 +275,7 @@ private byte[] SendReceiveRequestPDU(int proc_num, Guid objuuid, byte[] stub_dat
270275 RpcUtils . DumpBuffer ( true , name , fragment ) ;
271276 if ( ! WriteFragment ( fragment ) )
272277 throw new RpcTransportException ( "Failed to write out PDU buffer." ) ;
273- _send_senqunce_no ++ ;
278+ _send_sequence_no ++ ;
274279 }
275280
276281 MemoryStream recv_stm = new MemoryStream ( ) ;
@@ -294,7 +299,7 @@ private byte[] SendReceiveRequestPDU(int proc_num, Guid objuuid, byte[] stub_dat
294299 var recv_pdu = CheckFault ( curr_header . ToPDU ( pdu . Item2 ) ) ;
295300 if ( recv_pdu is PDUResponse resp_pdu )
296301 {
297- byte [ ] resp_stub_data = auth_required ? security_context . UnprotectPDU ( resp_pdu . ToArray ( curr_header ) ,
302+ byte [ ] resp_stub_data = _auth_data_required ? security_context . UnprotectPDU ( resp_pdu . ToArray ( curr_header ) ,
298303 resp_pdu . StubData , auth_data , _recv_sequence_no ) : resp_pdu . StubData ;
299304 _recv_sequence_no ++ ;
300305 recv_stm . Write ( resp_stub_data , 0 , resp_stub_data . Length ) ;
@@ -528,15 +533,24 @@ public RpcTransportSecurityContext AddSecurityContext(RpcTransportSecurity trans
528533 {
529534 if ( ! SupportsMultipleSecurityContexts )
530535 throw new InvalidOperationException ( "Transport doesn't support multiple security context." ) ;
531- if ( transport_security . AuthenticationLevel < RpcAuthenticationLevel . PacketIntegrity )
532- throw new ArgumentException ( "Can only create a new context with higher authentication level." ) ;
536+ switch ( transport_security . AuthenticationLevel )
537+ {
538+ case RpcAuthenticationLevel . Connect :
539+ case RpcAuthenticationLevel . PacketIntegrity :
540+ case RpcAuthenticationLevel . PacketPrivacy :
541+ break ;
542+ default :
543+ throw new ArgumentException ( "Can only create a new context with specific authentication levels." ) ;
544+ }
545+
533546 if ( ! _transport_bound )
534547 throw new InvalidOperationException ( "Transport hasn't been bound yet." ) ;
535548 var context = new RpcTransportSecurityContext ( this ,
536549 transport_security , _current_context_id ++ ) ;
537550 try
538551 {
539552 BindAuth ( true , context ) ;
553+ _auth_data_required = true ;
540554 return _security_context [ context . ContextId ] = context ;
541555 }
542556 catch
@@ -577,7 +591,6 @@ public RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresen
577591 /// </summary>
578592 /// <remarks>Should be set before connecting an RPC client.</remarks>
579593 public static bool DisableBindTimeFeatureNegotiation { get ; set ; }
580-
581594 #endregion
582595
583596 #region IDisposable implementation.
0 commit comments