SHA256 Hashing for AuthToken Complete
This commit is contained in:
@@ -25,7 +25,8 @@ public class FPSTemplate : ModuleRules
|
|||||||
{
|
{
|
||||||
"GameplayTags",
|
"GameplayTags",
|
||||||
"Slate",
|
"Slate",
|
||||||
"SlateCore"
|
"SlateCore",
|
||||||
|
"OpenSSL",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Adds in the plugin for GameLiftServerSDK if it is the server build.
|
// Adds in the plugin for GameLiftServerSDK if it is the server build.
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
#include "Game/ShooterGameMode.h"
|
#include "Game/ShooterGameMode.h"
|
||||||
|
#include "GenericPlatform/GenericPlatformMisc.h"
|
||||||
|
#include "Containers/UnrealString.h"
|
||||||
#include "GameLiftClpTypes.h"
|
#include "GameLiftClpTypes.h"
|
||||||
#include "GameLift/GameLiftClp.h"
|
#include "GameLift/GameLiftClp.h"
|
||||||
|
#include "openssl/sha.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DEFINE_LOG_CATEGORY(LogShooterGameMode);
|
DEFINE_LOG_CATEGORY(LogShooterGameMode);
|
||||||
@@ -45,8 +48,34 @@ void AShooterGameMode::InitGame(const FString& MapName, const FString& Options,
|
|||||||
|
|
||||||
FString AShooterGameMode::GetSHA256Hash(const FString& InString)
|
FString AShooterGameMode::GetSHA256Hash(const FString& InString)
|
||||||
{
|
{
|
||||||
if (InString.IsEmpty()) return TEXT("da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
|
||||||
|
|
||||||
|
// if (InString.IsEmpty()) return TEXT("da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
||||||
|
|
||||||
|
if (InString.IsEmpty())
|
||||||
|
return TEXT("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||||
|
|
||||||
|
FSHA256Signature Hash;
|
||||||
|
|
||||||
|
// Use OpenSSL to compute the SHA-256 hash
|
||||||
|
|
||||||
|
FTCHARToUTF8 Utf8(InString);
|
||||||
|
const uint8* Bytes = reinterpret_cast<const uint8*>(Utf8.Get());
|
||||||
|
uint32 Length = Utf8.Length() * sizeof(UTF8CHAR);
|
||||||
|
|
||||||
|
|
||||||
|
SHA256_CTX Sha256Context;
|
||||||
|
SHA256_Init(&Sha256Context);
|
||||||
|
SHA256_Update(&Sha256Context, Bytes,Length);
|
||||||
|
SHA256_Final(Hash.Signature, &Sha256Context);
|
||||||
|
|
||||||
|
return Hash.ToString();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
FSHA1 Sha;
|
FSHA1 Sha;
|
||||||
FTCHARToUTF8 Utf8(InString);
|
FTCHARToUTF8 Utf8(InString);
|
||||||
Sha.Update((uint8*)Utf8.Get(), Utf8.Length() * sizeof(UTF8CHAR));
|
Sha.Update((uint8*)Utf8.Get(), Utf8.Length() * sizeof(UTF8CHAR));
|
||||||
@@ -57,7 +86,7 @@ FString AShooterGameMode::GetSHA256Hash(const FString& InString)
|
|||||||
// 40-char hex (SHA1 = 160 bits)
|
// 40-char hex (SHA1 = 160 bits)
|
||||||
return FString::Printf(TEXT("%08X%08X%08X%08X%08X"),
|
return FString::Printf(TEXT("%08X%08X%08X%08X%08X"),
|
||||||
Hash[0], Hash[1], Hash[2], Hash[3], Hash[4]);
|
Hash[0], Hash[1], Hash[2], Hash[3], Hash[4]);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AShooterGameMode::InitGameLift()
|
void AShooterGameMode::InitGameLift()
|
||||||
|
|||||||
@@ -1,160 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "GameLift/GameLiftValidators.h"
|
|
||||||
|
|
||||||
#include "Game/ShooterGameMode.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///Lazy Singleton
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TArray<FString>& UGameLiftValidators::GetPatterns()
|
|
||||||
{
|
|
||||||
static TArray<FString> Patterns;
|
|
||||||
if (Patterns.Num() == 0)
|
|
||||||
{
|
|
||||||
Patterns.AddDefaulted(static_cast<int32>(EGameLiftParams::Max));
|
|
||||||
Patterns[static_cast<int32>(EGameLiftParams::AuthToken)] =
|
|
||||||
TEXT("^[a-zA-Z0-9\\-]+$"); // AuthToken
|
|
||||||
Patterns[static_cast<int32>(EGameLiftParams::FleetId)] =
|
|
||||||
TEXT("^[a-z]*fleet-[a-zA-Z0-9\\-]+$|^arn:.*:[a-z]*fleet\\/[a-z]*fleet-[a-zA-Z0-9\\-]+$"); // FleetId
|
|
||||||
Patterns[static_cast<int32>(EGameLiftParams::HostId)] =
|
|
||||||
TEXT("^[0-9A-Z]\\d+$"); // HostId
|
|
||||||
Patterns[static_cast<int32>(EGameLiftParams::WebSocketUrl)] =
|
|
||||||
TEXT("^wss:\\/\\/[a-zA-Z0-9.-]+(\\.amazonaws\\.com)?(\\/[^\\s]*)?$"); // WebSocketUrl
|
|
||||||
Patterns[static_cast<int32>(EGameLiftParams::ServerRegion)] =
|
|
||||||
TEXT("^[a-z]{2}-[a-z]+-[0-9]$"); // Region (ca-central-1)
|
|
||||||
}
|
|
||||||
return Patterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool UGameLiftValidators::IsMatchesRegex(const FString& Value, EGameLiftParams ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < EGameLiftParams::Max);
|
|
||||||
ensure(GetPatterns().Num() > static_cast<int32>(ParamType));
|
|
||||||
const FRegexPattern Pattern = FRegexPattern(GetPatterns()[static_cast<int32>(ParamType)]);
|
|
||||||
FRegexMatcher TestMatcher(Pattern, Value);
|
|
||||||
return TestMatcher.FindNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool UGameLiftValidators::IsStringValid(const FString& Value, EGameLiftParams ParamType)
|
|
||||||
{
|
|
||||||
// Checks to make sure the ParamType is not the sentinel
|
|
||||||
ensure(ParamType < EGameLiftParams::Max);
|
|
||||||
|
|
||||||
if (Value.IsEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const int32 Len = Value.Len();
|
|
||||||
const int32 Index = static_cast<int32>(ParamType);
|
|
||||||
|
|
||||||
if (Len < MinLengths[Index] || Len > MaxLengths[Index]) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UGameLiftValidators::IsStringShort(const FString& Value, EGameLiftParams ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < EGameLiftParams::Max);
|
|
||||||
if (Value.IsEmpty()) return false;
|
|
||||||
const int32 Len = Value.Len();
|
|
||||||
const int32 Index = static_cast<int32>(ParamType);
|
|
||||||
if (Len < MinLengths[Index]) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UGameLiftValidators::IsStringLong(const FString& Value, EGameLiftParams ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < EGameLiftParams::Max);
|
|
||||||
if (Value.IsEmpty()) return false;
|
|
||||||
const int32 Len = Value.Len();
|
|
||||||
const int32 Index = static_cast<int32>(ParamType);
|
|
||||||
if (Len > MaxLengths[Index]) return true;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
FParamResult UGameLiftValidators::ValidateParam(const FString& Value, const EGameLiftParams ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < EGameLiftParams::Max);
|
|
||||||
bool bErrorTriggered = false;
|
|
||||||
FParamResult Result;
|
|
||||||
Result.ParamType = ParamType;
|
|
||||||
|
|
||||||
// Quick empty check
|
|
||||||
if (Value.IsEmpty() && !bErrorTriggered)
|
|
||||||
{
|
|
||||||
Result.bValid = false;
|
|
||||||
Result.ErrorMessage = FString::Format(TEXT("Missing {0} in command line arguments"), {GetParameterFromEnum(ParamType)});
|
|
||||||
Result.ErrorCode = EValidationError::Empty;
|
|
||||||
bErrorTriggered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsStringShort(Value, ParamType) && !bErrorTriggered)
|
|
||||||
{
|
|
||||||
Result.bValid = false;
|
|
||||||
Result.Value = Value;
|
|
||||||
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} does not meet minimum length requirements."), { GetParameterFromEnum(ParamType)} );
|
|
||||||
Result.ErrorCode = EValidationError::TooShort;
|
|
||||||
bErrorTriggered = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsStringLong(Value, ParamType) && !bErrorTriggered)
|
|
||||||
{
|
|
||||||
Result.bValid = false;
|
|
||||||
Result.Value = Value;
|
|
||||||
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} does not meet maximum length requirements."), { GetParameterFromEnum(ParamType)} );
|
|
||||||
Result.ErrorCode = EValidationError::TooLong;
|
|
||||||
bErrorTriggered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsMatchesRegex(Value, ParamType) && !bErrorTriggered)
|
|
||||||
{
|
|
||||||
Result.bValid = false;
|
|
||||||
Result.Value = Value;
|
|
||||||
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} has an invalid format."), { GetParameterFromEnum(ParamType)} );
|
|
||||||
Result.ErrorCode = EValidationError::InvalidFormat;
|
|
||||||
bErrorTriggered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bErrorTriggered)
|
|
||||||
{
|
|
||||||
Result.bValid = true;
|
|
||||||
Result.Value = Value;
|
|
||||||
Result.ErrorMessage = FString("");
|
|
||||||
Result.ErrorCode = EValidationError::None;
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString UGameLiftValidators::GetParameterFromEnum(const EGameLiftParams InParam)
|
|
||||||
{
|
|
||||||
ensure(InParam < EGameLiftParams::Max);
|
|
||||||
const FString FullParameter = UEnum::GetValueAsString(InParam);
|
|
||||||
FString Left, Right;
|
|
||||||
FullParameter.Split(TEXT("::"), &Left, &Right);
|
|
||||||
const FString NameOnly = Right;
|
|
||||||
return NameOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString UGameLiftValidators::GetErrorFromEnum(EValidationError InParam)
|
|
||||||
{
|
|
||||||
ensure(InParam <= EValidationError::NotFound);
|
|
||||||
const FString FullParameter = UEnum::GetValueAsString(InParam);
|
|
||||||
FString Left, Right;
|
|
||||||
FullParameter.Split(TEXT("::"), &Left, &Right);
|
|
||||||
const FString NameOnly = Right;
|
|
||||||
return NameOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UGameLiftValidators::LogValidationErrorMessage(FParamResult ValidationResult)
|
|
||||||
{
|
|
||||||
if (ValidationResult.ErrorCode == EValidationError::None) return; // no error logging required
|
|
||||||
UE_LOGFMT(LogShooterGameMode, Error, "{0}", ValidationResult.ErrorMessage);
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#include "GameLift/GameLiftValidators_old.h"
|
|
||||||
|
|
||||||
namespace GameLiftValidators2
|
|
||||||
{
|
|
||||||
inline const FRegexPattern& GetPattern(ECliParam ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < ECliParam::Max);
|
|
||||||
static const FRegexPattern Patterns[static_cast<int32>(ECliParam::Max)] =
|
|
||||||
{
|
|
||||||
FRegexPattern(TEXT("^[a-zA-Z0-9\\-]+$")), // AuthToken
|
|
||||||
FRegexPattern(TEXT("^[a-z]*fleet-[a-zA-Z0-9\\-]+$|^arn:.*:[a-z]*fleet\\/[a-z]*fleet-[a-zA-Z0-9\\-]+$")), // FleetId
|
|
||||||
FRegexPattern(TEXT("^[0-9A-Z]\\d+$")), // HostId
|
|
||||||
FRegexPattern(TEXT("^wss:\\/\\/[a-zA-Z0-9.-]+(\\.amazonaws\\.com)?(\\/[^\\s]*)?$")), // WebSocketUrl
|
|
||||||
FRegexPattern(TEXT("^[a-z]{2}-[a-z]+-[0-9]$")), // Region (ca-central-1)
|
|
||||||
};
|
|
||||||
return Patterns[static_cast<int32>(ParamType)];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int32 MaxLengths[static_cast<int32>(ECliParam::Max)] =
|
|
||||||
{
|
|
||||||
64, //authToken
|
|
||||||
512, //FleetId
|
|
||||||
128, //HostId
|
|
||||||
128, //WebSocketUrl
|
|
||||||
16, //Region (ca-central-1)
|
|
||||||
};
|
|
||||||
|
|
||||||
inline int32 GetMaxLength(ECliParam ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < ECliParam::Max);
|
|
||||||
return MaxLengths[static_cast<int32>(ParamType)];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int32 MinLengths[static_cast<int32>(ECliParam::Max)] =
|
|
||||||
{
|
|
||||||
1, //authToken
|
|
||||||
1, //FleetId
|
|
||||||
1, //HostId
|
|
||||||
1, //WebSocketUrl
|
|
||||||
3, //Region (ca-central-1)
|
|
||||||
};
|
|
||||||
|
|
||||||
inline int32 GetMinLength(ECliParam ParamType)
|
|
||||||
{
|
|
||||||
ensure(ParamType < ECliParam::Max);
|
|
||||||
return MinLengths[static_cast<int32>(ParamType)];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool IsStringValid(const FString& Value, ECliParam ParamType)
|
|
||||||
{
|
|
||||||
|
|
||||||
ensure(ParamType < ECliParam::Max);
|
|
||||||
if (Value.IsEmpty()) return false;
|
|
||||||
|
|
||||||
if (const int32 Len = Value.Len(); (Len < GetMinLength(ParamType)) || (Len > GetMaxLength(ParamType)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const FRegexPattern& Pattern = GetPattern(ParamType);
|
|
||||||
FRegexMatcher StringMatcher(Pattern, Value);
|
|
||||||
return StringMatcher.FindNext() && StringMatcher.GetMatchEnding() == Value.Len(); // returns true on a full or partial match
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
|
||||||
#include "GameLiftValidators.generated.h"
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EGameLiftParams : uint8
|
|
||||||
{
|
|
||||||
AuthToken,
|
|
||||||
FleetId,
|
|
||||||
HostId,
|
|
||||||
ServerRegion,
|
|
||||||
WebSocketUrl,
|
|
||||||
Max // Sentry to determine length of EGameLiftParams
|
|
||||||
};
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EValidationError : uint8
|
|
||||||
{
|
|
||||||
None, // Valid
|
|
||||||
Empty, // Missing Parameter
|
|
||||||
TooShort, // Too Short
|
|
||||||
TooLong, // Too long
|
|
||||||
InvalidFormat, // Invalid format
|
|
||||||
NotFound // Sentinel value, any new error codes get put above this.
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FParamResult
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
EGameLiftParams ParamType;
|
|
||||||
FString Value;
|
|
||||||
bool bValid;
|
|
||||||
FString ErrorMessage;
|
|
||||||
EValidationError ErrorCode;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class FPSTEMPLATE_API UGameLiftValidators : public UBlueprintFunctionLibrary
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
private:
|
|
||||||
static TArray<FString>& GetPatterns();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static constexpr int32 MaxLengths[static_cast<int32>(EGameLiftParams::Max)] =
|
|
||||||
{
|
|
||||||
64, //authToken
|
|
||||||
512, //FleetId
|
|
||||||
128, //HostId
|
|
||||||
128, //WebSocketUrl
|
|
||||||
16, //Region (ca-central-1)
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr int32 MinLengths[static_cast<int32>(EGameLiftParams::Max)] =
|
|
||||||
{
|
|
||||||
1, //authToken
|
|
||||||
1, //FleetId
|
|
||||||
1, //HostId
|
|
||||||
1, //WebSocketUrl
|
|
||||||
3, //Region (ca-central-1)
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool IsStringValid(const FString& Value, EGameLiftParams ParamType);
|
|
||||||
static bool IsStringShort(const FString& Value, EGameLiftParams ParamType);
|
|
||||||
static bool IsStringLong(const FString& Value, EGameLiftParams ParamType);
|
|
||||||
static bool IsMatchesRegex(const FString& Value, EGameLiftParams ParamType);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
|
||||||
static FParamResult ValidateParam(const FString& Value, EGameLiftParams ParamType);
|
|
||||||
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
|
||||||
static FString GetParameterFromEnum(EGameLiftParams InParam);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
|
||||||
static FString GetErrorFromEnum(EValidationError InParam);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
|
||||||
static void LogValidationErrorMessage(FParamResult ValidationResult);
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
|
|
||||||
struct FParamResult
|
|
||||||
{
|
|
||||||
FString Value;
|
|
||||||
bool bValid;
|
|
||||||
FString ErrorMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace GameLiftValidators2
|
|
||||||
{
|
|
||||||
enum class ECliParam
|
|
||||||
{
|
|
||||||
AuthToken, FleetId, HostId, Region, WebSocketUrl, Max
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int32 GetMaxLength(ECliParam ParamType);
|
|
||||||
int32 GetMinLength(ECliParam ParamType);
|
|
||||||
|
|
||||||
bool IsStringValid(const FString& Value, ECliParam ParamType);
|
|
||||||
bool IsNumberValid(int32 Value, int32 Min, int32 Max);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user