From: Vásáry Dániel Date: Tue, 17 Oct 2017 15:58:50 +0000 (+0000) Subject: git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube... X-Git-Url: http://git.useribm.hu/?a=commitdiff_plain;h=f7ef37657c3be5faacac0580c51b00d4c7467ab9;p=mediacube.git git-tfs-id: [tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube;C30640 --- diff --git a/client/IntegrationTests/IntegrationTests.csproj b/client/IntegrationTests/IntegrationTests.csproj index de381e8a..d507334a 100644 --- a/client/IntegrationTests/IntegrationTests.csproj +++ b/client/IntegrationTests/IntegrationTests.csproj @@ -118,6 +118,7 @@ + diff --git a/client/IntegrationTests/MaestroIT.cs b/client/IntegrationTests/MaestroIT.cs index e669ea94..35ee458e 100644 --- a/client/IntegrationTests/MaestroIT.cs +++ b/client/IntegrationTests/MaestroIT.cs @@ -11,8 +11,8 @@ using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; using System.Runtime.ConstrainedExecution; using System.Security; -using System.Security.Permissions; -using System.Security.Principal; +using BethesdaConsentFormWCFSvc; +using System.IO; namespace IntegrationTests { public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid { @@ -97,68 +97,80 @@ namespace IntegrationTests { Debug.WriteLine(result); } - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, - int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); + /*******************************/ + [DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2", CallingConvention = CallingConvention.Winapi)] + private static extern int WNetAddConnection2(NETRESOURCE lpNetResource, string lpPassword, + string lpUsername, System.UInt32 dwFlags); + + [StructLayout(LayoutKind.Sequential)] + private class NETRESOURCE { + public ResourceScope dwScope = 0; + public ResourceType dwType = 0; + public ResourceDisplayType dwDisplayType = 0; + public ResourceUsage dwUsage = 0; + public string lpLocalName = null; + public string lpRemoteName = null; + public string lpComment = null; + public string lpProvider = null; + }; + + public enum ResourceScope { + RESOURCE_CONNECTED = 1, + RESOURCE_GLOBALNET, + RESOURCE_REMEMBERED, + RESOURCE_RECENT, + RESOURCE_CONTEXT + }; + + public enum ResourceType { + RESOURCETYPE_ANY, + RESOURCETYPE_DISK, + RESOURCETYPE_PRINT, + RESOURCETYPE_RESERVED + }; + + public enum ResourceUsage { + RESOURCEUSAGE_CONNECTABLE = 0x00000001, + RESOURCEUSAGE_CONTAINER = 0x00000002, + RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004, + RESOURCEUSAGE_SIBLING = 0x00000008, + RESOURCEUSAGE_ATTACHED = 0x00000010, + RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED), + }; + + public enum ResourceDisplayType { + RESOURCEDISPLAYTYPE_GENERIC, + RESOURCEDISPLAYTYPE_DOMAIN, + RESOURCEDISPLAYTYPE_SERVER, + RESOURCEDISPLAYTYPE_SHARE, + RESOURCEDISPLAYTYPE_FILE, + RESOURCEDISPLAYTYPE_GROUP, + RESOURCEDISPLAYTYPE_NETWORK, + RESOURCEDISPLAYTYPE_ROOT, + RESOURCEDISPLAYTYPE_SHAREADMIN, + RESOURCEDISPLAYTYPE_DIRECTORY, + RESOURCEDISPLAYTYPE_TREE, + RESOURCEDISPLAYTYPE_NDSCONTAINER + }; - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] - public extern static bool CloseHandle(IntPtr handle); - - - [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] [TestMethod] - public void TestImpersonate() { - SafeTokenHandle safeTokenHandle; - try { - string userName, domainName, password; - // Get the user token for the specified user, domain, and password using the - // unmanaged LogonUser method. - // The local machine name can be used for the domain name to impersonate a user on this machine. - domainName = "."; - userName = "mediacube"; - password = "Broadca5T"; - const int LOGON32_PROVIDER_DEFAULT = 0; - //This parameter causes LogonUser to create a primary token. - const int LOGON32_LOGON_INTERACTIVE = 2; - - // Call LogonUser to obtain a handle to an access token. - bool returnValue = LogonUser(userName, domainName, password, - LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, - out safeTokenHandle); - - Console.WriteLine("LogonUser called."); - - if (false == returnValue) { - int ret = Marshal.GetLastWin32Error(); - Console.WriteLine("LogonUser failed with error code : {0}", ret); - throw new System.ComponentModel.Win32Exception(ret); - } - using (safeTokenHandle) { - Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No")); - Console.WriteLine("Value of Windows NT token: " + safeTokenHandle); - - // Check the identity. - Console.WriteLine("Before impersonation: " - + WindowsIdentity.GetCurrent().Name); - // Use the token handle returned by LogonUser. - using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle())) { - using (WindowsImpersonationContext impersonatedUser = newId.Impersonate()) { - - // Check the identity. - Console.WriteLine("After impersonation: " - + WindowsIdentity.GetCurrent().Name); - } - } - // Releasing the context object stops the impersonation - // Check the identity. - Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name); - } - } - catch (Exception ex) { - Console.WriteLine("Exception occurred. " + ex.Message); - } - + public void TestUNC() { + //using (UNCAccessWithCredentials unc = new UNCAccessWithCredentials()) { + // if (unc.NetUseWithCredentials("\\\\10.10.1.100\\BRAAVOS", "mediacube", null, "Broadca5T")) { + // string[] files = Directory.GetFiles("\\\\10.10.1.100\\BRAAVOS\\Archive"); + + // } + //} + + NETRESOURCE nr = new NETRESOURCE(); + nr.dwType = ResourceType.RESOURCETYPE_DISK; + nr.lpLocalName = null; + nr.lpRemoteName = "\\\\10.10.1.100\\BRAAVOS"; + nr.lpProvider = null; + + int result = WNetAddConnection2(nr, "Broadca5T", "mediacube", 0); + string[] files = Directory.GetFiles("\\\\10.10.1.100\\BRAAVOS\\Archive"); } diff --git a/client/IntegrationTests/UNCAccessWithCredentials.cs b/client/IntegrationTests/UNCAccessWithCredentials.cs new file mode 100644 index 00000000..6d8d0501 --- /dev/null +++ b/client/IntegrationTests/UNCAccessWithCredentials.cs @@ -0,0 +1,119 @@ +using System; +using System.Runtime.InteropServices; + +namespace BethesdaConsentFormWCFSvc { + public class UNCAccessWithCredentials : IDisposable { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct USE_INFO_2 { + internal String ui2_local; + internal String ui2_remote; + internal String ui2_password; + internal UInt32 ui2_status; + internal UInt32 ui2_asg_type; + internal UInt32 ui2_refcount; + internal UInt32 ui2_usecount; + internal String ui2_username; + internal String ui2_domainname; + } + + [DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern UInt32 NetUseAdd( + String UncServerName, + UInt32 Level, + ref USE_INFO_2 Buf, + out UInt32 ParmError); + + [DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern UInt32 NetUseDel( + String UncServerName, + String UseName, + UInt32 ForceCond); + + private bool _disposed = false; + + private string _sUncPath; + private string _sUser; + private string _sPassword; + private string _sDomain; + private int _iLastError; + + /// + /// A disposeable class that allows access to a UNC resource with credentials. + /// + public UNCAccessWithCredentials() { + } + + /// + /// The last system error code returned from NetUseAdd or NetUseDel. Success = 0 + /// + public int LastError { + get { return _iLastError; } + } + + public void Dispose() { + if (!_disposed) { + NetUseDelete(); + } + _disposed = true; + GC.SuppressFinalize(this); + } + + /// + /// Connects to a UNC path using the credentials supplied. + /// + /// Fully qualified domain name UNC path + /// A user with sufficient rights to access the path. + /// Domain of User. + /// Password of User + /// True if mapping succeeds. Use LastError to get the system error code. + public bool NetUseWithCredentials(string uncPath, string user, string domain, string password) { + _sUncPath = uncPath; + _sUser = user; + _sPassword = password; + _sDomain = domain; + return NetUseWithCredentials(); + } + + private bool NetUseWithCredentials() { + try { + var useinfo = new USE_INFO_2 { + ui2_remote = _sUncPath, + ui2_username = _sUser, + ui2_domainname = _sDomain, + ui2_password = _sPassword, + ui2_asg_type = 0, + ui2_usecount = 1 + }; + + uint paramErrorIndex; + uint returncode = NetUseAdd(null, 2, ref useinfo, out paramErrorIndex); + _iLastError = (int)returncode; + return returncode == 0; + } + catch { + _iLastError = Marshal.GetLastWin32Error(); + return false; + } + } + + /// + /// Ends the connection to the remote resource + /// + /// True if it succeeds. Use LastError to get the system error code + public bool NetUseDelete() { + try { + uint returncode = NetUseDel(null, _sUncPath, 2); + _iLastError = (int)returncode; + return (returncode == 0); + } + catch { + _iLastError = Marshal.GetLastWin32Error(); + return false; + } + } + + ~UNCAccessWithCredentials() { + Dispose(); + } + } +} diff --git a/client/Maestro/Configuration/ConfigurationInfo.cs b/client/Maestro/Configuration/ConfigurationInfo.cs index bc2dc1a8..b09fc8a3 100644 --- a/client/Maestro/Configuration/ConfigurationInfo.cs +++ b/client/Maestro/Configuration/ConfigurationInfo.cs @@ -64,6 +64,7 @@ namespace Maestro.Configuration { //[JsonConverter(typeof(KeysJsonConverter))] public Uri Address { get; set; } public string UserName { get; set; } + [JsonConverter(typeof(KeysJsonConverter))] public string Password { get; set; } public int Timeout { get; set; } } diff --git a/client/Maestro/Configuration/KeysJsonConverter.cs b/client/Maestro/Configuration/KeysJsonConverter.cs index c65c2bd8..e24d6872 100644 --- a/client/Maestro/Configuration/KeysJsonConverter.cs +++ b/client/Maestro/Configuration/KeysJsonConverter.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using PasswordEncrypter; using System; namespace Maestro.Configuration { @@ -7,7 +8,8 @@ namespace Maestro.Configuration { } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - return new Uri(serializer.Deserialize(reader, objectType)?.ToString()); + string result = serializer.Deserialize(reader, objectType)?.ToString(); + return StringCipher.Decrypt(result); } public override bool CanConvert(Type objectType) { diff --git a/client/Maestro/Configuration/configuration-editor.json b/client/Maestro/Configuration/configuration-editor.json index 4b210961..466af5f5 100644 --- a/client/Maestro/Configuration/configuration-editor.json +++ b/client/Maestro/Configuration/configuration-editor.json @@ -28,7 +28,7 @@ "server": { "address": "Data Source=10.10.1.45\\sql16;Initial Catalog=PA_Echo;Persist Security Info=True;", "userName": "MAM", - "password": "Echotv.hu", + "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 } }, @@ -50,6 +50,8 @@ "killDateDays": 7, "remote": { "address": "file://10.10.1.100/BRAAVOS/OCTOPUS", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -62,8 +64,8 @@ "killDateDays": 7, "remote": { "address": "ftp://10.10.1.56:2098", - "userName": "administaror", - "password": "system", + "userName": "administrator", + "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", "timeout": 1000 } }, @@ -77,6 +79,8 @@ "useMetadata": false, "remote": { "address": "file://10.10.1.100/BRAAVOS/OCTOPUS", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -90,6 +94,8 @@ "useMetadata": false, "remote": { "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -101,6 +107,8 @@ "killDateDays": 7, "remote": { "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -112,6 +120,8 @@ "useMetadata": true, "remote": { "address": "file://10.10.1.100/BRAAVOS/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } diff --git a/client/Maestro/Configuration/configuration-nle.json b/client/Maestro/Configuration/configuration-nle.json index a5d17193..28c548c5 100644 --- a/client/Maestro/Configuration/configuration-nle.json +++ b/client/Maestro/Configuration/configuration-nle.json @@ -28,7 +28,7 @@ "server": { "address": "Data Source=10.10.1.45\\sql16;Initial Catalog=PA_Echo;Persist Security Info=True;", "userName": "MAM", - "password": "Echotv.hu", + "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 } }, @@ -42,7 +42,7 @@ ], "targets": [ { - "label": "Nyersanyag betöltés", + "label": "Hír nyersanyag betöltés", "processor": "UNCTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", @@ -50,6 +50,8 @@ "killDateDays": 7, "remote": { "address": "file://10.10.1.100/BRAAVOS/OCTOPUS", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -61,10 +63,11 @@ "nexioServer": true, "agency": "NLE UPLOAD", "killDateDays": 7, + "reference": "Hír nyersanyag betöltés", "remote": { "address": "ftp://10.10.1.56:2098", - "userName": "administaror", - "password": "system", + "userName": "administrator", + "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", "timeout": 1000 } }, @@ -76,6 +79,8 @@ "killDateDays": 7, "remote": { "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -87,6 +92,8 @@ "useMetadata": true, "remote": { "address": "file://10.10.1.100/BRAAVOS/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } diff --git a/client/Maestro/Configuration/configuration-playout.json b/client/Maestro/Configuration/configuration-playout.json index fd0ad3b2..e61d9a05 100644 --- a/client/Maestro/Configuration/configuration-playout.json +++ b/client/Maestro/Configuration/configuration-playout.json @@ -11,7 +11,16 @@ "source": { "$type": "UNCSource", "local": { - "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_CHECK" + "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + }, + "remote": { + "address": "ftp://10.10.1.100/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 } }, "metadatas": [ @@ -27,7 +36,7 @@ "server": { "address": "Data Source=10.10.1.45\\sql16;Initial Catalog=PA_Echo;Persist Security Info=True;", "userName": "MAM", - "password": "Echotv.hu", + "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 } }, @@ -46,8 +55,12 @@ "outputFormat": "%ID%", "saveSegments": true, "tag": "Adáskész", + "reference": "Archiválás", "remote": { - "address": "file://10.10.1.100/BRAAVOS/PLAYOUT/IceGateway" + "address": "file://10.10.1.100/BRAAVOS/PLAYOUT/IceGateway", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 } }, { @@ -56,9 +69,27 @@ "outputFormat": "%ID%", "tag": "Újravágás", "remote": { - "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_NLE" + "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + }, + "sendSEmailOnSuccess": true, + "successEmailRecipient": "vasary@elgekko.net", + "successEmailPattern": "A %TARGETNAME% újravágása szükséges." + }, + { + "label": "Újravágás FXP", + "processor": "FXPTargetProcessor", + "outputFormat": "%ID%", + "tag": "Újravágás FXP", + "remote": { + "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 }, - "sendSEmailOnSuccess" : true, + "sendSEmailOnSuccess": false, "successEmailRecipient": "vasary@elgekko.net", "successEmailPattern": "A %TARGETNAME% újravágása szükséges." }, @@ -70,6 +101,8 @@ "createMetadata": true, "remote": { "address": "file://10.10.1.100/BRAAVOS/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } diff --git a/client/Maestro/Configuration/configuration-studio.json b/client/Maestro/Configuration/configuration-studio.json index 2933e813..60518050 100644 --- a/client/Maestro/Configuration/configuration-studio.json +++ b/client/Maestro/Configuration/configuration-studio.json @@ -14,7 +14,7 @@ "remote": { "address": "ftp://10.10.1.56:2098", "userName": "administrator", - "password": "system" + "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh" } }, "metadatas": [ @@ -30,7 +30,7 @@ "server": { "address": "Data Source=10.10.1.45\\sql16;Initial Catalog=PA_Echo;Persist Security Info=True;", "userName": "MAM", - "password": "Echotv.hu", + "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 } }, @@ -38,6 +38,8 @@ "$type": "MediaCubeMetadata", "server": { "address": "http://10.10.1.28/services/rest/jobengine", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } @@ -51,17 +53,21 @@ "remote": { "address": "ftp://10.10.1.100:21/PLAYOUT_CHECK", "userName": "mediacube", - "password": "Broadca5T" + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 } }, { "label": "Archiválás", - "processor": "UNCTargetProcessor", + "processor": "FXPTargetProcessor", "outputFormat": "%ID%", "tag": "Archiválás", "createMetadata": true, "remote": { - "address": "file://10.10.1.100/BRAAVOS/ARCHIVE" + "address": "ftp://10.10.1.100:21/BRAAVOS/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 } } ] diff --git a/client/Maestro/Configuration/configuration-sxs.json b/client/Maestro/Configuration/configuration-sxs.json index 40127a92..407b1d75 100644 --- a/client/Maestro/Configuration/configuration-sxs.json +++ b/client/Maestro/Configuration/configuration-sxs.json @@ -28,7 +28,7 @@ "server": { "address": "Data Source=10.10.1.45\\sql16;Initial Catalog=PA_Echo;Persist Security Info=True;", "userName": "MAM", - "password": "Echotv.hu", + "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 } }, @@ -51,6 +51,8 @@ "useMetadata": false, "remote": { "address": "file://10.10.1.100/BRAAVOS/OCTOPUS", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -64,6 +66,8 @@ "useMetadata": false, "remote": { "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -75,6 +79,8 @@ "killDateDays": 7, "remote": { "address": "file://10.10.1.100/BRAAVOS/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, @@ -86,6 +92,8 @@ "useMetadata": true, "remote": { "address": "file://10.10.1.100/BRAAVOS/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } diff --git a/client/Maestro/Maestro.csproj b/client/Maestro/Maestro.csproj index 5c057d7c..6fa4b0a3 100644 --- a/client/Maestro/Maestro.csproj +++ b/client/Maestro/Maestro.csproj @@ -321,6 +321,10 @@ {8CC7C930-9DBF-487B-AED5-776937A649D5} OctopusClient + + {8c51d508-1759-4c10-84a4-80965fd074ff} + PasswordEncrypter + {a7a21311-cb0e-465f-8ad6-829faf093f00} TrafficClient diff --git a/client/Maestro/MaestroForm.Target.cs b/client/Maestro/MaestroForm.Target.cs index 46128517..d47e79de 100644 --- a/client/Maestro/MaestroForm.Target.cs +++ b/client/Maestro/MaestroForm.Target.cs @@ -56,61 +56,87 @@ namespace Maestro { Dock = DockStyle.Top, Tag = target }; - checkBox.CheckStateChanged += (s, e) => { - OnChecked(checkBox, target); - }; - + checkBox.CheckStateChanged += (s, e) => OnChecked(checkBox, target); panelActions.Controls.Add(checkBox); panelActions.RowCount = panelActions.Controls.Count; - } - private void OnChecked(object sender, Target target) { - CheckBox checkBox = sender as CheckBox; - if (checkBox == null) - return; + private void OnChecked(CheckBox checkBox, Target target) { if (checkBox.Checked) { - List processors = new List(); - foreach (DataGridViewRow actualRow in selectedSourceRows) { - ISourceItem sourceItem = actualRow.DataBoundItem as ISourceItem; - if (sourceItem == null) - continue; - string typeName = string.Format("{0}.{1}", typeof(ITargetProcessor).Namespace, target.Processor); - Type type = Type.GetType(typeName); - string id = selectedMetadata == null ? textSelectedMetadata.Text : selectedMetadata.ID; - if (segments == null) { - if (target.SaveSegments) { - segments = trafficIDSelector.trafficAPI.GetSegments(selectedMetadata.VariantID); - if (segments == null) { - //todo error report küldés? - } - } else segments = new List(); - } - TargetProcessorParameter processorParameter = new TargetProcessorParameter() { - ArchiveMetadata = ArchiveMetadata.DeepClone(archiveMetadatamodel), - Client = trafficIDSelector.trafficAPI, - ID = id, - InputFileName = sourceItem.Name, - MediaCubeApi = mediaCubeApi, - Segments = new List(segments), - SourceConfig = Configuration.Source, - TargetConfig = target, - VariantID = selectedMetadata == null ? 0 : selectedMetadata.VariantID - }; - object[] parameters = new object[] { this, processorParameter }; - ITargetProcessor processor = (ITargetProcessor)Activator.CreateInstance(type, parameters); - processors.Add(processor); - if (!String.IsNullOrEmpty(target.Reference)) - SetCheckBoxReferences(target.Reference, true); - } + List processors = CreateProcessors(target, checkBox); currentProcessors.Add(checkBox, processors); } else { - SetCheckBoxReferences(target.Reference, false); + HandleCheckBoxReferences(target.Reference, false); currentProcessors.Remove(checkBox); } btnExecute.Enabled = currentProcessors.Count > 0; } + private List CreateProcessors(Target target, CheckBox checkBox) { + List result = null; + foreach (DataGridViewRow actualRow in selectedSourceRows) { + ISourceItem sourceItem = actualRow.DataBoundItem as ISourceItem; + if (sourceItem == null) + continue; + if (!EnsureSegments(target)) { + checkBox.Checked = false; + continue; + } + if (!EnsureMetadata(target)) { + checkBox.Checked = false; + continue; + } + TargetProcessorParameter processorParameter = CreateProcessorParameter(target, sourceItem); + ITargetProcessor processor = CreateProcessor(target, processorParameter); + if (result == null) + result = new List(); + result.Add(processor); + HandleCheckBoxReferences(target.Reference, true); + } + return result; + } + + private bool EnsureSegments(Target target) { + if (target.SaveSegments && segments == null) { + segments = trafficIDSelector.trafficAPI.GetSegments(selectedMetadata.VariantID); + if (segments == null) { + MessageBox.Show("A {0} folyamat nem futtatható szegmens adatok nélkül."); + return false; + } + } + return true; + } + + private bool EnsureMetadata(Target target) { + if (target.CreateMetadata && (archiveMetadatamodel == null || !archiveMetadatamodel.IsFilled)) { + segments = trafficIDSelector.trafficAPI.GetSegments(selectedMetadata.VariantID); + if (segments == null) { + MessageBox.Show("A {0} folyamat nem futtatható kísérő adatok nélkül."); + return false; + } + } + return true; + } + + private ITargetProcessor CreateProcessor(Target target, TargetProcessorParameter processorParameter) { + string typeName = string.Format("{0}.{1}", typeof(ITargetProcessor).Namespace, target.Processor); + return (ITargetProcessor)Activator.CreateInstance(Type.GetType(typeName), new object[] { this, processorParameter }); + } + + private TargetProcessorParameter CreateProcessorParameter(Target target, ISourceItem sourceItem) { + return new TargetProcessorParameter() { + ArchiveMetadata = ArchiveMetadata.DeepClone(archiveMetadatamodel), + Client = trafficIDSelector.trafficAPI, + ID = selectedMetadata == null ? textSelectedMetadata.Text : selectedMetadata.ID, + InputFileName = sourceItem.Name, + MediaCubeApi = mediaCubeApi, + Segments = segments == null ? null : new List(segments), + SourceConfig = Configuration.Source, + TargetConfig = target, + VariantID = selectedMetadata == null ? 0 : selectedMetadata.VariantID + }; + } + private bool IsOffCheckAble(String text) { List checkBoxes = new List(currentProcessors.Keys); foreach (CheckBox actual in checkBoxes) { @@ -121,7 +147,9 @@ namespace Maestro { return true; } - private void SetCheckBoxReferences(string reference, bool check) { + private void HandleCheckBoxReferences(string reference, bool check) { + if (String.IsNullOrEmpty(reference)) + return; var controlls = panelActions.Controls; foreach (Control actual in controlls) { CheckBox actualCheckbox = actual as CheckBox; @@ -193,14 +221,14 @@ namespace Maestro { Cursor.Current = Cursors.WaitCursor; IDTypes idType = GetTypeOfSelectedMetadata(); if (idType == IDTypes.OctopusID) - FillTheModelFromOctopus(archiveMetadatamodel); + GetOctopusMetadata(archiveMetadatamodel); else //if (idType == IDTypes.TrafficID) - FillTheModelFromTraffic(archiveMetadatamodel); + GetTrafficMetadata(archiveMetadatamodel); } else archiveMetadatamodel = null; } - private void FillTheModelFromTraffic(ArchiveMetadata model) { + private void GetTrafficMetadata(ArchiveMetadata model) { string id = selectedMetadata.ID; TrafficAPI api = trafficIDSelector.trafficAPI; List result = null; @@ -223,7 +251,7 @@ namespace Maestro { model.mediaDescription = actualResult.EpisodeDescription; } - private void FillTheModelFromOctopus(ArchiveMetadata model) { + private void GetOctopusMetadata(ArchiveMetadata model) { string id = selectedMetadata.ID; OctopusAPI api = octopusIDSelector.GetClient(); IEnumerable storyEnum = api.GetStoriesById(id); diff --git a/client/Maestro/MeastroFormNotifyIcon.cs b/client/Maestro/MeastroFormNotifyIcon.cs index 3fa7ac9b..4182c2e6 100644 --- a/client/Maestro/MeastroFormNotifyIcon.cs +++ b/client/Maestro/MeastroFormNotifyIcon.cs @@ -29,19 +29,19 @@ namespace Maestro { private void OnFileCreated(FileActionMsg m) { if (!form.Equals(m.Source)) return; - Show(String.Format("File {0} created in source {1}", m.FileName, m.Source.Text)); + Show(String.Format("Új fájl a {1} forrásban: {0}", m.FileName, m.Source.Text)); } private void OnFileModified(FileActionMsg m) { if (!form.Equals(m.Source)) return; - Show(String.Format("File {0} modified in source {1}", m.FileName, m.Source.Text)); + Show(String.Format("Módosult fájl a {1} forrásban: {0}", m.FileName, m.Source.Text)); } private void OnFileRemoved(FileActionMsg m) { if (!form.Equals(m.Source)) return; - Show(String.Format("File {0} removed in source {1}", m.FileName, m.Source.Text)); + Show(String.Format("Törölt fájl a {1} forrásban: {0}", m.FileName, m.Source.Text)); } public void Show(string tooltipText) { @@ -49,7 +49,7 @@ namespace Maestro { return; notification.BalloonTipText = tooltipText; notification.Visible = true; - notification.ShowBalloonTip(3); + notification.ShowBalloonTip(1); } public void ShowForm() { diff --git a/client/Maestro/Metadata/ArchiveMetadata.cs b/client/Maestro/Metadata/ArchiveMetadata.cs index 3226d64c..d3a4d138 100644 --- a/client/Maestro/Metadata/ArchiveMetadata.cs +++ b/client/Maestro/Metadata/ArchiveMetadata.cs @@ -22,6 +22,16 @@ namespace Maestro.Metadata { // StuffID, StuffTitle, StuffDescription, MediaID, MediaTitle, MediaDescription); } + public bool IsFilled { + get { + return + !String.IsNullOrEmpty(itemHouseId) && + !String.IsNullOrEmpty(itemTitle) && + !String.IsNullOrEmpty(mediaHouseId) && + !String.IsNullOrEmpty(mediaTitle); + } + } + public static ArchiveMetadata DeepClone(ArchiveMetadata obj) { if (obj == null) return null; diff --git a/client/Maestro/Program.cs b/client/Maestro/Program.cs index 718fcd0a..1c75e6cd 100644 --- a/client/Maestro/Program.cs +++ b/client/Maestro/Program.cs @@ -10,6 +10,9 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Security.Principal; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -23,9 +26,33 @@ namespace Maestro { /// [STAThread] static void Main() { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new TrayApplicationContext()); + string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString(); + string mutexId = string.Format("Global\\{{{0}}}", appGuid); + bool createdNew; + var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); + var securitySettings = new MutexSecurity(); + securitySettings.AddAccessRule(allowEveryoneRule); + using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { + var hasHandle = false; + try { + try { + hasHandle = mutex.WaitOne(500, false); + if (hasHandle == false) + MessageBox.Show("A MediaCube Maestro alkalmazás már fut egy példányban."); + } + catch (AbandonedMutexException) { + hasHandle = true; + } + } + finally { + if (hasHandle) { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new TrayApplicationContext()); + mutex.ReleaseMutex(); + } + } + } } } @@ -63,6 +90,8 @@ namespace Maestro { private void CreateForm(string file) { try { ConfigurationInfo config = Loader.Get(file); + //string decryptedstring = StringCipher.Decrypt(encryptedstring, password); + if (!config.Active) return; MeastroFormNotifyIcon form = new MeastroFormNotifyIcon(config, messageBus); @@ -100,7 +129,7 @@ namespace Maestro { ContextMenu = new ContextMenu(menuItems.ToArray()), Visible = true }; - trayIcon.Click += TrayIcon_Click; + //trayIcon.Click += TrayIcon_Click; } private void TrayIcon_Click(object sender, EventArgs e) { diff --git a/client/Maestro/Targets/FXPTargetProcessor.cs b/client/Maestro/Targets/FXPTargetProcessor.cs index 11831ea0..bf7fd742 100644 --- a/client/Maestro/Targets/FXPTargetProcessor.cs +++ b/client/Maestro/Targets/FXPTargetProcessor.cs @@ -27,7 +27,10 @@ namespace Maestro.Targets { try { sourceFTP = CreateClient(sourceConfig.Remote); - long ilength = sourceFTP.GetFileSize(inputUri.AbsolutePath) / 2; + + long ilength = sourceFTP.GetFileSize(inputUri.AbsolutePath); + if (parameters.TargetConfig.NexioServer) + ilength = ilength / 2; FtpReply replyPASV = targetFTP.Execute("PASV"); if (!replyPASV.Success) @@ -46,7 +49,7 @@ namespace Maestro.Targets { if (!sourceReplyTYPE.Success) throw new Exception(sourceReplyTYPE.ErrorMessage); - FtpReply replyRETR = sourceFTP.Execute("RETR " + inputUri.AbsolutePath.Replace("/", "")); + FtpReply replyRETR = sourceFTP.Execute("RETR " + inputUri.AbsolutePath); if (!replyRETR.Success) { replyRETR = sourceFTP.Execute("RETR " + inputUri.Segments[inputUri.Segments.Length - 1]); diff --git a/client/MediaCube.sln b/client/MediaCube.sln index 56647098..f7e2b958 100644 --- a/client/MediaCube.sln +++ b/client/MediaCube.sln @@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AudioRecorder", "AudioRecor EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrafficClient", "PlanAIRClient\TrafficClient.csproj", "{A7A21311-CB0E-465F-8AD6-829FAF093F00}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PasswordEncrypter", "PasswordEncrypter\PasswordEncrypter.csproj", "{8C51D508-1759-4C10-84A4-80965FD074FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -108,12 +110,24 @@ Global {A7A21311-CB0E-465F-8AD6-829FAF093F00}.Release|x64.Build.0 = Release|Any CPU {A7A21311-CB0E-465F-8AD6-829FAF093F00}.Release|x86.ActiveCfg = Release|Any CPU {A7A21311-CB0E-465F-8AD6-829FAF093F00}.Release|x86.Build.0 = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|x64.Build.0 = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Debug|x86.Build.0 = Debug|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|Any CPU.Build.0 = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|x64.ActiveCfg = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|x64.Build.0 = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|x86.ActiveCfg = Release|Any CPU + {8C51D508-1759-4C10-84A4-80965FD074FF}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 8 + SccNumberOfProjects = 9 SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} SccTeamFoundationServer = https://tfs.userrendszerhaz.hu/tfs/defaultcollection SccLocalPath0 = . @@ -138,5 +152,8 @@ Global SccProjectUniqueName7 = Maestro\\Maestro.csproj SccProjectName7 = Maestro SccLocalPath7 = Maestro + SccProjectUniqueName8 = PasswordEncrypter\\PasswordEncrypter.csproj + SccProjectName8 = PasswordEncrypter + SccLocalPath8 = PasswordEncrypter EndGlobalSection EndGlobal diff --git a/client/PasswordEncrypter/App.config b/client/PasswordEncrypter/App.config new file mode 100644 index 00000000..00bfd114 --- /dev/null +++ b/client/PasswordEncrypter/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/client/PasswordEncrypter/PasswordEncrypter.csproj b/client/PasswordEncrypter/PasswordEncrypter.csproj new file mode 100644 index 00000000..0d11f917 --- /dev/null +++ b/client/PasswordEncrypter/PasswordEncrypter.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {8C51D508-1759-4C10-84A4-80965FD074FF} + Exe + PasswordEncrypter + PasswordEncrypter + v4.6.1 + 512 + true + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/PasswordEncrypter/Program.cs b/client/PasswordEncrypter/Program.cs new file mode 100644 index 00000000..37cb21e6 --- /dev/null +++ b/client/PasswordEncrypter/Program.cs @@ -0,0 +1,23 @@ +using System; +using System.Windows.Forms; + +namespace PasswordEncrypter { + class Program { + + [STAThread] + static void Main(string[] args) { + Console.WriteLine("Eredeti jelszó:"); + string password = Console.ReadLine(); + + Console.WriteLine("Kódolt jelszó a vágólapon:"); + string encryptedstring = StringCipher.Encrypt(password); + Console.WriteLine(encryptedstring); + Clipboard.SetText(encryptedstring); + + string originalstring = StringCipher.Decrypt(encryptedstring); + Console.WriteLine("Ellenőrzés:"); + Console.WriteLine(originalstring); + Console.ReadLine(); + } + } +} diff --git a/client/PasswordEncrypter/Properties/AssemblyInfo.cs b/client/PasswordEncrypter/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..92fde9a5 --- /dev/null +++ b/client/PasswordEncrypter/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PasswordEncrypter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PasswordEncrypter")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8c51d508-1759-4c10-84a4-80965fd074ff")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/client/PasswordEncrypter/StringCipher.cs b/client/PasswordEncrypter/StringCipher.cs new file mode 100644 index 00000000..eb06e399 --- /dev/null +++ b/client/PasswordEncrypter/StringCipher.cs @@ -0,0 +1,107 @@ +using System; +using System.Text; +using System.Security.Cryptography; +using System.IO; +using System.Linq; + +namespace PasswordEncrypter { + + public static class StringCipher + { + public static string helper = "Tetszőleges"; + + // 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) + { + // 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(helper, 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); + //return Encoding.UTF8.GetString(cipherTextBytes); + } + } + } + } + } + } + + public static string Decrypt(string cipherText) + { + // 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(helper, 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; + } + } +}