diff --git a/ClientServerLib/ClientServerLib/CConnection.cs b/ClientServerLib/ClientServerLib/CConnection.cs index 628381cb..c217bd4b 100644 --- a/ClientServerLib/ClientServerLib/CConnection.cs +++ b/ClientServerLib/ClientServerLib/CConnection.cs @@ -13,6 +13,7 @@ namespace ClientServerLib internal class CConnection { private bool keySet; + private bool encryption; private CDiffieHellman dh; private UTF8Encoding encoder; private int connectionID; @@ -29,17 +30,23 @@ namespace ClientServerLib get { return connectionID; } } - public CConnection(TcpClient client, int ConnectionID) + public CConnection(TcpClient client, int ConnectionID, bool Encryption = false) { TcpClient = client; client.NoDelay = true; keySet = false; + encryption = Encryption; connectionID = ConnectionID; encoder = new UTF8Encoding(); } public byte[] GetKeyParams() { + if (!encryption) + { + return encoder.GetBytes("NO ENCRYPTION"); + } + if (dh == null) dh = new CDiffieHellman(256).GenerateRequest(); @@ -51,34 +58,65 @@ namespace ClientServerLib if (serverParam == null) return null; - dh = new CDiffieHellman(256).GenerateResponse( - encoder.GetString(serverParam, 0, serverParam.Length)); + string response = encoder.GetString(serverParam, 0, serverParam.Length); + if (response == "NO ENCRYPTION") + { + encryption = false; + keySet = true; + return encoder.GetBytes(response); + } + + dh = new CDiffieHellman(256).GenerateResponse(response); keySet = true; + encryption = true; return encoder.GetBytes(dh.ToString()); } public void CreateServerKey(byte[] clientResponse) { + string response = encoder.GetString(clientResponse, 0, clientResponse.Length); + + if (response == "NO ENCRYPTION") + { + keySet = true; + return; + } + if (dh == null) return; - dh.HandleResponse(encoder.GetString(clientResponse, 0, clientResponse.Length)); + dh.HandleResponse(response); keySet = true; } public byte[] Encrypt(byte[] Data) { - if (Data == null || !keySet) + if (Data == null || (!keySet && encryption)) return Data; + byte[] dataLength = BitConverter.GetBytes(Data.Length); + + if (!encryption) + { + int len = 4 + dataLength.Length + Data.Length; + byte[] messageLength = BitConverter.GetBytes(len); + + using (var stream = new MemoryStream()) + { + stream.Write(messageLength, 0, messageLength.Length); + stream.Write(dataLength, 0, dataLength.Length); + stream.Write(Data, 0, Data.Length); + + return stream.ToArray(); + } + } + using (Aes aes = new AesManaged()) { aes.Key = dh.Key; aes.GenerateIV(); - byte[] dataLength = BitConverter.GetBytes(Data.Length); - using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV)) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) @@ -91,32 +129,47 @@ namespace ClientServerLib int len = 4 + aes.IV.Length + dataLength.Length + encrypted.Length; byte[] messageLength = BitConverter.GetBytes(len); - MemoryStream stream = new MemoryStream(); - stream.Write(messageLength, 0, messageLength.Length); - stream.Write(aes.IV, 0, aes.IV.Length); - stream.Write(dataLength, 0, dataLength.Length); - stream.Write(encrypted, 0, encrypted.Length); + using (var stream = new MemoryStream()) + { + stream.Write(messageLength, 0, messageLength.Length); + stream.Write(aes.IV, 0, aes.IV.Length); + stream.Write(dataLength, 0, dataLength.Length); + stream.Write(encrypted, 0, encrypted.Length); - return stream.ToArray(); + return stream.ToArray(); + } } } } public byte[] Decrypt(byte[] Data) { - if (Data == null || !keySet) + if (Data == null || (!keySet && encryption)) return Data; - if (Data.Length < 25) - return null; - + int messageLength = BitConverter.ToInt32(Data, 0); if (messageLength > Data.Length) return null; + int dataLength; + + if (!encryption) + { + dataLength = BitConverter.ToInt32(Data, 4); + + byte[] message = new byte[dataLength]; + Array.Copy(Data, 8, message, 0, dataLength); + return message; + } + + if (Data.Length < 25) + return null; + byte[] IV = new byte[16]; Array.Copy(Data, 4, IV, 0, 16); - int dataLength = BitConverter.ToInt32(Data, 20); + + dataLength = BitConverter.ToInt32(Data, 20); using (Aes aes = new AesManaged()) { diff --git a/ClientServerLib/ClientServerLib/CServer.cs b/ClientServerLib/ClientServerLib/CServer.cs index a02b1f41..b91ba110 100644 --- a/ClientServerLib/ClientServerLib/CServer.cs +++ b/ClientServerLib/ClientServerLib/CServer.cs @@ -13,6 +13,7 @@ namespace ClientServerLib private TcpListener tcpListener; private Thread listenThread; private int port; + private bool encryption; private int bufferLength = 8192; private bool running; @@ -21,11 +22,12 @@ namespace ClientServerLib private Dictionary clients; private Queue ids; - public CServer(HandleRequest RequestCallback, int Port = 3000) + public CServer(HandleRequest RequestCallback, int Port = 3000, bool Encryption = false) { port = Port; running = false; requestCallback = RequestCallback; + encryption = Encryption; clients = new Dictionary(); ids = new Queue(1000); @@ -90,7 +92,7 @@ namespace ClientServerLib if (client != null) { int id = ids.Dequeue(); - CConnection connection = new CConnection(client, id); + CConnection connection = new CConnection(client, id, encryption); lock (clients) { diff --git a/Output/ClientServerLib.dll b/Output/ClientServerLib.dll index 6931132f..f59ca7e8 100644 Binary files a/Output/ClientServerLib.dll and b/Output/ClientServerLib.dll differ diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index 7b6e35e2..ae7c18af 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -115,7 +115,8 @@ namespace Vocaluxe.Base public static SWebcamConfig WebcamConfig; // Server - public static EOffOn Server = EOffOn.TR_CONFIG_ON; + public static EOffOn ServerActive = EOffOn.TR_CONFIG_OFF; + public static EOffOn ServerEncryption = EOffOn.TR_CONFIG_OFF; public static int ServerPort = 3000; public static string ServerPassword = "vocaluxe"; @@ -280,6 +281,16 @@ namespace Vocaluxe.Base xmlReader.TryGetIntValueRange("//root/Record/MicDelay", ref MicDelay, 0, 500); MicDelay = (int)(20 * Math.Round(MicDelay / 20.0)); #endregion Record + + #region Server + xmlReader.TryGetEnumValue("//root/Server/ServerActive", ref ServerActive); + xmlReader.TryGetEnumValue("//root/Server/ServerEncryption", ref ServerEncryption); + xmlReader.TryGetIntValue("//root/Server/ServerPort", ref ServerPort); + if (ServerPort < 1 || ServerPort > 65535) + ServerPort = 3000; + + xmlReader.GetValue("//root/Server/ServerPassword", out ServerPassword, ServerPassword); + #endregion Server } public static bool SaveConfig() @@ -362,25 +373,25 @@ namespace Vocaluxe.Base writer.WriteComment("Name of cover-theme"); writer.WriteElementString("Cover", CoverTheme); - writer.WriteComment("Draw note-lines:" + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); + writer.WriteComment("Draw note-lines: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); writer.WriteElementString("DrawNoteLines", Enum.GetName(typeof(EOffOn), DrawNoteLines)); - writer.WriteComment("Draw tone-helper:" + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); + writer.WriteComment("Draw tone-helper: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); writer.WriteElementString("DrawToneHelper", Enum.GetName(typeof(EOffOn), DrawToneHelper)); - writer.WriteComment("Look of timer:" + CHelper.ListStrings(Enum.GetNames(typeof(ETimerLook)))); + writer.WriteComment("Look of timer: " + CHelper.ListStrings(Enum.GetNames(typeof(ETimerLook)))); writer.WriteElementString("TimerLook", Enum.GetName(typeof(ETimerLook), TimerLook)); - writer.WriteComment("Information about players on SingScreen:" + CHelper.ListStrings(Enum.GetNames(typeof(EPlayerInfo)))); + writer.WriteComment("Information about players on SingScreen: " + CHelper.ListStrings(Enum.GetNames(typeof(EPlayerInfo)))); writer.WriteElementString("PlayerInfo", Enum.GetName(typeof(EPlayerInfo), PlayerInfo)); - writer.WriteComment("Fade player-information with lyrics and notebars:" + CHelper.ListStrings(Enum.GetNames(typeof(EFadePlayerInfo)))); + writer.WriteComment("Fade player-information with lyrics and notebars: " + CHelper.ListStrings(Enum.GetNames(typeof(EFadePlayerInfo)))); writer.WriteElementString("FadePlayerInfo", Enum.GetName(typeof(EFadePlayerInfo), FadePlayerInfo)); - writer.WriteComment("Cover Loading:" + CHelper.ListStrings(Enum.GetNames(typeof(ECoverLoading)))); + writer.WriteComment("Cover Loading: " + CHelper.ListStrings(Enum.GetNames(typeof(ECoverLoading)))); writer.WriteElementString("CoverLoading", Enum.GetName(typeof(ECoverLoading), CoverLoading)); - writer.WriteComment("Lyric Style:" + CHelper.ListStrings(Enum.GetNames(typeof(ELyricStyle)))); + writer.WriteComment("Lyric Style: " + CHelper.ListStrings(Enum.GetNames(typeof(ELyricStyle)))); writer.WriteElementString("LyricStyle", Enum.GetName(typeof(ELyricStyle), LyricStyle)); writer.WriteEndElement(); @@ -401,15 +412,16 @@ namespace Vocaluxe.Base writer.WriteComment("AudioLatency from -500 to 500 ms"); writer.WriteElementString("AudioLatency", AudioLatency.ToString()); - writer.WriteComment("Background Music"); + writer.WriteComment("Background Music: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); writer.WriteElementString("BackgroundMusic", Enum.GetName(typeof(EOffOn), BackgroundMusic)); writer.WriteComment("Background Music Volume from 0 to 100"); writer.WriteElementString("BackgroundMusicVolume", BackgroundMusicVolume.ToString()); - writer.WriteComment("Background Music Source"); + writer.WriteComment("Background Music Source: " + CHelper.ListStrings(Enum.GetNames(typeof(EBackgroundMusicSource)))); writer.WriteElementString("BackgroundMusicSource", Enum.GetName(typeof(EBackgroundMusicSource), BackgroundMusicSource)); - writer.WriteComment("Background Music use start-tag of songs"); + + writer.WriteComment("Background Music use start-tag of songs: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); writer.WriteElementString("BackgroundMusicUseStart", Enum.GetName(typeof(EOffOn), BackgroundMusicUseStart)); writer.WriteComment("Preview Volume from 0 to 100"); @@ -539,6 +551,24 @@ namespace Vocaluxe.Base writer.WriteEndElement(); #endregion Record + #region Server + writer.WriteStartElement("Server"); + + writer.WriteComment("Server On/Off: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); + writer.WriteElementString("ServerActive", Enum.GetName(typeof(EOffOn), ServerActive)); + + writer.WriteComment("Server Encryption On/Off: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); + writer.WriteElementString("ServerEncryption", Enum.GetName(typeof(EOffOn), ServerEncryption)); + + writer.WriteComment("Server Port (default: 3000) [1..65535]"); + writer.WriteElementString("ServerPort", ServerPort.ToString()); + + writer.WriteComment("Server Password (default: vocaluxe)"); + writer.WriteElementString("ServerPassword", ServerPassword); + + writer.WriteEndElement(); + #endregion Server + // End of File writer.WriteEndElement(); //end of root writer.WriteEndDocument(); diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index 020ba745..f82f81b5 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -26,13 +26,13 @@ namespace Vocaluxe.Base.Server public static void Init() { _Clients = new Dictionary(); - _Server = new CServer(RequestHandler, CConfig.ServerPort); + _Server = new CServer(RequestHandler, CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON); Controller.Init(); } public static void Start() { - if (CConfig.Server == EOffOn.TR_CONFIG_ON) + if (CConfig.ServerActive == EOffOn.TR_CONFIG_ON) _Server.Start(); }