Initial Commit

This commit is contained in:
2016-07-27 00:32:34 -04:00
commit 8d162b2035
701 changed files with 188672 additions and 0 deletions

View File

@@ -0,0 +1,430 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pluto.Registration
{
internal class SystemAccessVerifier
{
#region Consts
const int SYSTEM_API_KEY_LENGTH = 22;
const int USER_API_KEY_LENGTH = 20;
const int PIN_LENGTH = 6;
const string SYSTEM_API_KEY_BEGIN_MARKER = "$";
const string SYSTEM_API_KEY_END_MARKER = "#";
internal static readonly string LETTER_CHARS = "AZXVGLTCIRKPNOMQJSHUFWDEYB";
internal static int GET_LETTER_CHARS_COUNT { get { return LETTER_CHARS.Length; } }
#endregion
#region System Api Key
private string _systemApiKey = String.Empty;
internal string SystemApiKey
{
get
{
return _systemApiKey;
}
set
{
if (ValidateSystemKey(value))
_systemApiKey = value.ToUpper().Trim();
}
}
private static bool ValidateSystemKey(string key)
{
if(!String.IsNullOrEmpty(key))
key = key.ToUpper().Trim();
// $247B2CB4A437EB74C62#M
if (!String.IsNullOrEmpty(key) && key.Length == SYSTEM_API_KEY_LENGTH &&
key[0] == Char.Parse(SYSTEM_API_KEY_BEGIN_MARKER) && key[SYSTEM_API_KEY_LENGTH - 2] == Char.Parse(SYSTEM_API_KEY_END_MARKER) &&
Char.IsLetter(key[SYSTEM_API_KEY_LENGTH - 1]))
{
// AllAreLettersOrDigit?
for (int i = 1; i < SYSTEM_API_KEY_LENGTH - 2; ++i)
{
if (!Char.IsLetterOrDigit(key[i]))
return false;
}
return true;
}
return false;
}
#endregion
#region User Api Key
private string _UserApiKey = String.Empty;
internal string UserApiKey
{
get
{
return _UserApiKey;
}
set
{
if (ValidateUserKey(value))
_UserApiKey = value.ToUpper().Trim();
}
}
private static bool ValidateUserKey(string key)
{
if (!String.IsNullOrEmpty(key))
key = key.ToUpper().Trim();
//247BQCB4A-37EB-4C62M
if (!String.IsNullOrEmpty(key) && key.Length == USER_API_KEY_LENGTH &&
Char.IsLetter(key[USER_API_KEY_LENGTH - 1]) &&
Char.IsLetter(key[4]) && key[9] == '-' && key[14] == '-')
{
// Perform Product Security check
char productType = key[USER_API_KEY_LENGTH - 1];
int v = (int)productType % GET_LETTER_CHARS_COUNT;
if (key[4] == LETTER_CHARS[v])
return true;
}
return false;
}
#endregion
#region Pin
private string _Pin = String.Empty;
internal string Pin { get { return _Pin; } }
internal bool IsValidPin { get { return (_Pin != String.Empty); } }
#endregion
#region Product Type
private char _productType = '\0';
internal char ProductType { get { return Char.ToUpper(_productType); } }
internal bool IsValidProductType { get { return (_productType != '\0'); } }
#endregion
#region Construction
internal SystemAccessVerifier(string systemApiKey)
{
if (!String.IsNullOrEmpty(systemApiKey))
systemApiKey = systemApiKey.ToUpper().Trim();
SystemApiKey = systemApiKey;
_productType = GetProductTypeFromSystemApiKey(SystemApiKey);
ConvertSystemToUserApiKey();
_Pin = RetrieveUserApkiKeyPin(UserApiKey);
}
internal SystemAccessVerifier(string userApiKey, string pin)
{
if (!String.IsNullOrEmpty(userApiKey))
userApiKey = userApiKey.ToUpper().Trim();
if (ValidateUserKey(userApiKey))
{
string aPin = RetrieveUserApkiKeyPin(userApiKey);
if (!String.IsNullOrEmpty(aPin) && !String.IsNullOrEmpty(pin) &&
aPin == pin)
{
UserApiKey = userApiKey;
_Pin = pin;
ConvertUserToSystemApiKey();
_productType = GetProductTypeFromSystemApiKey(SystemApiKey);
}
}
}
#endregion
#region Private Converters
private void ConvertSystemToUserApiKey()
{
if (ValidateSystemKey(SystemApiKey) && IsValidProductType)
{
// $247B2CB4A437EB74C62#M
string s = SystemApiKey;
s = s.Replace(SYSTEM_API_KEY_BEGIN_MARKER, "");
s = s.Replace(SYSTEM_API_KEY_END_MARKER, "");
// pop off the product type
char productType = SystemApiKey[SYSTEM_API_KEY_LENGTH - 1];
s = s.Substring(0, s.Length - 1);
// Stripe out the invalid chars
StringBuilder sb = new StringBuilder(s);
sb.Remove(14, 1);
sb.Remove(9, 1);
sb.Remove(4, 1);
s = sb.ToString();
// Then put the Dashes back
s = MakeIntoDashSeperatedString(s, 4);
// reverse the string (how clever) :S
s = ReverseString(s);
sb = new StringBuilder(s);
int v = (int)productType % GET_LETTER_CHARS_COUNT;
sb[4] = LETTER_CHARS[v];
// Perform an arbitrary swap (just in case)
// Swap 10 to 3, and 16 to 5
char c = sb[10];
sb[10] = sb[3];
sb[3] = c;
c = sb[16];
sb[16] = sb[5];
sb[5] = c;
// Add More Randomness into this (nobody will ever know :S)
// Dynamic Calc for 2 + 2, 12 + 4
int a = (int)'A';
int z = (int)'Z';
int ic = (int)sb[2];
if ((ic >= a) && (ic + 2 <= z))
sb[2] = (char)(ic + 2);
ic = sb[12];
if ((ic >= a) && (ic + 4 <= z))
sb[12] = (char)(ic + 4);
// 247BQCB4A-37EB-4C62M
s = sb.ToString() + productType;
UserApiKey = s;
}
}
private void ConvertUserToSystemApiKey()
{
if (ValidateUserKey(UserApiKey) && IsValidPin)
{
// 247BQCB4A-37EB-4C62M
StringBuilder sb = new StringBuilder(UserApiKey);
char productType = sb[USER_API_KEY_LENGTH - 1];
sb.Remove(USER_API_KEY_LENGTH - 1, 1);
// Add More Randomness into this (nobody will ever know :S)
// Dynamic Calc for 2 - 2, 12 - 4
int a = (int)'A';
int z = (int)'Z';
int ic = (int)sb[2];
if ((ic - 2 >= a) && (ic <= z))
sb[2] = (char)(ic - 2);
ic = sb[12];
if ((ic - 4 >= a) && (ic <= z))
sb[12] = (char)(ic - 4);
//Otherway arround arbitrary swap (just in case)
// Swap 3 to 10, and 5 to 16
char c = sb[3];
sb[3] = sb[10];
sb[10] = c;
c = sb[5];
sb[5] = sb[16];
sb[16] = c;
// Assign '-'
sb[4] = '-';
// How clever :S
string s = ReverseString(sb.ToString());
int n = 0;
sb = new StringBuilder(s);
for (int i = 0; i < s.Length; ++i)
{
if (s[i] == '-')
{
sb[i] = (s[n]);
n++;
}
else
{
sb[i] = (s[i]);
}
}
// $247B2CB4A437EB74C62#M
s = SYSTEM_API_KEY_BEGIN_MARKER + sb.ToString() + SYSTEM_API_KEY_END_MARKER + Char.ToUpper(productType);
SystemApiKey = s;
}
}
#endregion
#region Internal Statics
internal static string GenerateNewSystemApiKey(char productType)
{
if (Char.IsLetter(productType))
{
Guid guid = Guid.NewGuid();
string s = MakeIntoDashUnseperatedString(guid.ToString().ToUpper());
s = s.Substring(0, USER_API_KEY_LENGTH - 4);
s = MakeIntoDashSeperatedString(s, 4);
int n = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; ++i)
{
if (s[i] == '-')
{
sb.Append(s[n]);
n++;
}
else
{
sb.Append(s[i]);
}
}
//$C343C1B833740444938#M
s = SYSTEM_API_KEY_BEGIN_MARKER + sb.ToString() + SYSTEM_API_KEY_END_MARKER + Char.ToUpper(productType);
return s;
}
return String.Empty;
}
internal static char GetProductTypeFromSystemApiKey(string systemApiKey)
{
if (ValidateSystemKey(systemApiKey))
return Char.ToUpper(systemApiKey[SYSTEM_API_KEY_LENGTH - 1]);
else
return '\0';
}
internal static string RetrieveUserApkiKeyPin(string userApiKey)
{
if (!String.IsNullOrEmpty(userApiKey))
userApiKey = userApiKey.ToUpper().Trim();
if (ValidateUserKey(userApiKey))
{
string KeyChecksum = PerformChecksum(userApiKey).ToString();
if (KeyChecksum.Length == 1)
KeyChecksum = KeyChecksum + "7"; //Very Likely never single digit
string TimeChecksum = DateTime.Now.ToUniversalTime().ToShortDateString() + DateTime.Now.ToUniversalTime().Year.ToString().Substring(2);
TimeChecksum = PerformChecksum(TimeChecksum).ToString();
if (TimeChecksum.Length == 1)
TimeChecksum = TimeChecksum + "5"; //TimeChecksum coulde be single digit
bool bCheckPassed = false;
string nCheck = String.Empty;
char productType = userApiKey[USER_API_KEY_LENGTH - 1];
char check = userApiKey[4];
int v = (int)productType % GET_LETTER_CHARS_COUNT;
if (check == LETTER_CHARS[v])
{
bCheckPassed = true;
int n1 = (int)check + DateTime.Now.ToUniversalTime().Day;
int n2 = (int)LETTER_CHARS[v] - (int)DateTime.Now.ToUniversalTime().DayOfWeek;
int n1n2 = (n1 + n2);
nCheck = n1n2.ToString();
nCheck = nCheck.Substring(nCheck.Length - 2, 2);
}
// Use Pin Map to generate appropriate Pin
const string PIN_MAP = "2645309718";
string pin = String.Empty;
if (bCheckPassed)
{
int c1, c2, k1, k2, t1, t2;
int.TryParse(nCheck[0].ToString(), out c1);
int.TryParse(nCheck[1].ToString(), out c2);
int.TryParse(KeyChecksum[0].ToString(), out k1);
int.TryParse(KeyChecksum[1].ToString(), out k2);
int.TryParse(TimeChecksum[0].ToString(), out t1);
int.TryParse(TimeChecksum[1].ToString(), out t2);
pin = PIN_MAP[c2] + PIN_MAP[c1].ToString() + PIN_MAP[t2] + PIN_MAP[k2] + PIN_MAP[t1] + PIN_MAP[k1];
return pin;
}
}
return String.Empty;
}
#endregion
#region Private static Key Generation Helper Functions
private static string ReverseString(string str)
{
if (!String.IsNullOrEmpty(str))
{
Stack<char> stack = new Stack<char>();
foreach (char c in str)
stack.Push(c);
StringBuilder sb = new StringBuilder();
while (stack.Count > 0)
sb.Append(stack.Pop());
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Perform checksum on string
/// </summary>
/// <param name="strAboutToBeChecksummed"></param>
/// <returns>Checksum</returns>
private static int PerformChecksum(string strAboutToBeChecksummed)
{
if (!String.IsNullOrEmpty(strAboutToBeChecksummed))
{
int nChecksum = 0;
for (int i = 0; i < strAboutToBeChecksummed.Length; ++i)
{
if (Char.IsDigit(strAboutToBeChecksummed[i]))
nChecksum = nChecksum + int.Parse(strAboutToBeChecksummed[i].ToString());
}
return nChecksum;
}
return 0;
}
/// <summary>
/// Dash a String every Nth Character
/// </summary>
/// <returns>a dashed string</returns>
private static string MakeIntoDashSeperatedString(string strAboutToBeDashed, int DashEveryNthCharacter)
{
if (!String.IsNullOrEmpty(strAboutToBeDashed))
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < strAboutToBeDashed.Length; i++)
{
if ((i != 0) && ((i % DashEveryNthCharacter) == 0))
sb.Append("-");
sb.Append(strAboutToBeDashed[i]);
}
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Undash a String
/// </summary>
/// <returns>a string without dashes</returns>
private static string MakeIntoDashUnseperatedString(string strAboutToBeUndashed)
{
if (!String.IsNullOrEmpty(strAboutToBeUndashed))
return strAboutToBeUndashed.Replace("-", "");
return String.Empty;
}
/// <summary>
/// Check if the passed in string contains only digits
/// </summary>
/// <param name="strToCheckForDigits">string to check for digits for</param>
/// <returns>true, if all digits are numbers</returns>
private static bool ContainsOnlyDigits(string strToCheckForDigits)
{
if (!String.IsNullOrEmpty(strToCheckForDigits))
{
for (int i = 0; i < strToCheckForDigits.Length; ++i)
{
if (!Char.IsDigit(strToCheckForDigits[i]))
return false;
}
return true;
}
return false;
}
#endregion
}
}