improve locks
This commit is contained in:
parent
bb57c26dea
commit
cd581593bb
3 changed files with 130 additions and 142 deletions
|
|
@ -65,119 +65,120 @@ public class Requests
|
|||
return;
|
||||
}
|
||||
|
||||
await createLock.WaitAsync();
|
||||
try
|
||||
|
||||
switch (step)
|
||||
{
|
||||
switch (step)
|
||||
case "init":
|
||||
{
|
||||
case "init":
|
||||
foreach (var kvp in createHolder) // czyszczenie nieaktywnych od 2 minut requestow
|
||||
{
|
||||
foreach (var kvp in createHolder) // czyszczenie nieaktywnych od 2 minut requestow
|
||||
if (kvp.Value.date < DateTimeOffset.UtcNow.AddMinutes(-2))
|
||||
{
|
||||
if (kvp.Value.date < DateTimeOffset.UtcNow.AddMinutes(-2))
|
||||
{
|
||||
createHolder.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
createHolder.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.ContentType = mimeTypes["json"];
|
||||
context.Response.ContentType = mimeTypes["json"];
|
||||
|
||||
var serverInfo = Encryption.Encryption.InitHybridKEM();
|
||||
KeyExchangePayload payload = new KeyExchangePayload();
|
||||
payload.pubX25519 = Convert.ToBase64String(serverInfo.pubX25519);
|
||||
payload.pubMlKem = Convert.ToBase64String(serverInfo.pubMlKem);
|
||||
payload.idKey = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\n";
|
||||
var serverInfo = Encryption.Encryption.InitHybridKEM();
|
||||
KeyExchangePayload payload = new KeyExchangePayload();
|
||||
payload.pubX25519 = Convert.ToBase64String(serverInfo.pubX25519);
|
||||
payload.pubMlKem = Convert.ToBase64String(serverInfo.pubMlKem);
|
||||
payload.idKey = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\n";
|
||||
|
||||
while (createHolder.ContainsKey(payload.idKey))
|
||||
{
|
||||
payload.idKey += Random.Shared.Next(0, 10).ToString();
|
||||
}
|
||||
while (createHolder.ContainsKey(payload.idKey))
|
||||
{
|
||||
payload.idKey += Random.Shared.Next(0, 10).ToString();
|
||||
}
|
||||
|
||||
CreateHolder dataHolder = new();
|
||||
dataHolder.date = DateTimeOffset.UtcNow;
|
||||
dataHolder.privX25519Server = serverInfo.privX25519;
|
||||
dataHolder.privMlKemServer = serverInfo.privMlKem;
|
||||
CreateHolder dataHolder = new();
|
||||
dataHolder.date = DateTimeOffset.UtcNow;
|
||||
dataHolder.privX25519Server = serverInfo.privX25519;
|
||||
dataHolder.privMlKemServer = serverInfo.privMlKem;
|
||||
|
||||
createHolder.TryAdd(payload.idKey, dataHolder);
|
||||
createHolder.TryAdd(payload.idKey, dataHolder);
|
||||
|
||||
var serializedPayload = JsonSerializer.Serialize(
|
||||
payload,
|
||||
AppJsonSerializerContext.Default.KeyExchangePayload
|
||||
);
|
||||
var serializedPayload = JsonSerializer.Serialize(
|
||||
payload,
|
||||
AppJsonSerializerContext.Default.KeyExchangePayload
|
||||
);
|
||||
|
||||
await context.Response.WriteAsync(serializedPayload);
|
||||
await context.Response.WriteAsync(serializedPayload);
|
||||
return;
|
||||
}
|
||||
case "register":
|
||||
{
|
||||
string body = await LoadBody(bodyReader);
|
||||
|
||||
KeyExchangePayloadClient serializedBody = JsonSerializer.Deserialize(
|
||||
body,
|
||||
AppJsonSerializerContext.Default.KeyExchangePayloadClient
|
||||
);
|
||||
if (!createHolder.TryGetValue(serializedBody.idKey, out CreateHolder entry))
|
||||
{
|
||||
await context.Response.WriteAsync("error:account.creation.request.expired");
|
||||
return;
|
||||
}
|
||||
case "register":
|
||||
|
||||
entry.date = DateTimeOffset.UtcNow;
|
||||
|
||||
byte[] pubX25519Client = Convert.FromBase64String(serializedBody.pubX25519);
|
||||
byte[] ciphertextMlKem = Convert.FromBase64String(serializedBody.ciphertextMlKem);
|
||||
|
||||
byte[] sharedKey = Encryption.Encryption.CalcHybridSharedKey(
|
||||
pubX25519Client, entry.privX25519Server, ciphertextMlKem, entry.privMlKemServer);
|
||||
|
||||
|
||||
entry.name = Encryption.Encryption.Decrypt(serializedBody.username, sharedKey);
|
||||
entry.pass = Encryption.Encryption.Decrypt(serializedBody.password, sharedKey);
|
||||
|
||||
if (!Utils.IsValidUsername(entry.name, out string message))
|
||||
{
|
||||
string body = await LoadBody(bodyReader);
|
||||
|
||||
KeyExchangePayloadClient serializedBody = JsonSerializer.Deserialize(
|
||||
body,
|
||||
AppJsonSerializerContext.Default.KeyExchangePayloadClient
|
||||
);
|
||||
if (!createHolder.TryGetValue(serializedBody.idKey, out CreateHolder entry))
|
||||
{
|
||||
await context.Response.WriteAsync("error:account.creation.request.expired");
|
||||
return;
|
||||
}
|
||||
|
||||
entry.date = DateTimeOffset.UtcNow;
|
||||
|
||||
byte[] pubX25519Client = Convert.FromBase64String(serializedBody.pubX25519);
|
||||
byte[] ciphertextMlKem = Convert.FromBase64String(serializedBody.ciphertextMlKem);
|
||||
|
||||
byte[] sharedKey = Encryption.Encryption.CalcHybridSharedKey(
|
||||
pubX25519Client, entry.privX25519Server, ciphertextMlKem, entry.privMlKemServer);
|
||||
|
||||
|
||||
entry.name = Encryption.Encryption.Decrypt(serializedBody.username, sharedKey);
|
||||
entry.pass = Encryption.Encryption.Decrypt(serializedBody.password, sharedKey);
|
||||
|
||||
if (!Utils.IsValidUsername(entry.name, out string message))
|
||||
{
|
||||
await context.Response.WriteAsync(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Utils.IsValidPassword(entry.pass, out message))
|
||||
{
|
||||
await context.Response.WriteAsync(message);
|
||||
return;
|
||||
}
|
||||
|
||||
(byte[] ImageBytes, string CaptchaText) captchaResult = Captcha.GenerateCaptcha();
|
||||
entry.captcha = captchaResult.CaptchaText;
|
||||
context.Response.ContentType = mimeTypes["webp"];
|
||||
context.Response.ContentLength = captchaResult.ImageBytes.Length;
|
||||
|
||||
await context.Response.Body.WriteAsync(captchaResult.ImageBytes, 0,
|
||||
captchaResult.ImageBytes.Length);
|
||||
await context.Response.WriteAsync(message);
|
||||
return;
|
||||
}
|
||||
case "finish":
|
||||
|
||||
if (!Utils.IsValidPassword(entry.pass, out message))
|
||||
{
|
||||
string body = await LoadBody(bodyReader);
|
||||
|
||||
CaptchaPayloadClient serialized = JsonSerializer.Deserialize(
|
||||
body,
|
||||
AppJsonSerializerContext.Default.CaptchaPayloadClient
|
||||
);
|
||||
if (!createHolder.TryGetValue(serialized.idKey, out var entry))
|
||||
{
|
||||
await context.Response.WriteAsync("error:account.creation.request.expired");
|
||||
return;
|
||||
}
|
||||
await context.Response.WriteAsync(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.captcha.ToLower() != serialized.captcha.ToLower())
|
||||
{
|
||||
createHolder.TryRemove(serialized.idKey, out _);
|
||||
await context.Response.WriteAsync("error:incorrect.captcha");
|
||||
return;
|
||||
}
|
||||
(byte[] ImageBytes, string CaptchaText) captchaResult = Captcha.GenerateCaptcha();
|
||||
entry.captcha = captchaResult.CaptchaText;
|
||||
context.Response.ContentType = mimeTypes["webp"];
|
||||
context.Response.ContentLength = captchaResult.ImageBytes.Length;
|
||||
|
||||
string lowerName = entry.name.ToLowerInvariant();
|
||||
await context.Response.Body.WriteAsync(captchaResult.ImageBytes, 0,
|
||||
captchaResult.ImageBytes.Length);
|
||||
return;
|
||||
}
|
||||
case "finish":
|
||||
{
|
||||
string body = await LoadBody(bodyReader);
|
||||
|
||||
CaptchaPayloadClient serialized = JsonSerializer.Deserialize(
|
||||
body,
|
||||
AppJsonSerializerContext.Default.CaptchaPayloadClient
|
||||
);
|
||||
if (!createHolder.TryGetValue(serialized.idKey, out var entry))
|
||||
{
|
||||
await context.Response.WriteAsync("error:account.creation.request.expired");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.captcha.ToLower() != serialized.captcha.ToLower())
|
||||
{
|
||||
createHolder.TryRemove(serialized.idKey, out _);
|
||||
await context.Response.WriteAsync("error:incorrect.captcha");
|
||||
return;
|
||||
}
|
||||
|
||||
string lowerName = entry.name.ToLowerInvariant();
|
||||
|
||||
await createLock.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (Fs.Exists($"{ACCOUNTS_NAME_DIR}/{lowerName}"))
|
||||
{
|
||||
await context.Response.WriteAsync("error:username.taken");
|
||||
|
|
@ -229,7 +230,6 @@ public class Requests
|
|||
await Fs.WriteFile($"{ACCOUNTS_DIR}/registration", Encoding.UTF8.GetBytes("0;"));
|
||||
}
|
||||
|
||||
|
||||
ulong id = ulong.Parse(await Fs.ReadFile($"{ACCOUNTS_DIR}/last"));
|
||||
id++;
|
||||
var freeid = Path.GetFileName(Directory.EnumerateFiles(ACCOUNTS_FREEID_DIR).FirstOrDefault());
|
||||
|
|
@ -270,17 +270,19 @@ public class Requests
|
|||
await context.Response.WriteAsync("success:account.created");
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
createLock.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await next();
|
||||
}
|
||||
finally
|
||||
{
|
||||
createLock.Release();
|
||||
}
|
||||
await next();
|
||||
}
|
||||
|
||||
public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollection query, StreamReader bodyReader)
|
||||
|
||||
|
||||
public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollection query, StreamReader bodyReader)
|
||||
{
|
||||
if (!query.TryGetValue("id", out var idQuery))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue