fix(tls): enable TLS 1.2/1.3 on AddIn startup — fix SecureChannelFailure

Symptom: "Could not create SSL/TLS secure channel" on every CRM request
(GlobalSearch, MatchingService, TestConnection). TCP and DNS succeed
fine — the failure is at the schannel handshake stage.

Root cause: .NET Framework 4.8 inherits ServicePointManager.SecurityProtocol
from the host process. In Outlook 2019/M365 that ends up as SSL3/Tls1
which modern HTTPS servers reject.

Fix: in AddInHost ctor, OR Tls12 + Tls13 into SecurityProtocol before
any HttpClient is created. Tls13 (value 12288) is wrapped in try/catch
for pre-Win10-1809 systems.

Also surface WebExceptionStatus values in the Settings "Test connection"
dialog (SecureChannelFailure / TrustFailure / NameResolutionFailure /
ConnectFailure / Timeout) so future schannel issues report a clear
Hebrew explanation instead of "One or more errors occurred".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
PointStar
2026-05-11 16:15:42 +03:00
parent 40c3839278
commit 661e0cb598
2 changed files with 41 additions and 0 deletions
@@ -161,6 +161,22 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
current = current.InnerException;
}
if (current is System.Net.WebException web)
{
switch (web.Status)
{
case System.Net.WebExceptionStatus.SecureChannelFailure:
return "כשל TLS — לא הצלחתי ליצור ערוץ מאובטח. ייתכן שהשרת דורש TLS 1.2/1.3 שאינו מופעל ב-.NET Framework. נסה לסגור ולפתוח Outlook מחדש; אם הבעיה חוזרת, פנה לאדמין.";
case System.Net.WebExceptionStatus.TrustFailure:
return "אישור ה-TLS של השרת לא נסמך. ייתכן שצריך להתקין את ה-CA של השרת ב-Trusted Root.";
case System.Net.WebExceptionStatus.NameResolutionFailure:
return $"השרת {target.Host} לא נמצא ב-DNS. ודא שהכתובת נכונה.";
case System.Net.WebExceptionStatus.ConnectFailure:
return $"החיבור ל-{target.Host}:{target.Port} נכשל. ודא שהשרת רץ ושאין חסימה ברשת.";
case System.Net.WebExceptionStatus.Timeout:
return "החיבור פג זמן. השרת אולי לא מגיב.";
}
}
if (current is System.Net.Sockets.SocketException sock)
{
switch (sock.SocketErrorCode)
+25
View File
@@ -52,6 +52,14 @@ namespace OutlookAddin.Services
public AddInHost(Outlook.Application outlookApp)
{
_outlookApp = outlookApp ?? throw new ArgumentNullException(nameof(outlookApp));
// .NET Framework 4.8 defaults to SystemDefault for TLS negotiation,
// which in Outlook's host process can end up as SSL3/TLS1.0 and trip
// "Could not create SSL/TLS secure channel" on modern EspoCRM servers.
// Force TLS 1.2 (always present on Win10+) and try TLS 1.3 (Win10
// 1809+ only — wrap in try/catch for older Windows).
EnableModernTls();
Logger = LoggerFactory.Init();
Logger.Information("AddInHost starting up");
@@ -70,6 +78,23 @@ namespace OutlookAddin.Services
HookItemSend();
}
private static void EnableModernTls()
{
try
{
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
}
catch (NotSupportedException) { /* extremely old Windows — ignore */ }
try
{
// Tls13 enum is present in .NET Framework 4.8, but the OS schannel
// only honours it on Windows 10 1809+ / Server 2022+.
System.Net.ServicePointManager.SecurityProtocol |= (System.Net.SecurityProtocolType)12288;
}
catch (NotSupportedException) { /* older Windows — TLS 1.2 only is fine */ }
}
private void InitializeSentItemsWatcher()
{
try