diff --git a/Step.Config/Config/cmsConnectConfig.xml b/Step.Config/Config/cmsConnectConfig.xml
new file mode 100644
index 00000000..0fe16b37
--- /dev/null
+++ b/Step.Config/Config/cmsConnectConfig.xml
@@ -0,0 +1,10 @@
+
+
+
+ true
+
+ 192.168.214.200
+ gsHOP9H9aJHqgVzxruZg/T3XiZ9AfS1NdS/y/JFl05y8nCY9rmrCssxSONSyN/xkkLRvEcEYd/kf0HrluGX6MGrv8qLlCIIZXS6uKQNz7mtG4HokLFqIrHKdu3u3P6jI
+
+
+
\ No newline at end of file
diff --git a/Step.Config/Config/cmsConnectConfigValidator.xsd b/Step.Config/Config/cmsConnectConfigValidator.xsd
new file mode 100644
index 00000000..fdf6760a
--- /dev/null
+++ b/Step.Config/Config/cmsConnectConfigValidator.xsd
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Config/Config/serverConfig.xml b/Step.Config/Config/serverConfig.xml
index 2ae275c9..6949760e 100644
--- a/Step.Config/Config/serverConfig.xml
+++ b/Step.Config/Config/serverConfig.xml
@@ -24,7 +24,6 @@
false
C:\CMS\MTC\ADAPTER\
SCMA
- true
50000
5000
diff --git a/Step.Config/Config/serverConfigValidator.xsd b/Step.Config/Config/serverConfigValidator.xsd
index bb2e14ef..3bc53d0c 100644
--- a/Step.Config/Config/serverConfigValidator.xsd
+++ b/Step.Config/Config/serverConfigValidator.xsd
@@ -36,8 +36,7 @@
-
-
+
diff --git a/Step.Config/ServerConfig.cs b/Step.Config/ServerConfig.cs
index b7336c29..c60ffd61 100644
--- a/Step.Config/ServerConfig.cs
+++ b/Step.Config/ServerConfig.cs
@@ -24,6 +24,7 @@ namespace Step.Config
public static List InitialAlarmsConfig;
public static List HeadsConfig;
public static ToolManagerConfigModel ToolManagerConfig;
+ public static CmsConnectConfigModel CmsConnectConfig;
public static AreasConfigModel ProductionConfig;
public static AreasConfigModel ToolingConfig;
diff --git a/Step.Config/ServerConfigController.cs b/Step.Config/ServerConfigController.cs
index 3021db0d..ff8dcc42 100644
--- a/Step.Config/ServerConfigController.cs
+++ b/Step.Config/ServerConfigController.cs
@@ -33,6 +33,7 @@ namespace Step.Config
ReadAlarmsConfig();
ReadHeadsConfig();
ReadToolManagerConfig();
+ ReadCMSConnectConfig();
ReadMacros();
ReadScadaFile();
//ReadMainProgram();
@@ -306,8 +307,7 @@ namespace Step.Config
MTCFolderPath = x.Element("MTCFolderPath").Value,
MTCApplicationName = x.Element("MTCApplicationName").Value,
MaxAlarmsRows = Convert.ToInt32(x.Element("maxAlarmsRows").Value),
- AlarmToDelete = Convert.ToInt32(x.Element("alarmToDelete").Value),
- CMSConnectReady = Convert.ToBoolean(x.Element("CMSConnectReady").Value)
+ AlarmToDelete = Convert.ToInt32(x.Element("alarmToDelete").Value),
}).FirstOrDefault();
int softwareId = 0;
@@ -547,6 +547,50 @@ namespace Step.Config
.ToList();
}
+
+ private static void ReadCMSConnectConfig()
+ {
+ String _tempUSR, _tempPSW;
+ XDocument xmlConfigFile = GetXmlHandlerWithValidator(CMS_CONNECT_CONFIG_SCHEMA_PATH, CMS_CONNECT_CONFIG_PATH);
+
+ XElement l = xmlConfigFile
+ .Root
+ .Descendants("cmsConnectConfig")
+ .FirstOrDefault();
+
+ // Read config from XML file
+ CmsConnectConfig = xmlConfigFile
+ .Root
+ .Descendants("cmsConnectConfig")
+ .Select(x => new CmsConnectConfigModel()
+ {
+ Enabled = Convert.ToBoolean(x.Element("enabled").Value)
+ })
+ .FirstOrDefault();
+
+ // Read config from XML file for Gateway
+ GatewayConfigModel tempGatewayConfigModel = xmlConfigFile
+ .Root
+ .Descendants("gateway")
+ .Select(x => new GatewayConfigModel()
+ {
+ Address = x.Element("address").Value,
+ Token = x.Element("token").Value
+ })
+ .FirstOrDefault();
+
+ if (DecodeCMSConnectGatewayLogin(tempGatewayConfigModel.Token, out _tempUSR, out _tempPSW))
+ {
+ tempGatewayConfigModel.Username = _tempUSR;
+ tempGatewayConfigModel.Password = _tempPSW;
+ }
+ else
+ throw new Exception("Error while reading \""+ CMS_CONNECT_CONFIG_PATH + "\": Gateway Token not valid");
+
+ CmsConnectConfig.Gateway = tempGatewayConfigModel;
+ }
+
+
public static void ReadMacros()
{
XDocument xmlConfigFile = GetXmlHandlerWithValidator(MACROS_CONFIG_SCHEMA_PATH, MACROS_CONFIG_PATH);
diff --git a/Step.Config/Step.Config.csproj b/Step.Config/Step.Config.csproj
index 60932e76..8f51832a 100644
--- a/Step.Config/Step.Config.csproj
+++ b/Step.Config/Step.Config.csproj
@@ -42,6 +42,9 @@
+
+ PreserveNewest
+
PreserveNewest
@@ -144,5 +147,10 @@
Designer
+
+
+ Designer
+
+
\ No newline at end of file
diff --git a/Step.Core/ThreadsFunctions.cs b/Step.Core/ThreadsFunctions.cs
index 074ed7a1..92cec6e1 100644
--- a/Step.Core/ThreadsFunctions.cs
+++ b/Step.Core/ThreadsFunctions.cs
@@ -834,7 +834,7 @@ public static class ThreadsFunctions
foreach (M154DataModel m154 in data)
{
- if(ServerStartupConfig.CMSConnectReady)
+ if(CmsConnectConfig.Enabled)
{
if (m154.Parameters.Count() >= 2 && m154.Parameters[0] == "SOUR")
diff --git a/Step.Model/ConfigModels/CmsConnectConfigModel.cs b/Step.Model/ConfigModels/CmsConnectConfigModel.cs
new file mode 100644
index 00000000..2b615c61
--- /dev/null
+++ b/Step.Model/ConfigModels/CmsConnectConfigModel.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Step.Model.ConfigModels
+{
+ public class CmsConnectConfigModel
+ {
+ public CmsConnectConfigModel()
+ {
+ Gateway = new GatewayConfigModel();
+ }
+ public bool Enabled { get; set; }
+
+ public GatewayConfigModel Gateway { get; set; }
+ }
+
+ public class GatewayConfigModel
+ {
+ public string Address { get; set; }
+ public string Token { get; set; }
+ public string Username { get; set; }
+ public string Password { get; set; }
+
+ }
+}
diff --git a/Step.Model/ConfigModels/ServerConfigModel.cs b/Step.Model/ConfigModels/ServerConfigModel.cs
index a2f5dbb7..1479bafd 100644
--- a/Step.Model/ConfigModels/ServerConfigModel.cs
+++ b/Step.Model/ConfigModels/ServerConfigModel.cs
@@ -18,7 +18,6 @@ namespace Step.Model.ConfigModels
public string MTCFolderPath { get; set; }
public string MTCApplicationName { get; set; }
- public Boolean CMSConnectReady { get; set; }
public int MaxAlarmsRows { get; set; }
public int AlarmToDelete { get; set; }
diff --git a/Step.Model/Constants.cs b/Step.Model/Constants.cs
index 1a8abe06..ca6e47ac 100644
--- a/Step.Model/Constants.cs
+++ b/Step.Model/Constants.cs
@@ -184,6 +184,9 @@ namespace Step.Model
public const string TOOL_MANAGER_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "toolManagerConfigValidator.xsd";
public const string TOOL_MANAGER_CONFIG_PATH = CONFIG_DIRECTORY + "toolManagerConfig.xml";
+ public const string CMS_CONNECT_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "cmsConnectConfigValidator.xsd";
+ public const string CMS_CONNECT_CONFIG_PATH = CONFIG_DIRECTORY + "cmsConnectConfig.xml";
+
public const string MACROS_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "macrosConfigValidator.xsd";
public const string MACROS_CONFIG_PATH = CONFIG_DIRECTORY + "macrosConfig.xml";
diff --git a/Step.Model/Step.Model.csproj b/Step.Model/Step.Model.csproj
index d49b564b..3332d080 100644
--- a/Step.Model/Step.Model.csproj
+++ b/Step.Model/Step.Model.csproj
@@ -64,6 +64,7 @@
+
diff --git a/Step.Utils/supportFunctions.cs b/Step.Utils/supportFunctions.cs
index ac142322..2ad16536 100644
--- a/Step.Utils/supportFunctions.cs
+++ b/Step.Utils/supportFunctions.cs
@@ -8,6 +8,8 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
using static CMS_CORE_Library.Models.DataStructures;
using static Step.Model.Constants;
@@ -15,6 +17,8 @@ namespace Step.Utils
{
public static class SupportFunctions
{
+ private static readonly string CMSCONNECT_TOKEN = "59f1qik5PYfiJLiXZ4xZ05pjzx5E9FscQWtj4lmfLKXaF1OAxkvu7ziBzXFBuuVQ";
+
public static SOFTKEY_TYPE GetSoftKeyType(string type)
{
switch (type)
@@ -399,7 +403,158 @@ namespace Step.Utils
}
return "";
- }
-
+ }
+
+
+ public static Boolean DecodeCMSConnectGatewayLogin(string encryptedString, out string login, out string password)
+ {
+ login = "";
+ password = "";
+
+ //Check if is null
+ if (String.IsNullOrEmpty(encryptedString))
+ return false;
+
+ //Decode it
+ String decodedLogin = StringCipher.Decrypt(encryptedString, CMSCONNECT_TOKEN);
+
+ //Check if contains the Space
+ if (!decodedLogin.Contains(" "))
+ return false;
+
+ //Split it and check
+ String[] tempLogin = decodedLogin.Split(' ');
+ if (tempLogin.Length != 2)
+ return false;
+
+ //Set the variable
+ login = tempLogin[0];
+ password = tempLogin[1];
+
+ return true;
+ }
+
+
+
+ public static Boolean EncodeCMSConnectGatewayLogin(out string encryptedString, string login, string password)
+ {
+ encryptedString = "";
+
+ //Check if contains the Space
+ if (String.IsNullOrEmpty(login) || login.Contains(" "))
+ return false;
+
+ //Check if contains the Space
+ if (String.IsNullOrEmpty(password) || password.Contains(" "))
+ return false;
+
+ encryptedString = StringCipher.Encrypt(login + " " + password, CMSCONNECT_TOKEN);
+ return true;
+ }
+
+ //----- Chipher Private Class ---------------------------------
+ #region Chipher_Private_Class
+
+ private static class StringCipher
+ {
+ // This constant is used to determine the keysize of the encryption algorithm in bits.
+ // We divide this by 8 within the code below to get the equivalent number of bytes.
+ private const int Keysize = 256;
+
+ // This constant determines the number of iterations for the password bytes generation function.
+ private const int DerivationIterations = 1000;
+
+ public static string Encrypt(string plainText, string passPhrase)
+ {
+ // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
+ // so that the same Salt and IV values can be used when decrypting.
+ var saltStringBytes = Generate256BitsOfRandomEntropy();
+ var ivStringBytes = Generate256BitsOfRandomEntropy();
+ var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
+ using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+ {
+ var keyBytes = password.GetBytes(Keysize / 8);
+ using (var symmetricKey = new RijndaelManaged())
+ {
+ symmetricKey.BlockSize = 256;
+ symmetricKey.Mode = CipherMode.CBC;
+ symmetricKey.Padding = PaddingMode.PKCS7;
+ using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
+ {
+ cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
+ cryptoStream.FlushFinalBlock();
+ // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
+ var cipherTextBytes = saltStringBytes;
+ cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
+ cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
+ memoryStream.Close();
+ cryptoStream.Close();
+ return Convert.ToBase64String(cipherTextBytes);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static string Decrypt(string cipherText, string passPhrase)
+ {
+ // Get the complete stream of bytes that represent:
+ // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
+ var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
+ // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
+ var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
+ // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
+ var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
+ // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
+ var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
+
+ using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+ {
+ var keyBytes = password.GetBytes(Keysize / 8);
+ using (var symmetricKey = new RijndaelManaged())
+ {
+ symmetricKey.BlockSize = 256;
+ symmetricKey.Mode = CipherMode.CBC;
+ symmetricKey.Padding = PaddingMode.PKCS7;
+ using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
+ {
+ using (var memoryStream = new MemoryStream(cipherTextBytes))
+ {
+ using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
+ {
+ var plainTextBytes = new byte[cipherTextBytes.Length];
+ var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
+ memoryStream.Close();
+ cryptoStream.Close();
+ return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static byte[] Generate256BitsOfRandomEntropy()
+ {
+ var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
+ using (var rngCsp = new RNGCryptoServiceProvider())
+ {
+ // Fill the array with cryptographically secure random bytes.
+ rngCsp.GetBytes(randomBytes);
+ }
+ return randomBytes;
+ }
+ }
+
+ #endregion
}
+
+
+
+
}
\ No newline at end of file