Skip to content

Commit

Permalink
dev
Browse files Browse the repository at this point in the history
  • Loading branch information
immisterio committed Nov 12, 2022
1 parent 9c565a3 commit cf4a51a
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 44 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
/Properties
/TSApi.csproj.user
/obj
/bin/Release/net5.0
/.vs/TSApi
/bin
/.vs
7 changes: 3 additions & 4 deletions Controllers/CronController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
Expand All @@ -19,7 +18,7 @@ public string UpdateUsersDb()
return "ip != 127.0.0.1";

if (System.IO.File.Exists($"{Startup.settings.appfolder}/usersDb.json"))
Startup.usersDb = JsonConvert.DeserializeObject<Dictionary<string, UserData>>(System.IO.File.ReadAllText($"{Startup.settings.appfolder}/usersDb.json"));
Startup.usersDb = JsonConvert.DeserializeObject<ConcurrentDictionary<string, UserData>>(System.IO.File.ReadAllText($"{Startup.settings.appfolder}/usersDb.json"));

return "ok";
}
Expand All @@ -44,8 +43,8 @@ async public Task<string> CheckingNodes()
{
if (node.Value.countError >= 2 || DateTime.Now.AddMinutes(-Startup.settings.worknodetominutes) > node.Value.lastActive)
{
TorAPI.db.TryRemove(node.Key, out _);
node.Value.Dispose();
TorAPI.db.Remove(node.Key);
}
else
{
Expand Down
43 changes: 25 additions & 18 deletions Engine/Middlewares/Accs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,27 @@ public Accs(RequestDelegate next, IMemoryCache memoryCache)
#endregion

#region IsLockHostOrUser
bool IsLockHostOrUser(HttpContext httpContext, string login)
bool IsLockHostOrUser(HttpContext httpContext, UserData user, out HashSet<string> ips)
{
string memKeyLocIP = $"memKeyLocIP:{login}:{DateTime.Today.Day}";
string memKeyLocIP = $"memKeyLocIP:{user.login}:{DateTime.Today.Day}";
string clientIP = httpContext.Connection.RemoteIpAddress.ToString();

if (memoryCache.TryGetValue(memKeyLocIP, out HashSet<string> _ips))
if (memoryCache.TryGetValue(memKeyLocIP, out ips))
{
_ips.Add(clientIP);
memoryCache.Set(memKeyLocIP, _ips, DateTime.Today.AddDays(1));
ips.Add(clientIP);
memoryCache.Set(memKeyLocIP, ips, DateTime.Today.AddDays(1));

if (_ips.Count >= Startup.settings.maxiptoIsLockHostOrUser)
int maxiptoIsLockHostOrUser = Startup.settings.maxiptoIsLockHostOrUser;
if (user.maxiptoIsLockHostOrUser > 0)
maxiptoIsLockHostOrUser = user.maxiptoIsLockHostOrUser;

if (ips.Count > maxiptoIsLockHostOrUser)
return true;
}
else
{
_ips = new HashSet<string>() { clientIP };
memoryCache.Set(memKeyLocIP, _ips, DateTime.Today.AddDays(1));
ips = new HashSet<string>() { clientIP };
memoryCache.Set(memKeyLocIP, ips, DateTime.Today.AddDays(1));
}

return false;
Expand All @@ -58,9 +62,6 @@ public Task Invoke(HttpContext httpContext)
#endregion

#region Методы работающие без авторизации
if (httpContext.Request.Path.Value.StartsWith("/echo"))
return httpContext.Response.WriteAsync("MatriX.API");

if (httpContext.Request.Path.Value.StartsWith("/shutdown"))
return httpContext.Response.WriteAsync("");
#endregion
Expand All @@ -74,10 +75,11 @@ public Task Invoke(HttpContext httpContext)
UserData _domainUser = Startup.usersDb.FirstOrDefault(i => i.Value.domainid == domainid).Value;
if (_domainUser != null)
{
if (!_domainUser.IsShared && IsLockHostOrUser(httpContext, _domainUser.login))
if (!_domainUser.IsShared && IsLockHostOrUser(httpContext, _domainUser, out HashSet<string> ips))
{
httpContext.Response.StatusCode = 403;
return httpContext.Response.WriteAsync($"you ban to {DateTime.Today.AddDays(1).ToString("dd.MM.yyyy hh:mm")}, server time {DateTime.Now.ToString("dd.MM.yyyy hh:mm")}");
httpContext.Response.ContentType = "text/plain; charset=UTF-8";
return httpContext.Response.WriteAsync($"Превышено допустимое количество ip. Разбан через {(int)(DateTime.Today.AddDays(1) - DateTime.Now).TotalMinutes} мин.\n\n" + string.Join(", ", ips));
}

httpContext.Features.Set(_domainUser);
Expand All @@ -90,18 +92,19 @@ public Task Invoke(HttpContext httpContext)
{
if (TorAPI.db.LastOrDefault(i => i.Value.clientIps.Contains(clientIp)).Value is TorInfo info)
{
if (!info.user.IsShared && IsLockHostOrUser(httpContext, info.user.login))
if (!info.user.IsShared && IsLockHostOrUser(httpContext, info.user, out HashSet<string> ips))
{
httpContext.Response.StatusCode = 403;
return httpContext.Response.WriteAsync($"you ban to {DateTime.Today.AddDays(1).ToString("dd.MM.yyyy hh:mm")}, server time {DateTime.Now.ToString("dd.MM.yyyy hh:mm")}");
httpContext.Response.ContentType = "text/plain; charset=UTF-8";
return httpContext.Response.WriteAsync($"Превышено допустимое количество ip. Разбан через {(int)(DateTime.Today.AddDays(1) - DateTime.Now).TotalMinutes} мин.\n\n" + string.Join(", ", ips));
}

httpContext.Features.Set(info.user);
return _next(httpContext);
}
else
{
httpContext.Response.StatusCode = 403;
httpContext.Response.StatusCode = 404;
return Task.CompletedTask;
}
}
Expand All @@ -125,17 +128,21 @@ public Task Invoke(HttpContext httpContext)

if (Startup.usersDb.TryGetValue(login, out UserData _u) && _u.passwd == passwd)
{
if (!_u.IsShared && IsLockHostOrUser(httpContext, _u.login))
if (!_u.IsShared && IsLockHostOrUser(httpContext, _u, out HashSet<string> ips))
{
httpContext.Response.StatusCode = 403;
return httpContext.Response.WriteAsync($"you ban to {DateTime.Today.AddDays(1).ToString("dd.MM.yyyy hh:mm")}, server time {DateTime.Now.ToString("dd.MM.yyyy hh:mm")}");
httpContext.Response.ContentType = "text/plain; charset=UTF-8";
return httpContext.Response.WriteAsync($"Превышено допустимое количество ip. Разбан через {(int)(DateTime.Today.AddDays(1) - DateTime.Now).TotalMinutes} мин.\n\n" + string.Join(", ", ips));
}

httpContext.Features.Set(_u);
return _next(httpContext);
}
}

if (httpContext.Request.Path.Value.StartsWith("/echo"))
return httpContext.Response.WriteAsync("MatriX.API");

httpContext.Response.StatusCode = 401;
httpContext.Response.Headers.Add("Www-Authenticate", "Basic realm=Authorization Required");
return Task.CompletedTask;
Expand Down
35 changes: 23 additions & 12 deletions Engine/Middlewares/TorAPI.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using TSApi.Models;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System;
using System.Threading;
Expand All @@ -20,7 +20,7 @@ public class TorAPI

static Random random = new Random();

public static Dictionary<string, TorInfo> db = new Dictionary<string, TorInfo>();
public static ConcurrentDictionary<string, TorInfo> db = new ConcurrentDictionary<string, TorInfo>();

public TorAPI(RequestDelegate next)
{
Expand Down Expand Up @@ -49,11 +49,15 @@ async public static ValueTask<bool> CheckPort(int port, HttpContext httpContext)
{
client.Timeout = TimeSpan.FromSeconds(2);

var response = await client.GetAsync($"http://127.0.0.1:{port}", HttpCompletionOption.ResponseHeadersRead, httpContext.RequestAborted);
var response = await client.GetAsync($"http://127.0.0.1:{port}/echo", httpContext.RequestAborted);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
servIsWork = true;
break;
string echo = await response.Content.ReadAsStringAsync();
if (echo.StartsWith("MatriX."))
{
servIsWork = true;
break;
}
}
}
}
Expand Down Expand Up @@ -90,17 +94,23 @@ async public Task InvokeAsync(HttpContext httpContext)
if (!db.TryGetValue(dbKeyOrLogin, out TorInfo info))
{
string inDir = Startup.settings.appfolder;
string torPath = userData.torPath ?? "master";

string domaintoPath = Regex.Match(httpContext.Request.Host.Value, "^[^\\.]+\\.([0-9]+)\\.").Groups[1].Value;
string torPath = userData.torPath ?? (File.Exists($"{inDir}/dl/{domaintoPath}/TorrServer-linux-amd64") ? domaintoPath : "master");

#region TorInfo
info = new TorInfo()
{
user = userData,
port = random.Next(60000, 62000),
port = random.Next(40000, 60000),
lastActive = DateTime.Now
};

db.Add(dbKeyOrLogin, info);
if (!db.TryAdd(dbKeyOrLogin, info))
{
await httpContext.Response.WriteAsync("error: db.TryAdd(dbKeyOrLogin, info)");
return;
}
#endregion

#region Создаем папку пользователя
Expand Down Expand Up @@ -156,17 +166,17 @@ async public Task InvokeAsync(HttpContext httpContext)
#region Проверяем доступность сервера
if (await CheckPort(info.port, httpContext) == false)
{
db.TryRemove(dbKeyOrLogin, out _);
info.Dispose();
db.Remove(dbKeyOrLogin);
return;
}
#endregion

#region Отслеживанием падение процесса
info.processForExit += (s, e) =>
{
db.TryRemove(dbKeyOrLogin, out _);
info.Dispose();
db.Remove(dbKeyOrLogin);
};
#endregion
}
Expand All @@ -187,7 +197,7 @@ async public Task InvokeAsync(HttpContext httpContext)

using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(2);
client.Timeout = TimeSpan.FromSeconds(15);

#region Данные запроса
MemoryStream mem = new MemoryStream();
Expand Down Expand Up @@ -218,6 +228,7 @@ async public Task InvokeAsync(HttpContext httpContext)

settingsJson = Regex.Replace(settingsJson, "\"ReaderReadAHead\":([0-9]+)", $"\"ReaderReadAHead\":{ReaderReadAHead}", RegexOptions.IgnoreCase);
settingsJson = Regex.Replace(settingsJson, "\"PreloadCache\":([0-9]+)", $"\"PreloadCache\":{PreloadCache}", RegexOptions.IgnoreCase);
settingsJson = "{\"action\":\"set\",\"sets\":" + settingsJson + "}";

await client.PostAsync($"http://127.0.0.1:{info.port}/settings", new StringContent(settingsJson, Encoding.UTF8, "application/json"));
#endregion
Expand Down Expand Up @@ -266,7 +277,7 @@ HttpRequestMessage CreateProxyHttpRequest(HttpContext context, Uri uri)
}
}

