@@ -52,7 +52,7 @@ sealed class AuthBlock
5252
5353 public bool WireCryptInitialized { get ; private set ; }
5454
55- private const int STACKALLOC_LIMIT = 512 ;
55+ private const byte SEPARATOR_BYTE = ( byte ) ',' ;
5656
5757 public AuthBlock ( GdsConnection connection , string user , string password , WireCryptOption wireCrypt )
5858 {
@@ -70,166 +70,72 @@ public byte[] UserIdentificationData()
7070 {
7171 using ( var result = new MemoryStream ( 256 ) )
7272 {
73- {
74- var userString = Environment . GetEnvironmentVariable ( "USERNAME" ) ?? Environment . GetEnvironmentVariable ( "USER" ) ?? string . Empty ;
75- var slen = Encoding . UTF8 . GetByteCount ( userString ) ;
76- byte [ ] rented = null ;
77- Span < byte > user = slen > STACKALLOC_LIMIT
78- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
79- : stackalloc byte [ slen ] ;
80- int real_len = Encoding . UTF8 . GetBytes ( userString , user ) ;
81- result . WriteByte ( IscCodes . CNCT_user ) ;
82- result . WriteByte ( ( byte ) real_len ) ;
83- result . Write ( user ) ;
84- if ( rented != null )
85- {
86- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
87- }
88- }
89-
90- {
91- var hostName = Dns . GetHostName ( ) ;
92- var slen = Encoding . UTF8 . GetByteCount ( hostName ) ;
93- byte [ ] rented = null ;
94- Span < byte > host = slen > STACKALLOC_LIMIT
95- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
96- : stackalloc byte [ slen ] ;
97- int real_len = Encoding . UTF8 . GetBytes ( hostName , host ) ;
98- result . WriteByte ( IscCodes . CNCT_host ) ;
99- result . WriteByte ( ( byte ) real_len ) ;
100- result . Write ( host ) ;
101- if ( rented != null )
102- {
103- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
104- }
105- }
73+ Span < byte > scratchpad = stackalloc byte [ 258 ] ;
74+ var userString = Environment . GetEnvironmentVariable ( "USERNAME" ) ?? Environment . GetEnvironmentVariable ( "USER" ) ?? string . Empty ;
75+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_user , userString ) ;
76+ var hostName = Dns . GetHostName ( ) ;
77+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_host , hostName ) ;
10678
10779 result . WriteByte ( IscCodes . CNCT_user_verification ) ;
10880 result . WriteByte ( 0 ) ;
10981
11082 if ( ! string . IsNullOrEmpty ( User ) )
11183 {
112- {
113- var slen = Encoding . UTF8 . GetByteCount ( User ) ;
114- byte [ ] rented = null ;
115- Span < byte > bytes = slen > STACKALLOC_LIMIT
116- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
117- : stackalloc byte [ slen ] ;
118- int real_len = Encoding . UTF8 . GetBytes ( User , bytes ) ;
119- result . WriteByte ( IscCodes . CNCT_login ) ;
120- result . WriteByte ( ( byte ) real_len ) ;
121- result . Write ( bytes ) ;
122- if ( rented != null )
123- {
124- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
125- }
126- }
127- {
128- var slen = Encoding . UTF8 . GetByteCount ( _srp256 . Name ) ;
129- byte [ ] rented = null ;
130- Span < byte > bytes = slen > STACKALLOC_LIMIT
131- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
132- : stackalloc byte [ slen ] ;
133- int real_len = Encoding . UTF8 . GetBytes ( _srp256 . Name , bytes ) ;
134- result . WriteByte ( IscCodes . CNCT_plugin_name ) ;
135- result . WriteByte ( ( byte ) real_len ) ;
136- result . Write ( bytes [ ..real_len ] ) ;
137- if ( rented != null )
138- {
139- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
140- }
141- }
142- {
143- var slen = Encoding . UTF8 . GetByteCount ( _srp256 . PublicKeyHex ) ;
144- byte [ ] rented = null ;
145- Span < byte > specificData = slen > STACKALLOC_LIMIT
146- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
147- : stackalloc byte [ slen ] ;
148- Encoding . UTF8 . GetBytes ( _srp256 . PublicKeyHex . AsSpan ( ) , specificData ) ;
149- WriteMultiPartHelper ( result , IscCodes . CNCT_specific_data , specificData ) ;
150- if ( rented != null )
151- {
152- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
153- }
154- }
155- {
156- var slen1 = Encoding . UTF8 . GetByteCount ( _srp256 . Name ) ;
157- byte [ ] rented1 = null ;
158- Span < byte > bytes1 = slen1 > STACKALLOC_LIMIT
159- ? ( rented1 = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen1 ) ) . AsSpan ( 0 , slen1 )
160- : stackalloc byte [ slen1 ] ;
161- Span < byte > bytes2 = stackalloc byte [ 1 ] ;
162- var slen3 = Encoding . UTF8 . GetByteCount ( _srp . Name ) ;
163- byte [ ] rented3 = null ;
164- Span < byte > bytes3 = slen3 > STACKALLOC_LIMIT
165- ? ( rented3 = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen3 ) ) . AsSpan ( 0 , slen3 )
166- : stackalloc byte [ slen3 ] ;
167- int l1 = Encoding . UTF8 . GetBytes ( _srp256 . Name . AsSpan ( ) , bytes1 ) ;
168- int l2 = Encoding . UTF8 . GetBytes ( "," . AsSpan ( ) , bytes2 ) ;
169- int l3 = Encoding . UTF8 . GetBytes ( _srp . Name . AsSpan ( ) , bytes3 ) ;
170- result . WriteByte ( IscCodes . CNCT_plugin_list ) ;
171- result . WriteByte ( ( byte ) ( l1 + l2 + l3 ) ) ;
172- result . Write ( bytes1 ) ;
173- result . Write ( bytes2 ) ;
174- result . Write ( bytes3 ) ;
175- if ( rented1 != null )
176- {
177- System . Buffers . ArrayPool < byte > . Shared . Return ( rented1 , clearArray : true ) ;
178- }
179- if ( rented3 != null )
180- {
181- System . Buffers . ArrayPool < byte > . Shared . Return ( rented3 , clearArray : true ) ;
182- }
183- }
84+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_login , User ) ;
85+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_plugin_name , _srp256 . Name ) ;
86+
87+ var len = Encoding . UTF8 . GetBytes ( _srp256 . PublicKeyHex , scratchpad ) ;
88+ WriteMultiPartHelper ( result , IscCodes . CNCT_specific_data , scratchpad [ ..len ] ) ;
18489
90+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_plugin_list , _srp256 . Name , _srp . Name ) ;
91+
92+ result . WriteByte ( IscCodes . CNCT_client_crypt ) ;
93+ result . WriteByte ( 4 ) ;
94+ if ( ! BitConverter . TryWriteBytes ( scratchpad , IPAddress . NetworkToHostOrder ( WireCryptOptionValue ( WireCrypt ) ) ) )
18595 {
186- result . WriteByte ( IscCodes . CNCT_client_crypt ) ;
187- result . WriteByte ( 4 ) ;
188- Span < byte > bytes = stackalloc byte [ 4 ] ;
189- if ( ! BitConverter . TryWriteBytes ( bytes , IPAddress . NetworkToHostOrder ( WireCryptOptionValue ( WireCrypt ) ) ) )
190- {
191- throw new InvalidOperationException ( "Failed to write wire crypt option bytes." ) ;
192- }
193- result . Write ( bytes ) ;
96+ throw new InvalidOperationException ( "Failed to write wire crypt option bytes." ) ;
19497 }
98+ result . Write ( scratchpad [ ..4 ] ) ;
19599 }
196100 else
197101 {
198- var slen = Encoding . UTF8 . GetByteCount ( _sspi . Name ) ;
199- byte [ ] rented = null ;
200- Span < byte > pluginNameBytes = slen > STACKALLOC_LIMIT
201- ? ( rented = System . Buffers . ArrayPool < byte > . Shared . Rent ( slen ) ) . AsSpan ( 0 , slen )
202- : stackalloc byte [ slen ] ;
203- int pluginNameLen = Encoding . UTF8 . GetBytes ( _sspi . Name . AsSpan ( ) , pluginNameBytes ) ;
204- result . WriteByte ( IscCodes . CNCT_plugin_name ) ;
205- result . WriteByte ( ( byte ) pluginNameLen ) ;
206- result . Write ( pluginNameBytes [ ..pluginNameLen ] ) ;
102+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_plugin_name , _sspi . Name ) ;
207103
208104 var specificData = _sspi . InitializeClientSecurity ( ) ;
209105 WriteMultiPartHelper ( result , IscCodes . CNCT_specific_data , specificData ) ;
210106
211- result . WriteByte ( IscCodes . CNCT_plugin_list ) ;
212- result . WriteByte ( ( byte ) pluginNameLen ) ;
213- result . Write ( pluginNameBytes [ ..pluginNameLen ] ) ;
107+ WriteUserIdentificationParams ( result , scratchpad , IscCodes . CNCT_plugin_list , _sspi . Name ) ;
214108
215109 result . WriteByte ( IscCodes . CNCT_client_crypt ) ;
216110 result . WriteByte ( 4 ) ;
217- Span < byte > wireCryptBytes = stackalloc byte [ 4 ] ;
218- if ( ! BitConverter . TryWriteBytes ( wireCryptBytes , IPAddress . NetworkToHostOrder ( IscCodes . WIRE_CRYPT_DISABLED ) ) )
111+ if ( ! BitConverter . TryWriteBytes ( scratchpad , IPAddress . NetworkToHostOrder ( IscCodes . WIRE_CRYPT_DISABLED ) ) )
219112 {
220113 throw new InvalidOperationException ( "Failed to write wire crypt disabled bytes." ) ;
221114 }
222- result . Write ( wireCryptBytes ) ;
223- if ( rented != null )
224- {
225- System . Buffers . ArrayPool < byte > . Shared . Return ( rented , clearArray : true ) ;
226- }
115+ result . Write ( scratchpad [ ..4 ] ) ;
227116 }
228-
117+ scratchpad . Clear ( ) ;
229118 return result . ToArray ( ) ;
230119 }
231120 }
232121
122+ static void WriteUserIdentificationParams ( MemoryStream result , Span < byte > scratchpad , byte type , params ReadOnlySpan < string > strings )
123+ {
124+ scratchpad [ 0 ] = type ;
125+ int len = 2 ;
126+ if ( strings . Length > 0 )
127+ {
128+ len += Encoding . UTF8 . GetBytes ( strings [ 0 ] , scratchpad [ len ..] ) ;
129+ for ( int i = 1 ; i < strings . Length ; i ++ )
130+ {
131+ scratchpad [ len ++ ] = SEPARATOR_BYTE ;
132+ len += Encoding . UTF8 . GetBytes ( strings [ i ] , scratchpad [ len ..] ) ;
133+ }
134+ }
135+ scratchpad [ 1 ] = ( byte ) ( len - 2 ) ;
136+ result . Write ( scratchpad [ ..len ] ) ;
137+ }
138+
233139 public void SendContAuthToBuffer ( )
234140 {
235141 Connection . Xdr . Write ( IscCodes . op_cont_auth ) ;
0 commit comments