diff --git a/ChatController/HauptKlassen/Chat.cs b/ChatController/HauptKlassen/Chat.cs index 231b546..d140728 100644 --- a/ChatController/HauptKlassen/Chat.cs +++ b/ChatController/HauptKlassen/Chat.cs @@ -73,6 +73,10 @@ namespace ChatController.HauptKlassen ServicePointManager.ServerCertificateValidationCallback = PinPublicKey; } + //!!!!Wenn hier neue Keys hinzugefügt werden, muss das auch in der Klasse BeWo.LoginControl und im DatabaseTerminator gemacht werden!! + + private const string PinningFailMessage = "Es konnte keine sichere Verbindung zum Server hergestellt werden."; + private const String PUB_KEY_X3 = "9CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001"; private const String PUB_KEY_R3 = "BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001"; @@ -124,8 +128,7 @@ namespace ChatController.HauptKlassen } - - //!!!!Wenn hier neue Keys hinzugefügt werden, muss das auch in der Klasse BeWo.LoginControl und im DatabaseTerminator gemacht werden!! + public List AddContacts() { @@ -227,7 +230,7 @@ namespace ChatController.HauptKlassen public void CheckIfNewMessagesExistAsync(long groupId, Action callback) { #if DEBUG - if(_UserMessages.Response is null) + if(_UserMessages?.Response is null) { throw new Exception("Too many requests."); } diff --git a/ChatController/HauptKlassen/Login.cs b/ChatController/HauptKlassen/Login.cs index d12455c..4d94464 100644 --- a/ChatController/HauptKlassen/Login.cs +++ b/ChatController/HauptKlassen/Login.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using System.Web; using System.Windows; using ChatController.Core; @@ -18,6 +20,74 @@ namespace ChatController.HauptKlassen { public class Login { + private Action _ExceptionCallback; + + private void PinCertificate() + { + ServicePointManager.ServerCertificateValidationCallback = PinPublicKey; + } + + private bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors) + { + try + { + if(certificate is null || chain is null) + { + return false; + } + + var chainContainsPk = false; + + foreach(var element in chain.ChainElements) + { + var pk = element.Certificate.GetPublicKeyString(); + if(pk == PubKeyX3 || pk == PubKeyR3 || pk == PubKeyE1) + { + chainContainsPk = true; + } + } + + var subjectAccepted = certificate.Subject.Trim().ToLower().EndsWith(".bewoplaner.de") || certificate.Subject.Trim().ToLower().EndsWith(".ownchat.de"); + + var result = chainContainsPk && subjectAccepted; + + if(false == result) + { + throw new Exception(PinningFailMessage); + } + + return result; + } + catch(Exception exception) + { + if(exception.Message?.Equals(PinningFailMessage) ?? false) + { + _ExceptionCallback?.Invoke(PinningFailMessage); + } + + return false; + } + } + + private const string PinningFailMessage = "Es konnte keine sichere Verbindung zum Server hergestellt werden."; + + private const string PubKeyX3 = "3082010A02820101009CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001"; + + private const string PubKeyR3 = "3082010A0282010100BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001"; + + private const string PubKeyE1 = "04245C2DA22AFD1C4BA65D97732731ACB2A06962EF65E8A6B0F0AC4B9FFF1C0B700FD3982F4DFC0F009B37F074055732972E05EF2A4325A3FB6E342713F64F7E69D302995EEB244792C1249BE6B1218FC12481FC68CC1F69BA58F51922F774C616"; + + + + + + + + + + + + private string _BaseUrl = string.Empty; private const string DictionaryServerUrl = "https://dict.ownchat.de/api/server/resolve/1/"; @@ -115,7 +185,11 @@ namespace ChatController.HauptKlassen public void DoLoginAsync(Action callback, Action exceptionCallback) { - LookupServerUrlAsync(isConnectedWithServer => + try + { + _ExceptionCallback = exceptionCallback; + + LookupServerUrlAsync(isConnectedWithServer => { if(isConnectedWithServer) { @@ -132,55 +206,83 @@ namespace ChatController.HauptKlassen { callback?.Invoke(new ChatDatenUebergabe(_LoggedInUser, _AllGroups, ServerUrl, _AuthToken, _UserId, _Tenant, _ApiKey, maxUploadFileSize)); }); - } + } }); } - }, + }, errorMessage => { exceptionCallback?.Invoke(errorMessage); }); } }, errorMessage => { exceptionCallback?.Invoke(errorMessage); }); + } + catch(Exception exception) + { + exceptionCallback?.Invoke(exception.Message); + } } public void LookupServerUrlAsync(Action callback, Action exceptionCallback) { - if(!string.IsNullOrWhiteSpace(ServerUrl)) + try { - callback?.Invoke(false); - return; - } - - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - - var client = new RestClient(DictionaryServerUrl); - var request = new RestRequest(_Tenant); - - client.ExecuteAsync(request, response => - { - var lookupResult = JsonConvert.DeserializeObject(response.Content); - - _BaseUrl = lookupResult.Url; - ServerUrl = _BaseUrl; - OwnChatCache.BaseUri = _BaseUrl; - - var result = false; - - switch(lookupResult.Status) + if(!string.IsNullOrWhiteSpace(ServerUrl)) { - case 0: - result = true; - break; - case 1: - exceptionCallback?.Invoke("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen."); - break; - case 2: - exceptionCallback?.Invoke("Der Diensttyp ist für die angegebene Kundennummer nicht definiert."); - MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk); - break; + callback?.Invoke(false); + return; } - callback?.Invoke(result); - }); + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + + PinCertificate(); + + var client = new RestClient(DictionaryServerUrl); + var request = new RestRequest(_Tenant); + + client.ExecuteAsync(request, response => + { + var lookupResult = JsonConvert.DeserializeObject(response.Content); + + if(lookupResult is null) + { + if(response.ErrorException?.InnerException?.Message.Equals(PinningFailMessage) ?? false) + { + exceptionCallback?.Invoke(PinningFailMessage); + } + else + { + exceptionCallback?.Invoke("Anmeldung nicht möglich. Bitte prüfen Sie Ihre Internet-Verbindung."); + } + + return; + } + + _BaseUrl = lookupResult.Url; + ServerUrl = _BaseUrl; + OwnChatCache.BaseUri = _BaseUrl; + + var result = false; + + switch(lookupResult.Status) + { + case 0: + result = true; + break; + case 1: + exceptionCallback?.Invoke("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen."); + break; + case 2: + exceptionCallback?.Invoke("Der Diensttyp ist für die angegebene Kundennummer nicht definiert."); + MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk); + break; + } + + callback?.Invoke(result); + }); + } + catch(Exception exception) + { + exceptionCallback?.Invoke(exception.Message); + } } public bool ServerErmittlung() diff --git a/ChatController/LoginControl.xaml.cs b/ChatController/LoginControl.xaml.cs index f015062..23ba140 100644 --- a/ChatController/LoginControl.xaml.cs +++ b/ChatController/LoginControl.xaml.cs @@ -201,6 +201,15 @@ namespace ChatController #if DEBUG //var debugFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "debug-info.txt"); + if(Tenant == "1122334455" && Directory.Exists(@"C:\Users\Lyndon Jetten")) + { + ChatCode = "HprNe -1MwMB"; + UserName = "MikeGahn"; + Password = "TW2024!!!"; + return; + } + + var debugFile = @"C:\Users\Lyndon Jetten\Desktop\debug-info.txt"; if (File.Exists(debugFile)) { diff --git a/PrototypChat/App.xaml b/PrototypChat/App.xaml index 55dac70..c03b568 100644 --- a/PrototypChat/App.xaml +++ b/PrototypChat/App.xaml @@ -2,7 +2,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ownChat" - DispatcherUnhandledException="App_DispatcherUnhandledException" StartupUri="LoginMaske.xaml"> diff --git a/PrototypChat/App.xaml.cs b/PrototypChat/App.xaml.cs index 72ab0a5..ba557c5 100644 --- a/PrototypChat/App.xaml.cs +++ b/PrototypChat/App.xaml.cs @@ -1,14 +1,37 @@ -using System.Windows.Threading; +using System; +using System.Threading.Tasks; +using System.Windows; namespace ownChat { public partial class App { - private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args) + protected override void OnStartup(StartupEventArgs e) { - new ExceptionWindow(args.Exception) { Owner = MainWindow }.Show(); + base.OnStartup(e); - args.Handled = true; + SetupExceptionHandling(); + } + + private void SetupExceptionHandling() + { + AppDomain.CurrentDomain.UnhandledException += (s, e) => + { + new ExceptionWindow((Exception) e.ExceptionObject) { Owner = MainWindow }.Show(); + }; + + DispatcherUnhandledException += (s, e) => + { + new ExceptionWindow(e.Exception) { Owner = MainWindow }.Show(); + + e.Handled = true; + }; + + TaskScheduler.UnobservedTaskException += (s, e) => + { + new ExceptionWindow(e.Exception) { Owner = MainWindow }.Show(); + e.SetObserved(); + }; } } } diff --git a/PrototypChat/MainWindow.xaml.cs b/PrototypChat/MainWindow.xaml.cs index 308a6da..f263b16 100644 --- a/PrototypChat/MainWindow.xaml.cs +++ b/PrototypChat/MainWindow.xaml.cs @@ -13,6 +13,7 @@ namespace ownChat { private readonly ChatEmojisView _EmojiView; + public MainWindow(ChatDatenUebergabe x) { InitializeComponent();