Updated REST to use an RNGCryptoServiceProvider for more secure random numbers involved in token generation.
Also removes some unnecessary limitations. Closes #1388
This commit is contained in:
parent
94fb0e18b7
commit
26010c0acf
1 changed files with 7 additions and 6 deletions
|
|
@ -25,6 +25,7 @@ using TShockAPI;
|
||||||
using TShockAPI.DB;
|
using TShockAPI.DB;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Terraria;
|
using Terraria;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace Rests
|
namespace Rests
|
||||||
{
|
{
|
||||||
|
|
@ -41,6 +42,8 @@ namespace Rests
|
||||||
public Dictionary<string, TokenData> Tokens { get; protected set; }
|
public Dictionary<string, TokenData> Tokens { get; protected set; }
|
||||||
public Dictionary<string, TokenData> AppTokens { get; protected set; }
|
public Dictionary<string, TokenData> AppTokens { get; protected set; }
|
||||||
|
|
||||||
|
private RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
|
||||||
|
|
||||||
public SecureRest(IPAddress ip, int port)
|
public SecureRest(IPAddress ip, int port)
|
||||||
: base(ip, port)
|
: base(ip, port)
|
||||||
{
|
{
|
||||||
|
|
@ -112,7 +115,7 @@ namespace Rests
|
||||||
int tokens = 0;
|
int tokens = 0;
|
||||||
if (tokenBucket.TryGetValue(context.RemoteEndPoint.Address.ToString(), out tokens))
|
if (tokenBucket.TryGetValue(context.RemoteEndPoint.Address.ToString(), out tokens))
|
||||||
{
|
{
|
||||||
if (tokens >= Math.Max(TShock.Config.RESTMaximumRequestsPerInterval, 5))
|
if (tokens >= TShock.Config.RESTMaximumRequestsPerInterval)
|
||||||
{
|
{
|
||||||
TShock.Log.ConsoleError("A REST login from {0} was blocked as it currently has {1} tokens", context.RemoteEndPoint.Address.ToString(), tokens);
|
TShock.Log.ConsoleError("A REST login from {0} was blocked as it currently has {1} tokens", context.RemoteEndPoint.Address.ToString(), tokens);
|
||||||
tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens over limit, increment by one and reject request
|
tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens over limit, increment by one and reject request
|
||||||
|
|
@ -121,8 +124,7 @@ namespace Rests
|
||||||
Error = "Username or password may be incorrect or this account may not have sufficient privileges."
|
Error = "Username or password may be incorrect or this account may not have sufficient privileges."
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!TShock.Config.RESTLimitOnlyFailedLoginRequests)
|
tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens under limit, increment by one and process request
|
||||||
tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens under limit, increment by one and process request
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -150,13 +152,12 @@ namespace Rests
|
||||||
return new RestObject("403")
|
return new RestObject("403")
|
||||||
{ Error = "Username or password may be incorrect or this account may not have sufficient privileges." };
|
{ Error = "Username or password may be incorrect or this account may not have sufficient privileges." };
|
||||||
}
|
}
|
||||||
|
|
||||||
string tokenHash;
|
string tokenHash;
|
||||||
var rand = new Random();
|
|
||||||
var randbytes = new byte[32];
|
var randbytes = new byte[32];
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rand.NextBytes(randbytes);
|
_rng.GetBytes(randbytes);
|
||||||
tokenHash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
tokenHash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||||
} while (Tokens.ContainsKey(tokenHash));
|
} while (Tokens.ContainsKey(tokenHash));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue