summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2014-08-27 14:16:15 (GMT)
committerKevin Smith <kevin.smith@isode.com>2015-06-10 20:29:05 (GMT)
commitb2093a372874aefb4f56f66a70a96f78d6cbbaec (patch)
treeab779a4cc7950339d2c2cb0261ae6a08df84c645 /Swift
parentb6b0695643f932827add43b9de0e09ed74eb6799 (diff)
downloadswift-b2093a372874aefb4f56f66a70a96f78d6cbbaec.zip
swift-b2093a372874aefb4f56f66a70a96f78d6cbbaec.tar.bz2
Add ability to limit SChannel to TLS 1.0
Some servers have very restrictive TLS stacks that respond badly to a bug in the SChannel TLS implementation, meaning that TLS has to be limited to 1.0. Add ClientOptions.tlsOptions. This is a method of passing options into the TLS stack. It's currently only used for the TLS 1.0 workaround in SChannel, but we might reasonably expose other options in the future, such as limiting cypher suites. Disables use of SSLv3 for SChannel Also updates the coding style in SchannelContext a bit. Test-Information: Compiles on both OS X and Windows(SChannel). OS X doesn't show the new option. Windows shows it, and remembers it between logins. Not tested against a server requiring 1.0 only, but a previous hack with the same approach was tested. Change-Id: I1e7854d43811fd173f21f98d4dc3915fc7a4b322
Diffstat (limited to 'Swift')
-rw-r--r--Swift/Controllers/MainController.cpp8
-rw-r--r--Swift/QtUI/QtConnectionSettings.ui7
-rw-r--r--Swift/QtUI/QtConnectionSettingsWindow.cpp8
3 files changed, 19 insertions, 4 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 328d837..c6b6dfc 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -398,7 +398,7 @@ void MainController::handleConnected() {
398 userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle()); 398 userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle());
399 userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle()); 399 userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle());
400 adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow()); 400 adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow());
401 401
402 chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1)); 402 chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1));
403 } 403 }
404 loginWindow_->setIsLoggingIn(false); 404 loginWindow_->setIsLoggingIn(false);
@@ -410,7 +410,7 @@ void MainController::handleConnected() {
410 discoInfoRequest->send(); 410 discoInfoRequest->send();
411 411
412 client_->getVCardManager()->requestOwnVCard(); 412 client_->getVCardManager()->requestOwnVCard();
413 413
414 rosterController_->setJID(boundJID_); 414 rosterController_->setJID(boundJID_);
415 rosterController_->setEnabled(true); 415 rosterController_->setEnabled(true);
416 rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted()); 416 rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted());
@@ -841,10 +841,11 @@ std::string MainController::serializeClientOptions(const ClientOptions& options)
841 SERIALIZE_URL(boshHTTPConnectProxyURL); 841 SERIALIZE_URL(boshHTTPConnectProxyURL);
842 SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID); 842 SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID);
843 SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); 843 SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
844 SERIALIZE_BOOL(tlsOptions.schannelTLS1_0Workaround);
844 return result; 845 return result;
845} 846}
846 847
847#define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;} 848#define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;}
848#define PARSE_INT_RAW(defaultValue) CHECK_PARSE_LENGTH intVal = defaultValue; try {intVal = boost::lexical_cast<int>(segments[i]);} catch(const boost::bad_lexical_cast&) {};i++; 849#define PARSE_INT_RAW(defaultValue) CHECK_PARSE_LENGTH intVal = defaultValue; try {intVal = boost::lexical_cast<int>(segments[i]);} catch(const boost::bad_lexical_cast&) {};i++;
849#define PARSE_STRING_RAW CHECK_PARSE_LENGTH stringVal = byteArrayToString(Base64::decode(segments[i]));i++; 850#define PARSE_STRING_RAW CHECK_PARSE_LENGTH stringVal = byteArrayToString(Base64::decode(segments[i]));i++;
850 851
@@ -888,6 +889,7 @@ ClientOptions MainController::parseClientOptions(const std::string& optionString
888 PARSE_URL(boshHTTPConnectProxyURL); 889 PARSE_URL(boshHTTPConnectProxyURL);
889 PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID); 890 PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID);
890 PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); 891 PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
892 PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false);
891 893
892 return result; 894 return result;
893} 895}
diff --git a/Swift/QtUI/QtConnectionSettings.ui b/Swift/QtUI/QtConnectionSettings.ui
index 2dc46d1..cce60fe 100644
--- a/Swift/QtUI/QtConnectionSettings.ui
+++ b/Swift/QtUI/QtConnectionSettings.ui
@@ -136,6 +136,13 @@
136 </widget> 136 </widget>
137 </item> 137 </item>
138 <item> 138 <item>
139 <widget class="QCheckBox" name="manual_forceTLS1_0">
140 <property name="text">
141 <string>Limit encryption to TLS 1.0</string>
142 </property>
143 </widget>
144 </item>
145 <item>
139 <spacer name="verticalSpacer_2"> 146 <spacer name="verticalSpacer_2">
140 <property name="orientation"> 147 <property name="orientation">
141 <enum>Qt::Vertical</enum> 148 <enum>Qt::Vertical</enum>
diff --git a/Swift/QtUI/QtConnectionSettingsWindow.cpp b/Swift/QtUI/QtConnectionSettingsWindow.cpp
index a3598fa..7b5003a 100644
--- a/Swift/QtUI/QtConnectionSettingsWindow.cpp
+++ b/Swift/QtUI/QtConnectionSettingsWindow.cpp
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012 Isode Limited. 2 * Copyright (c) 2012-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
@@ -67,6 +67,7 @@ QtConnectionSettingsWindow::QtConnectionSettingsWindow(const ClientOptions& opti
67 isDefault &= options.proxyType == defaults.proxyType; 67 isDefault &= options.proxyType == defaults.proxyType;
68 isDefault &= options.manualProxyHostname == defaults.manualProxyHostname; 68 isDefault &= options.manualProxyHostname == defaults.manualProxyHostname;
69 isDefault &= options.manualProxyPort == defaults.manualProxyPort; 69 isDefault &= options.manualProxyPort == defaults.manualProxyPort;
70 isDefault &= options.tlsOptions.schannelTLS1_0Workaround == defaults.tlsOptions.schannelTLS1_0Workaround;
70 if (isDefault) { 71 if (isDefault) {
71 ui.connectionMethod->setCurrentIndex(0); 72 ui.connectionMethod->setCurrentIndex(0);
72 } 73 }
@@ -88,6 +89,7 @@ QtConnectionSettingsWindow::QtConnectionSettingsWindow(const ClientOptions& opti
88 ui.manual_manualProxyHost->setText(P2QSTRING(options.manualProxyHostname)); 89 ui.manual_manualProxyHost->setText(P2QSTRING(options.manualProxyHostname));
89 ui.manual_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualProxyPort))); 90 ui.manual_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualProxyPort)));
90 } 91 }
92 ui.manual_forceTLS1_0->setChecked(options.tlsOptions.schannelTLS1_0Workaround);
91 } 93 }
92 } else { 94 } else {
93 ui.connectionMethod->setCurrentIndex(2); 95 ui.connectionMethod->setCurrentIndex(2);
@@ -100,6 +102,9 @@ QtConnectionSettingsWindow::QtConnectionSettingsWindow(const ClientOptions& opti
100 } 102 }
101 } 103 }
102 } 104 }
105#ifndef HAVE_SCHANNEL
106 ui.manual_forceTLS1_0->hide();
107#endif
103} 108}
104 109
105void QtConnectionSettingsWindow::handleProxyTypeChanged(int index) { 110void QtConnectionSettingsWindow::handleProxyTypeChanged(int index) {
@@ -129,6 +134,7 @@ ClientOptions QtConnectionSettingsWindow::getOptions() {
129 options.useTLS = static_cast<ClientOptions::UseTLS>(ui.manual_useTLS->currentIndex()); 134 options.useTLS = static_cast<ClientOptions::UseTLS>(ui.manual_useTLS->currentIndex());
130 options.useStreamCompression = ui.manual_allowCompression->isChecked(); 135 options.useStreamCompression = ui.manual_allowCompression->isChecked();
131 options.allowPLAINWithoutTLS = ui.manual_allowPLAINWithoutTLS->isChecked(); 136 options.allowPLAINWithoutTLS = ui.manual_allowPLAINWithoutTLS->isChecked();
137 options.tlsOptions.schannelTLS1_0Workaround = ui.manual_forceTLS1_0->isChecked();
132 if (ui.manual_manualHost->isChecked()) { 138 if (ui.manual_manualHost->isChecked()) {
133 options.manualHostname = Q2PSTRING(ui.manual_manualHostName->text()); 139 options.manualHostname = Q2PSTRING(ui.manual_manualHostName->text());
134 try { 140 try {