requestMessage.Headers.Host = uri.Authority;
requestMessage.Headers.Host = context.Request.Host.Value;// uri.Authority;
requestMessage.RequestUri = uri;
requestMessage.Method = new HttpMethod(request.Method);

Expand Down
9 changes: 9 additions & 0 deletions Models/Known.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TSApi.Models
{
public class Known
{
public string ip { get; set; }

public int prefixLength { get; set; }
}
}
2 changes: 1 addition & 1 deletion Models/Setting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public class Setting

public bool AuthorizationRequired { get; set; } = true;

public List<(string ip, int prefixLength)> KnownProxies { get; set; } = new List<(string, int)>();
public HashSet<Known> KnownProxies { get; set; } = new HashSet<Known>();
}
}
3 changes: 3 additions & 0 deletions Models/UserData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ public class UserData

[JsonIgnore]
public bool IsShared { get; set; }

[JsonIgnore]
public byte maxiptoIsLockHostOrUser { get; set; }
}
}
4 changes: 2 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Program
{
public static void Main(string[] args)
{
string appfolder = "/opt/TSApi";
string appfolder = "/opt/tsapi";

foreach (var line in args)
{
Expand All @@ -23,7 +23,7 @@ public static void Main(string[] args)
{
case "d":
{
// -d=/opt/TSApi
// -d=/opt/tsapi
appfolder = value;
break;
}
Expand Down
8 changes: 4 additions & 4 deletions Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Microsoft.Extensions.DependencyInjection;
using System.Text.Json.Serialization;
using TSApi.Engine.Middlewares;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Newtonsoft.Json;
using TSApi.Models;
using System.Net;
Expand All @@ -13,7 +13,7 @@ namespace TSApi
{
public class Startup
{
public static Dictionary<string, UserData> usersDb = new Dictionary<string, UserData>();
public static ConcurrentDictionary<string, UserData> usersDb = new ConcurrentDictionary<string, UserData>();

public static Setting settings = new Setting();

Expand All @@ -36,11 +36,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
#region load usersDb.json
if (System.IO.File.Exists($"{settings.appfolder}/usersDb.json"))
{
usersDb = JsonConvert.DeserializeObject<Dictionary<string, UserData>>(System.IO.File.ReadAllText($"{settings.appfolder}/usersDb.json"));
usersDb = JsonConvert.DeserializeObject<ConcurrentDictionary<string, UserData>>(System.IO.File.ReadAllText($"{settings.appfolder}/usersDb.json"));
}
else
{
usersDb = new Dictionary<string, UserData>()
usersDb = new ConcurrentDictionary<string, UserData>()
{
["ts"] = new UserData()
{
Expand Down
2 changes: 1 addition & 1 deletion TSApi.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<UserSecretsId>88dba83d-18a4-4477-811f-067572d28f09</UserSecretsId>
<AssemblyName>TSApi</AssemblyName>
<RootNamespace>TSApi</RootNamespace>
Expand Down

0 comments on commit cf4a51a

Please sign in to comment.