Skip to content

Commit 8835558

Browse files
committed
Refactored and optimized overcomplicated auth-block
1 parent f87f965 commit 8835558

File tree

1 file changed

+40
-134
lines changed
  • src/FirebirdSql.Data.FirebirdClient/Client/Managed

1 file changed

+40
-134
lines changed

src/FirebirdSql.Data.FirebirdClient/Client/Managed/AuthBlock.cs

Lines changed: 40 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)