340 lines
12 KiB
C#
340 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Web;
|
|
using System.Windows;
|
|
using BeWo.Data;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Service.Core;
|
|
using BS.Shared.DataContracts;
|
|
|
|
namespace BeWo.Service.Security
|
|
{
|
|
public class SecurityUtils
|
|
{
|
|
private static readonly byte[] _Rc2IV = { 35, 138, 177, 253, 227, 63, 2, 27 };
|
|
|
|
private static readonly byte[] _Rc2Key = { 174, 130, 219, 185, 185, 221, 96, 50, 37, 212, 81, 121, 71, 206, 130, 153 };
|
|
|
|
public static string EncryptString(string strToEncrypt)
|
|
{
|
|
var lRc2CSP = new RC2CryptoServiceProvider();
|
|
var lEncryptor = lRc2CSP.CreateEncryptor(_Rc2Key, _Rc2IV);
|
|
|
|
using (var msEncrypt = new MemoryStream())
|
|
{
|
|
using (var csEncrypt = new CryptoStream(msEncrypt, lEncryptor, CryptoStreamMode.Write))
|
|
{
|
|
byte[] toEncrypt = Encoding.UTF8.GetBytes(strToEncrypt);
|
|
|
|
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
|
|
csEncrypt.FlushFinalBlock();
|
|
|
|
byte[] encrypted = msEncrypt.ToArray();
|
|
return Convert.ToBase64String(encrypted);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string DecryptString(string strToDecrypt)
|
|
{
|
|
var lRc2CSP = new RC2CryptoServiceProvider();
|
|
var lDecryptor = lRc2CSP.CreateDecryptor(_Rc2Key, _Rc2IV);
|
|
|
|
strToDecrypt = strToDecrypt.Replace(' ', '+');
|
|
strToDecrypt = strToDecrypt.Trim(',');
|
|
|
|
using (var msDecrypt = new MemoryStream(Convert.FromBase64String(strToDecrypt)))
|
|
{
|
|
using (var csDecrypt = new CryptoStream(msDecrypt, lDecryptor, CryptoStreamMode.Read))
|
|
{
|
|
var bytes = new List<byte>();
|
|
int b;
|
|
do
|
|
{
|
|
b = csDecrypt.ReadByte();
|
|
if (b != -1)
|
|
bytes.Add(Convert.ToByte(b));
|
|
|
|
} while (b != -1);
|
|
return Encoding.UTF8.GetString(bytes.ToArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static string CreateToken(bool ispermalink, string link)
|
|
{
|
|
var guid = Guid.NewGuid();
|
|
|
|
string loginName, rc2EncryptedHash;
|
|
var tenant = MultitenancyOperationContextExt.Current is null ? SessionFacade.Tenant : MultitenancyOperationContextExt.Current.Tenant;
|
|
|
|
if(LoggedInUserOperationContextExt.Current is null)
|
|
{
|
|
loginName = SessionFacade.LoggedInUser.LoginName;
|
|
rc2EncryptedHash = SessionFacade.LoggedInUser.RC2EncryptedHash;
|
|
}
|
|
else
|
|
{
|
|
loginName = LoggedInUserOperationContextExt.Current.User.LoginName;
|
|
rc2EncryptedHash = LoggedInUserOperationContextExt.Current.User.RC2EncryptedHash;
|
|
}
|
|
|
|
var tokendata = $"expdate={DateTime.Now.AddMinutes(10)};guid={guid};tenant={tenant};user={loginName};password={rc2EncryptedHash};permalink={ispermalink};link={Utils.GetSHA256(link)}";
|
|
|
|
return HttpUtility.UrlEncode(EncryptString(tokendata));
|
|
}
|
|
|
|
|
|
|
|
public static bool CheckToken(string token, string link)
|
|
{
|
|
if (string.IsNullOrEmpty(token))
|
|
return false;
|
|
|
|
string decodedToken = DecryptString(token);
|
|
|
|
string[] Params = decodedToken.Split(';');
|
|
|
|
|
|
var linkSha256 = Params[6];
|
|
|
|
if (!String.IsNullOrWhiteSpace(link) && link.IndexOf("token") > 1)
|
|
{
|
|
var firstpart = link.Substring(0, link.IndexOf("token") - 1);
|
|
|
|
var sha = String.Format("link={0}", Utils.GetSHA256(firstpart));
|
|
|
|
if (linkSha256 != sha)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (Boolean.Parse(Params[5].Split('=')[1]))
|
|
return true;
|
|
|
|
string date = Params[0].Split('=')[1];
|
|
string[] expdatestrarr = date.Split(new[] { '.', ':', ' ' });
|
|
|
|
var expdate = new DateTime(Convert.ToInt32(expdatestrarr[2]), Convert.ToInt32(expdatestrarr[1]),
|
|
Convert.ToInt32(expdatestrarr[0]), Convert.ToInt32(expdatestrarr[3]),
|
|
Convert.ToInt32(expdatestrarr[4]), Convert.ToInt32(expdatestrarr[5]));
|
|
|
|
return expdate >= DateTime.Now;
|
|
}
|
|
|
|
public static Dictionary<string,object> sliceToken(string token, string link)
|
|
{
|
|
string decodedToken;
|
|
var result = new Dictionary<string, object>();
|
|
var ParamsDic = new Dictionary<string, string>();
|
|
|
|
try
|
|
{
|
|
decodedToken = DecryptString(HttpUtility.UrlDecode(token));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
decodedToken = DecryptString(token);
|
|
}
|
|
|
|
string[] Params = decodedToken.Split(';');
|
|
|
|
foreach (var splittedItem in Params.Select(item => new Regex(@"[\=]{1}").Split(item, 2)).Where(splittedItem => !ParamsDic.ContainsKey(splittedItem[0])))
|
|
{
|
|
ParamsDic.Add(splittedItem[0], splittedItem[1]);
|
|
}
|
|
|
|
string[] expdatestrarr = ParamsDic["expdate"].Split(new[] { '.', ':', ' ' });
|
|
|
|
var expdate = new DateTime(Convert.ToInt32(expdatestrarr[2]), Convert.ToInt32(expdatestrarr[1]),
|
|
Convert.ToInt32(expdatestrarr[0]), Convert.ToInt32(expdatestrarr[3]),
|
|
Convert.ToInt32(expdatestrarr[4]), Convert.ToInt32(expdatestrarr[5]));
|
|
|
|
result.Add("expdate", expdate);
|
|
result.Add("guid", Guid.Parse(ParamsDic["guid"]));
|
|
result.Add("tenant", ParamsDic["tenant"]);
|
|
result.Add("user", ParamsDic["user"]);
|
|
result.Add("password", ParamsDic["password"]);
|
|
result.Add("ispermalink", ParamsDic["permalink"]);
|
|
|
|
return result;
|
|
}
|
|
|
|
public static LicenseInfoDC GetLicenseInfo()
|
|
{
|
|
var info = new LicenseInfoDC();
|
|
|
|
#if DEBUG
|
|
|
|
info.MaxLicenseCount = 1000;
|
|
info.PercentFreeEmployee = 100;
|
|
|
|
info.LicenseInUseCount = 1;
|
|
info.EmployeeCount = 1;
|
|
|
|
info.MaxEmployeeCount = 1000;
|
|
|
|
|
|
return info;
|
|
try
|
|
{
|
|
string url = ConfigurationManager.AppSettings.Get("LicenseInfoUrl");
|
|
|
|
//url = url.Replace("[TENANT]", MultitenancyOperationContextExt.Current.Tenant);
|
|
|
|
var test = MultitenancyOperationContextExt.Current.Tenant;
|
|
|
|
url = url.Replace("[TENANT]", "1234567890");
|
|
url += "&t=0";
|
|
//url = url.Replace("[TENANT]", "1441747891");
|
|
|
|
using (WebClient client = new WebClient())
|
|
{
|
|
//MessageBox.Show(hostAddress);
|
|
byte[] response = client.DownloadData(url);
|
|
|
|
String result = System.Text.Encoding.ASCII.GetString(response);
|
|
//if (MultitenancyOperationContextExt.Current.Tenant == "demo")
|
|
//{
|
|
// result = "7;30";
|
|
//}
|
|
String[] resultArray = result.Split(';');
|
|
|
|
int maxLicenses = 0;
|
|
int midLicenses = 0;
|
|
decimal percentFreeEmployees = 0;
|
|
if (resultArray.Length > 0)
|
|
{
|
|
Int32.TryParse(resultArray[0], out maxLicenses);
|
|
if (resultArray.Length > 1)
|
|
{
|
|
Decimal.TryParse(resultArray[1], out percentFreeEmployees);
|
|
}
|
|
if (resultArray.Length > 2)
|
|
{
|
|
Int32.TryParse(resultArray[2], out midLicenses);
|
|
}
|
|
}
|
|
if (midLicenses > 0)
|
|
{
|
|
percentFreeEmployees = 0;
|
|
maxLicenses += midLicenses;
|
|
}
|
|
info.MaxLicenseCount = 1000;
|
|
info.PercentFreeEmployee = percentFreeEmployees;
|
|
|
|
info.LicenseInUseCount = DAOFactory.GenericDAO.GetAllActive<ApplicationUser>().Count;
|
|
info.EmployeeCount = DAOFactory.GenericDAO.GetAllActive<Employee>().Count;
|
|
|
|
info.MaxEmployeeCount = (int)Math.Ceiling(maxLicenses * ((100 + percentFreeEmployees) / 100));
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//
|
|
}
|
|
return info;
|
|
|
|
#endif
|
|
|
|
try
|
|
{
|
|
string url = ConfigurationManager.AppSettings.Get("LicenseInfoUrl");
|
|
|
|
url = url.Replace("[TENANT]", MultitenancyOperationContextExt.Current.Tenant);
|
|
url += "&t=0";
|
|
//url = url.Replace("[TENANT]", "1441747891");
|
|
|
|
using (WebClient client = new WebClient())
|
|
{
|
|
//MessageBox.Show(hostAddress);
|
|
byte[] response = client.DownloadData(url);
|
|
|
|
String result = System.Text.Encoding.ASCII.GetString(response);
|
|
//if (MultitenancyOperationContextExt.Current.Tenant == "demo")
|
|
//{
|
|
// result = "7;30";
|
|
//}
|
|
String[] resultArray = result.Split(';');
|
|
|
|
int maxLicenses = 0;
|
|
int midLicenses = 0;
|
|
decimal percentFreeEmployees = 0;
|
|
if (resultArray.Length > 0)
|
|
{
|
|
Int32.TryParse(resultArray[0], out maxLicenses);
|
|
if (resultArray.Length > 1)
|
|
{
|
|
Decimal.TryParse(resultArray[1], out percentFreeEmployees);
|
|
}
|
|
if (resultArray.Length > 2)
|
|
{
|
|
Int32.TryParse(resultArray[2], out midLicenses);
|
|
}
|
|
}
|
|
if (midLicenses > 0)
|
|
{
|
|
percentFreeEmployees = 0;
|
|
maxLicenses += midLicenses;
|
|
}
|
|
info.MaxLicenseCount = maxLicenses;
|
|
info.PercentFreeEmployee = percentFreeEmployees;
|
|
|
|
info.LicenseInUseCount = DAOFactory.GenericDAO.GetAllActive<ApplicationUser>().Count;
|
|
info.EmployeeCount = DAOFactory.GenericDAO.GetAllActive<Employee>().Count;
|
|
|
|
info.MaxEmployeeCount = (int)Math.Ceiling(maxLicenses * ((100 + percentFreeEmployees) / 100));
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//
|
|
}
|
|
return info;
|
|
}
|
|
|
|
public static string CreateRandomString(int size, bool capitals = false, bool small = false, bool numbers = true)
|
|
{
|
|
var data = new byte[1];
|
|
var crypto = new RNGCryptoServiceProvider();
|
|
var result = new StringBuilder(size);
|
|
|
|
const string numbersString = "0123456789";
|
|
const string capitalsString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
const string smallString = "abcdefghijklmnopqrstuvwxyz";
|
|
|
|
var str = string.Empty;
|
|
|
|
if (numbers)
|
|
str += numbersString;
|
|
if (capitals)
|
|
str += capitalsString;
|
|
if (small)
|
|
str += smallString;
|
|
|
|
if (str.Length == 0)
|
|
str = numbersString;
|
|
|
|
var chars = str.ToCharArray();
|
|
|
|
crypto.GetBytes(data);
|
|
data = new byte[size];
|
|
crypto.GetBytes(data);
|
|
|
|
foreach (byte b in data)
|
|
result.Append(chars[b % (chars.Length)]);
|
|
|
|
return result.ToString();
|
|
}
|
|
}
|
|
}
|