diff options
27 files changed, 248 insertions, 162 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 | ||
| 105 | void QtConnectionSettingsWindow::handleProxyTypeChanged(int index) { | 110 | void 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 { |
diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h index 4aac609..25393e4 100644 --- a/Swiften/Client/ClientOptions.h +++ b/Swiften/Client/ClientOptions.h | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #include <Swiften/Base/API.h> | 11 | #include <Swiften/Base/API.h> |
| 12 | #include <Swiften/Base/URL.h> | 12 | #include <Swiften/Base/URL.h> |
| 13 | #include <Swiften/Base/SafeString.h> | 13 | #include <Swiften/Base/SafeString.h> |
| 14 | #include <Swiften/TLS/TLSOptions.h> | ||
| 15 | |||
| 14 | 16 | ||
| 15 | namespace Swift { | 17 | namespace Swift { |
| 16 | class HTTPTrafficFilter; | 18 | class HTTPTrafficFilter; |
| @@ -145,5 +147,10 @@ namespace Swift { | |||
| 145 | * proxy initialization to be customized. | 147 | * proxy initialization to be customized. |
| 146 | */ | 148 | */ |
| 147 | boost::shared_ptr<HTTPTrafficFilter> httpTrafficFilter; | 149 | boost::shared_ptr<HTTPTrafficFilter> httpTrafficFilter; |
| 150 | |||
| 151 | /** | ||
| 152 | * Options passed to the TLS stack | ||
| 153 | */ | ||
| 154 | TLSOptions tlsOptions; | ||
| 148 | }; | 155 | }; |
| 149 | } | 156 | } |
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index 842488d..c91e5c5 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp | |||
| @@ -138,7 +138,8 @@ void CoreClient::connect(const ClientOptions& o) { | |||
| 138 | host, | 138 | host, |
| 139 | options.boshHTTPConnectProxyURL, | 139 | options.boshHTTPConnectProxyURL, |
| 140 | options.boshHTTPConnectProxyAuthID, | 140 | options.boshHTTPConnectProxyAuthID, |
| 141 | options.boshHTTPConnectProxyAuthPassword)); | 141 | options.boshHTTPConnectProxyAuthPassword, |
| 142 | options.tlsOptions)); | ||
| 142 | sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1)); | 143 | sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1)); |
| 143 | sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1)); | 144 | sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1)); |
| 144 | bindSessionToStream(); | 145 | bindSessionToStream(); |
| @@ -189,7 +190,7 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio | |||
| 189 | connection_ = connection; | 190 | connection_ = connection; |
| 190 | 191 | ||
| 191 | assert(!sessionStream_); | 192 | assert(!sessionStream_); |
| 192 | sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory()); | 193 | sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), options.tlsOptions); |
| 193 | if (certificate_ && !certificate_->isNull()) { | 194 | if (certificate_ && !certificate_->isNull()) { |
| 194 | sessionStream_->setTLSCertificate(certificate_); | 195 | sessionStream_->setTLSCertificate(certificate_); |
| 195 | } | 196 | } |
diff --git a/Swiften/Component/CoreComponent.cpp b/Swiften/Component/CoreComponent.cpp index 23b7759..358b0c6 100644 --- a/Swiften/Component/CoreComponent.cpp +++ b/Swiften/Component/CoreComponent.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2013 Isode Limited. | 2 | * Copyright (c) 2010-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 | */ |
| @@ -9,14 +9,16 @@ | |||
| 9 | #include <boost/bind.hpp> | 9 | #include <boost/bind.hpp> |
| 10 | #include <iostream> | 10 | #include <iostream> |
| 11 | 11 | ||
| 12 | #include <Swiften/Base/IDGenerator.h> | ||
| 12 | #include <Swiften/Component/ComponentSession.h> | 13 | #include <Swiften/Component/ComponentSession.h> |
| 14 | #include <Swiften/Component/ComponentSessionStanzaChannel.h> | ||
| 13 | #include <Swiften/Network/Connector.h> | 15 | #include <Swiften/Network/Connector.h> |
| 14 | #include <Swiften/Network/NetworkFactories.h> | 16 | #include <Swiften/Network/NetworkFactories.h> |
| 15 | #include <Swiften/TLS/PKCS12Certificate.h> | ||
| 16 | #include <Swiften/Session/BasicSessionStream.h> | ||
| 17 | #include <Swiften/Queries/IQRouter.h> | 17 | #include <Swiften/Queries/IQRouter.h> |
| 18 | #include <Swiften/Base/IDGenerator.h> | 18 | #include <Swiften/Session/BasicSessionStream.h> |
| 19 | #include <Swiften/Component/ComponentSessionStanzaChannel.h> | 19 | #include <Swiften/TLS/PKCS12Certificate.h> |
| 20 | #include <Swiften/TLS/TLSOptions.h> | ||
| 21 | |||
| 20 | 22 | ||
| 21 | namespace Swift { | 23 | namespace Swift { |
| 22 | 24 | ||
| @@ -63,7 +65,7 @@ void CoreComponent::handleConnectorFinished(boost::shared_ptr<Connection> connec | |||
| 63 | connection_ = connection; | 65 | connection_ = connection; |
| 64 | 66 | ||
| 65 | assert(!sessionStream_); | 67 | assert(!sessionStream_); |
| 66 | sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ComponentStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), NULL, networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory())); | 68 | sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ComponentStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), NULL, networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), TLSOptions())); |
| 67 | sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1)); | 69 | sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1)); |
| 68 | sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); | 70 | sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); |
| 69 | 71 | ||
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp index 56f7d12..c037b34 100644 --- a/Swiften/Network/BOSHConnectionPool.cpp +++ b/Swiften/Network/BOSHConnectionPool.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2011 Isode Limited. | 2 | * Copyright (c) 2011-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 | */ |
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <Swiften/Network/CachingDomainNameResolver.h> | 17 | #include <Swiften/Network/CachingDomainNameResolver.h> |
| 18 | 18 | ||
| 19 | namespace Swift { | 19 | namespace Swift { |
| 20 | BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* realResolver, ConnectionFactory* connectionFactoryParameter, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword) : | 20 | BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* realResolver, ConnectionFactory* connectionFactoryParameter, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword, const TLSOptions& tlsOptions) : |
| 21 | boshURL(boshURL), | 21 | boshURL(boshURL), |
| 22 | connectionFactory(connectionFactoryParameter), | 22 | connectionFactory(connectionFactoryParameter), |
| 23 | xmlParserFactory(parserFactory), | 23 | xmlParserFactory(parserFactory), |
| @@ -31,13 +31,13 @@ BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* r | |||
| 31 | 31 | ||
| 32 | if (!boshHTTPConnectProxyURL.isEmpty()) { | 32 | if (!boshHTTPConnectProxyURL.isEmpty()) { |
| 33 | if (boshHTTPConnectProxyURL.getScheme() == "https") { | 33 | if (boshHTTPConnectProxyURL.getScheme() == "https") { |
| 34 | connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory); | 34 | connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory, tlsOptions); |
| 35 | myConnectionFactories.push_back(connectionFactory); | 35 | myConnectionFactories.push_back(connectionFactory); |
| 36 | } | 36 | } |
| 37 | connectionFactory = new HTTPConnectProxiedConnectionFactory(realResolver, connectionFactory, timerFactory, boshHTTPConnectProxyURL.getHost(), URL::getPortOrDefaultPort(boshHTTPConnectProxyURL), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword); | 37 | connectionFactory = new HTTPConnectProxiedConnectionFactory(realResolver, connectionFactory, timerFactory, boshHTTPConnectProxyURL.getHost(), URL::getPortOrDefaultPort(boshHTTPConnectProxyURL), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword); |
| 38 | } | 38 | } |
| 39 | if (boshURL.getScheme() == "https") { | 39 | if (boshURL.getScheme() == "https") { |
| 40 | connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory); | 40 | connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory, tlsOptions); |
| 41 | myConnectionFactories.push_back(connectionFactory); | 41 | myConnectionFactories.push_back(connectionFactory); |
| 42 | } | 42 | } |
| 43 | resolver = new CachingDomainNameResolver(realResolver, eventLoop); | 43 | resolver = new CachingDomainNameResolver(realResolver, eventLoop); |
diff --git a/Swiften/Network/BOSHConnectionPool.h b/Swiften/Network/BOSHConnectionPool.h index 570ba4b..d845a3d 100644 --- a/Swiften/Network/BOSHConnectionPool.h +++ b/Swiften/Network/BOSHConnectionPool.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2011 Isode Limited. | 2 | * Copyright (c) 2011-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 | */ |
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <Swiften/Base/API.h> | 12 | #include <Swiften/Base/API.h> |
| 13 | #include <Swiften/Base/SafeString.h> | 13 | #include <Swiften/Base/SafeString.h> |
| 14 | #include <Swiften/Network/BOSHConnection.h> | 14 | #include <Swiften/Network/BOSHConnection.h> |
| 15 | #include <Swiften/TLS/TLSOptions.h> | ||
| 16 | |||
| 15 | 17 | ||
| 16 | namespace Swift { | 18 | namespace Swift { |
| 17 | class HTTPConnectProxiedConnectionFactory; | 19 | class HTTPConnectProxiedConnectionFactory; |
| @@ -21,7 +23,7 @@ namespace Swift { | |||
| 21 | 23 | ||
| 22 | class SWIFTEN_API BOSHConnectionPool : public boost::bsignals::trackable { | 24 | class SWIFTEN_API BOSHConnectionPool : public boost::bsignals::trackable { |
| 23 | public: | 25 | public: |
| 24 | BOSHConnectionPool(const URL& boshURL, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword); | 26 | BOSHConnectionPool(const URL& boshURL, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword, const TLSOptions& tlsOptions); |
| 25 | ~BOSHConnectionPool(); | 27 | ~BOSHConnectionPool(); |
| 26 | void write(const SafeByteArray& data); | 28 | void write(const SafeByteArray& data); |
| 27 | void writeFooter(); | 29 | void writeFooter(); |
diff --git a/Swiften/Network/TLSConnection.cpp b/Swiften/Network/TLSConnection.cpp index f0b6fa4..149548a 100644 --- a/Swiften/Network/TLSConnection.cpp +++ b/Swiften/Network/TLSConnection.cpp | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | 14 | ||
| 15 | namespace Swift { | 15 | namespace Swift { |
| 16 | 16 | ||
| 17 | TLSConnection::TLSConnection(Connection::ref connection, TLSContextFactory* tlsFactory) : connection(connection) { | 17 | TLSConnection::TLSConnection(Connection::ref connection, TLSContextFactory* tlsFactory, const TLSOptions& tlsOptions) : connection(connection) { |
| 18 | context = tlsFactory->createTLSContext(); | 18 | context = tlsFactory->createTLSContext(tlsOptions); |
| 19 | context->onDataForNetwork.connect(boost::bind(&TLSConnection::handleTLSDataForNetwork, this, _1)); | 19 | context->onDataForNetwork.connect(boost::bind(&TLSConnection::handleTLSDataForNetwork, this, _1)); |
| 20 | context->onDataForApplication.connect(boost::bind(&TLSConnection::handleTLSDataForApplication, this, _1)); | 20 | context->onDataForApplication.connect(boost::bind(&TLSConnection::handleTLSDataForApplication, this, _1)); |
| 21 | context->onConnected.connect(boost::bind(&TLSConnection::handleTLSConnectFinished, this, false)); | 21 | context->onConnected.connect(boost::bind(&TLSConnection::handleTLSConnectFinished, this, false)); |
diff --git a/Swiften/Network/TLSConnection.h b/Swiften/Network/TLSConnection.h index ebf2e43..96525ad 100644 --- a/Swiften/Network/TLSConnection.h +++ b/Swiften/Network/TLSConnection.h | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | #include <Swiften/Base/API.h> | 13 | #include <Swiften/Base/API.h> |
| 14 | #include <Swiften/Base/SafeByteArray.h> | 14 | #include <Swiften/Base/SafeByteArray.h> |
| 15 | #include <Swiften/Network/Connection.h> | 15 | #include <Swiften/Network/Connection.h> |
| 16 | #include <Swiften/TLS/TLSOptions.h> | ||
| 17 | |||
| 16 | 18 | ||
| 17 | namespace Swift { | 19 | namespace Swift { |
| 18 | class HostAddressPort; | 20 | class HostAddressPort; |
| @@ -22,7 +24,7 @@ namespace Swift { | |||
| 22 | class SWIFTEN_API TLSConnection : public Connection { | 24 | class SWIFTEN_API TLSConnection : public Connection { |
| 23 | public: | 25 | public: |
| 24 | 26 | ||
| 25 | TLSConnection(Connection::ref connection, TLSContextFactory* tlsFactory); | 27 | TLSConnection(Connection::ref connection, TLSContextFactory* tlsFactory, const TLSOptions&); |
| 26 | virtual ~TLSConnection(); | 28 | virtual ~TLSConnection(); |
| 27 | 29 | ||
| 28 | virtual void listen() {assert(false);} | 30 | virtual void listen() {assert(false);} |
diff --git a/Swiften/Network/TLSConnectionFactory.cpp b/Swiften/Network/TLSConnectionFactory.cpp index ac0ab8e..cc20b2d 100644 --- a/Swiften/Network/TLSConnectionFactory.cpp +++ b/Swiften/Network/TLSConnectionFactory.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Swift { | 13 | namespace Swift { |
| 14 | 14 | ||
| 15 | TLSConnectionFactory::TLSConnectionFactory(TLSContextFactory* contextFactory, ConnectionFactory* connectionFactory) : contextFactory(contextFactory), connectionFactory(connectionFactory){ | 15 | TLSConnectionFactory::TLSConnectionFactory(TLSContextFactory* contextFactory, ConnectionFactory* connectionFactory, const TLSOptions& o) : contextFactory(contextFactory), connectionFactory(connectionFactory), options_(o) { |
| 16 | 16 | ||
| 17 | } | 17 | } |
| 18 | 18 | ||
| @@ -22,7 +22,7 @@ TLSConnectionFactory::~TLSConnectionFactory() { | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | boost::shared_ptr<Connection> TLSConnectionFactory::createConnection() { | 24 | boost::shared_ptr<Connection> TLSConnectionFactory::createConnection() { |
| 25 | return boost::make_shared<TLSConnection>(connectionFactory->createConnection(), contextFactory); | 25 | return boost::make_shared<TLSConnection>(connectionFactory->createConnection(), contextFactory, options_); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | } | 28 | } |
diff --git a/Swiften/Network/TLSConnectionFactory.h b/Swiften/Network/TLSConnectionFactory.h index 3dfee06..0c67014 100644 --- a/Swiften/Network/TLSConnectionFactory.h +++ b/Swiften/Network/TLSConnectionFactory.h | |||
| @@ -11,18 +11,20 @@ | |||
| 11 | #include <Swiften/Base/API.h> | 11 | #include <Swiften/Base/API.h> |
| 12 | #include <Swiften/Network/ConnectionFactory.h> | 12 | #include <Swiften/Network/ConnectionFactory.h> |
| 13 | #include <Swiften/TLS/TLSContextFactory.h> | 13 | #include <Swiften/TLS/TLSContextFactory.h> |
| 14 | #include <Swiften/TLS/TLSOptions.h> | ||
| 14 | 15 | ||
| 15 | namespace Swift { | 16 | namespace Swift { |
| 16 | class Connection; | 17 | class Connection; |
| 17 | 18 | ||
| 18 | class SWIFTEN_API TLSConnectionFactory : public ConnectionFactory { | 19 | class SWIFTEN_API TLSConnectionFactory : public ConnectionFactory { |
| 19 | public: | 20 | public: |
| 20 | TLSConnectionFactory(TLSContextFactory* contextFactory, ConnectionFactory* connectionFactory); | 21 | TLSConnectionFactory(TLSContextFactory* contextFactory, ConnectionFactory* connectionFactory, const TLSOptions&); |
| 21 | virtual ~TLSConnectionFactory(); | 22 | virtual ~TLSConnectionFactory(); |
| 22 | 23 | ||
| 23 | virtual boost::shared_ptr<Connection> createConnection(); | 24 | virtual boost::shared_ptr<Connection> createConnection(); |
| 24 | private: | 25 | private: |
| 25 | TLSContextFactory* contextFactory; | 26 | TLSContextFactory* contextFactory; |
| 26 | ConnectionFactory* connectionFactory; | 27 | ConnectionFactory* connectionFactory; |
| 28 | TLSOptions options_; | ||
| 27 | }; | 29 | }; |
| 28 | } | 30 | } |
diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp index e5ac121..e687517 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp | |||
| @@ -16,15 +16,16 @@ | |||
| 16 | #include <boost/lexical_cast.hpp> | 16 | #include <boost/lexical_cast.hpp> |
| 17 | 17 | ||
| 18 | #include <Swiften/Base/Algorithm.h> | 18 | #include <Swiften/Base/Algorithm.h> |
| 19 | #include <Swiften/Network/Connection.h> | 19 | #include <Swiften/EventLoop/DummyEventLoop.h> |
| 20 | #include <Swiften/Network/ConnectionFactory.h> | ||
| 21 | #include <Swiften/Network/BOSHConnection.h> | 20 | #include <Swiften/Network/BOSHConnection.h> |
| 22 | #include <Swiften/Network/BOSHConnectionPool.h> | 21 | #include <Swiften/Network/BOSHConnectionPool.h> |
| 22 | #include <Swiften/Network/Connection.h> | ||
| 23 | #include <Swiften/Network/ConnectionFactory.h> | ||
| 24 | #include <Swiften/Network/DummyTimerFactory.h> | ||
| 23 | #include <Swiften/Network/HostAddressPort.h> | 25 | #include <Swiften/Network/HostAddressPort.h> |
| 24 | #include <Swiften/Network/StaticDomainNameResolver.h> | 26 | #include <Swiften/Network/StaticDomainNameResolver.h> |
| 25 | #include <Swiften/Network/DummyTimerFactory.h> | ||
| 26 | #include <Swiften/EventLoop/DummyEventLoop.h> | ||
| 27 | #include <Swiften/Parser/PlatformXMLParserFactory.h> | 27 | #include <Swiften/Parser/PlatformXMLParserFactory.h> |
| 28 | #include <Swiften/TLS/TLSOptions.h> | ||
| 28 | 29 | ||
| 29 | 30 | ||
| 30 | 31 | ||
| @@ -322,7 +323,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { | |||
| 322 | private: | 323 | private: |
| 323 | 324 | ||
| 324 | PoolRef createTestling() { | 325 | PoolRef createTestling() { |
| 325 | BOSHConnectionPool* a = new BOSHConnectionPool(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString("")); | 326 | BOSHConnectionPool* a = new BOSHConnectionPool(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString(""), TLSOptions()); |
| 326 | PoolRef pool(a); | 327 | PoolRef pool(a); |
| 327 | //FIXME: Remko - why does the above work, but the below fail? | 328 | //FIXME: Remko - why does the above work, but the below fail? |
| 328 | //PoolRef pool = boost::make_shared<BOSHConnectionPool>(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString("")); | 329 | //PoolRef pool = boost::make_shared<BOSHConnectionPool>(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString("")); |
diff --git a/Swiften/Session/BOSHSessionStream.cpp b/Swiften/Session/BOSHSessionStream.cpp index eac493e..62942b9 100644 --- a/Swiften/Session/BOSHSessionStream.cpp +++ b/Swiften/Session/BOSHSessionStream.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2011-2014 Isode Limited. | 2 | * Copyright (c) 2011-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 | */ |
| @@ -39,7 +39,8 @@ BOSHSessionStream::BOSHSessionStream( | |||
| 39 | const std::string& to, | 39 | const std::string& to, |
| 40 | const URL& boshHTTPConnectProxyURL, | 40 | const URL& boshHTTPConnectProxyURL, |
| 41 | const SafeString& boshHTTPConnectProxyAuthID, | 41 | const SafeString& boshHTTPConnectProxyAuthID, |
| 42 | const SafeString& boshHTTPConnectProxyAuthPassword) : | 42 | const SafeString& boshHTTPConnectProxyAuthPassword, |
| 43 | const TLSOptions& tlsOptions) : | ||
| 43 | available(false), | 44 | available(false), |
| 44 | eventLoop(eventLoop), | 45 | eventLoop(eventLoop), |
| 45 | firstHeader(true) { | 46 | firstHeader(true) { |
| @@ -49,7 +50,7 @@ BOSHSessionStream::BOSHSessionStream( | |||
| 49 | random.seed(static_cast<unsigned int>(time(NULL))); | 50 | random.seed(static_cast<unsigned int>(time(NULL))); |
| 50 | unsigned long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned long long> >(random, dist)(); | 51 | unsigned long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned long long> >(random, dist)(); |
| 51 | 52 | ||
| 52 | connectionPool = new BOSHConnectionPool(boshURL, resolver, connectionFactory, xmlParserFactory, tlsContextFactory, timerFactory, eventLoop, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword); | 53 | connectionPool = new BOSHConnectionPool(boshURL, resolver, connectionFactory, xmlParserFactory, tlsContextFactory, timerFactory, eventLoop, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword, tlsOptions); |
| 53 | connectionPool->onSessionTerminated.connect(boost::bind(&BOSHSessionStream::handlePoolSessionTerminated, this, _1)); | 54 | connectionPool->onSessionTerminated.connect(boost::bind(&BOSHSessionStream::handlePoolSessionTerminated, this, _1)); |
| 54 | connectionPool->onSessionStarted.connect(boost::bind(&BOSHSessionStream::handlePoolSessionStarted, this)); | 55 | connectionPool->onSessionStarted.connect(boost::bind(&BOSHSessionStream::handlePoolSessionStarted, this)); |
| 55 | connectionPool->onXMPPDataRead.connect(boost::bind(&BOSHSessionStream::handlePoolXMPPDataRead, this, _1)); | 56 | connectionPool->onXMPPDataRead.connect(boost::bind(&BOSHSessionStream::handlePoolXMPPDataRead, this, _1)); |
diff --git a/Swiften/Session/BOSHSessionStream.h b/Swiften/Session/BOSHSessionStream.h index e97436c..436b941 100644 --- a/Swiften/Session/BOSHSessionStream.h +++ b/Swiften/Session/BOSHSessionStream.h | |||
| @@ -9,12 +9,14 @@ | |||
| 9 | #include <boost/shared_ptr.hpp> | 9 | #include <boost/shared_ptr.hpp> |
| 10 | 10 | ||
| 11 | #include <Swiften/Base/API.h> | 11 | #include <Swiften/Base/API.h> |
| 12 | #include <Swiften/Base/SafeString.h> | ||
| 13 | #include <Swiften/Base/SafeByteArray.h> | 12 | #include <Swiften/Base/SafeByteArray.h> |
| 14 | #include <Swiften/Network/BOSHConnectionPool.h> | 13 | #include <Swiften/Base/SafeString.h> |
| 15 | #include <Swiften/Session/SessionStream.h> | ||
| 16 | #include <Swiften/Elements/StreamType.h> | 14 | #include <Swiften/Elements/StreamType.h> |
| 17 | #include <Swiften/EventLoop/EventOwner.h> | 15 | #include <Swiften/EventLoop/EventOwner.h> |
| 16 | #include <Swiften/Network/BOSHConnectionPool.h> | ||
| 17 | #include <Swiften/Session/SessionStream.h> | ||
| 18 | #include <Swiften/TLS/TLSOptions.h> | ||
| 19 | |||
| 18 | 20 | ||
| 19 | namespace Swift { | 21 | namespace Swift { |
| 20 | class TimerFactory; | 22 | class TimerFactory; |
| @@ -43,7 +45,8 @@ namespace Swift { | |||
| 43 | const std::string& to, | 45 | const std::string& to, |
| 44 | const URL& boshHTTPConnectProxyURL, | 46 | const URL& boshHTTPConnectProxyURL, |
| 45 | const SafeString& boshHTTPConnectProxyAuthID, | 47 | const SafeString& boshHTTPConnectProxyAuthID, |
| 46 | const SafeString& boshHTTPConnectProxyAuthPassword | 48 | const SafeString& boshHTTPConnectProxyAuthPassword, |
| 49 | const TLSOptions& tlsOptions | ||
| 47 | ); | 50 | ); |
| 48 | ~BOSHSessionStream(); | 51 | ~BOSHSessionStream(); |
| 49 | 52 | ||
diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index 274d218..43f1c48 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2014 Isode Limited. | 2 | * Copyright (c) 2010-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 | */ |
| @@ -27,14 +27,16 @@ BasicSessionStream::BasicSessionStream( | |||
| 27 | PayloadSerializerCollection* payloadSerializers, | 27 | PayloadSerializerCollection* payloadSerializers, |
| 28 | TLSContextFactory* tlsContextFactory, | 28 | TLSContextFactory* tlsContextFactory, |
| 29 | TimerFactory* timerFactory, | 29 | TimerFactory* timerFactory, |
| 30 | XMLParserFactory* xmlParserFactory) : | 30 | XMLParserFactory* xmlParserFactory, |
| 31 | const TLSOptions& tlsOptions) : | ||
| 31 | available(false), | 32 | available(false), |
| 32 | connection(connection), | 33 | connection(connection), |
| 33 | tlsContextFactory(tlsContextFactory), | 34 | tlsContextFactory(tlsContextFactory), |
| 34 | timerFactory(timerFactory), | 35 | timerFactory(timerFactory), |
| 35 | compressionLayer(NULL), | 36 | compressionLayer(NULL), |
| 36 | tlsLayer(NULL), | 37 | tlsLayer(NULL), |
| 37 | whitespacePingLayer(NULL) { | 38 | whitespacePingLayer(NULL), |
| 39 | tlsOptions_(tlsOptions) { | ||
| 38 | xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, xmlParserFactory, streamType); | 40 | xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, xmlParserFactory, streamType); |
| 39 | xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); | 41 | xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); |
| 40 | xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); | 42 | xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); |
| @@ -106,7 +108,7 @@ bool BasicSessionStream::supportsTLSEncryption() { | |||
| 106 | 108 | ||
| 107 | void BasicSessionStream::addTLSEncryption() { | 109 | void BasicSessionStream::addTLSEncryption() { |
| 108 | assert(available); | 110 | assert(available); |
| 109 | tlsLayer = new TLSLayer(tlsContextFactory); | 111 | tlsLayer = new TLSLayer(tlsContextFactory, tlsOptions_); |
| 110 | if (hasTLSCertificate() && !tlsLayer->setClientCertificate(getTLSCertificate())) { | 112 | if (hasTLSCertificate() && !tlsLayer->setClientCertificate(getTLSCertificate())) { |
| 111 | onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::InvalidTLSCertificateError)); | 113 | onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::InvalidTLSCertificateError)); |
| 112 | } | 114 | } |
diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h index 7832e42..811374a 100644 --- a/Swiften/Session/BasicSessionStream.h +++ b/Swiften/Session/BasicSessionStream.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <Swiften/Session/SessionStream.h> | 14 | #include <Swiften/Session/SessionStream.h> |
| 15 | #include <Swiften/Elements/StreamType.h> | 15 | #include <Swiften/Elements/StreamType.h> |
| 16 | #include <Swiften/TLS/TLSError.h> | 16 | #include <Swiften/TLS/TLSError.h> |
| 17 | #include <Swiften/TLS/TLSOptions.h> | ||
| 17 | 18 | ||
| 18 | namespace Swift { | 19 | namespace Swift { |
| 19 | class TLSContextFactory; | 20 | class TLSContextFactory; |
| @@ -37,7 +38,8 @@ namespace Swift { | |||
| 37 | PayloadSerializerCollection* payloadSerializers, | 38 | PayloadSerializerCollection* payloadSerializers, |
| 38 | TLSContextFactory* tlsContextFactory, | 39 | TLSContextFactory* tlsContextFactory, |
| 39 | TimerFactory* whitespacePingLayerFactory, | 40 | TimerFactory* whitespacePingLayerFactory, |
| 40 | XMLParserFactory* xmlParserFactory | 41 | XMLParserFactory* xmlParserFactory, |
| 42 | const TLSOptions& tlsOptions | ||
| 41 | ); | 43 | ); |
| 42 | ~BasicSessionStream(); | 44 | ~BasicSessionStream(); |
| 43 | 45 | ||
| @@ -86,6 +88,7 @@ namespace Swift { | |||
| 86 | TLSLayer* tlsLayer; | 88 | TLSLayer* tlsLayer; |
| 87 | WhitespacePingLayer* whitespacePingLayer; | 89 | WhitespacePingLayer* whitespacePingLayer; |
| 88 | StreamStack* streamStack; | 90 | StreamStack* streamStack; |
| 91 | TLSOptions tlsOptions_; | ||
| 89 | }; | 92 | }; |
| 90 | 93 | ||
| 91 | } | 94 | } |
diff --git a/Swiften/StreamStack/TLSLayer.cpp b/Swiften/StreamStack/TLSLayer.cpp index aebf4a2..15c4101 100644 --- a/Swiften/StreamStack/TLSLayer.cpp +++ b/Swiften/StreamStack/TLSLayer.cpp | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | namespace Swift { | 14 | namespace Swift { |
| 15 | 15 | ||
| 16 | TLSLayer::TLSLayer(TLSContextFactory* factory) { | 16 | TLSLayer::TLSLayer(TLSContextFactory* factory, const TLSOptions& tlsOptions) { |
| 17 | context = factory->createTLSContext(); | 17 | context = factory->createTLSContext(tlsOptions); |
| 18 | context->onDataForNetwork.connect(boost::bind(&TLSLayer::writeDataToChildLayer, this, _1)); | 18 | context->onDataForNetwork.connect(boost::bind(&TLSLayer::writeDataToChildLayer, this, _1)); |
| 19 | context->onDataForApplication.connect(boost::bind(&TLSLayer::writeDataToParentLayer, this, _1)); | 19 | context->onDataForApplication.connect(boost::bind(&TLSLayer::writeDataToParentLayer, this, _1)); |
| 20 | context->onConnected.connect(onConnected); | 20 | context->onConnected.connect(onConnected); |
diff --git a/Swiften/StreamStack/TLSLayer.h b/Swiften/StreamStack/TLSLayer.h index 089512d..87d69a9 100644 --- a/Swiften/StreamStack/TLSLayer.h +++ b/Swiften/StreamStack/TLSLayer.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <Swiften/TLS/CertificateWithKey.h> | 15 | #include <Swiften/TLS/CertificateWithKey.h> |
| 16 | #include <Swiften/TLS/CertificateVerificationError.h> | 16 | #include <Swiften/TLS/CertificateVerificationError.h> |
| 17 | #include <Swiften/TLS/TLSError.h> | 17 | #include <Swiften/TLS/TLSError.h> |
| 18 | #include <Swiften/TLS/TLSOptions.h> | ||
| 18 | 19 | ||
| 19 | namespace Swift { | 20 | namespace Swift { |
| 20 | class TLSContext; | 21 | class TLSContext; |
| @@ -22,7 +23,7 @@ namespace Swift { | |||
| 22 | 23 | ||
| 23 | class SWIFTEN_API TLSLayer : public StreamLayer { | 24 | class SWIFTEN_API TLSLayer : public StreamLayer { |
| 24 | public: | 25 | public: |
| 25 | TLSLayer(TLSContextFactory*); | 26 | TLSLayer(TLSContextFactory*, const TLSOptions&); |
| 26 | ~TLSLayer(); | 27 | ~TLSLayer(); |
| 27 | 28 | ||
| 28 | void connect(); | 29 | void connect(); |
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp index 5fbc913..50f6731 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp | |||
| @@ -14,7 +14,7 @@ bool OpenSSLContextFactory::canCreate() const { | |||
| 14 | return true; | 14 | return true; |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | TLSContext* OpenSSLContextFactory::createTLSContext() { | 17 | TLSContext* OpenSSLContextFactory::createTLSContext(const TLSOptions&) { |
| 18 | return new OpenSSLContext(); | 18 | return new OpenSSLContext(); |
| 19 | } | 19 | } |
| 20 | 20 | ||
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h index 8e689b5..bf7f08a 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h +++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h | |||
| @@ -14,7 +14,7 @@ namespace Swift { | |||
| 14 | class OpenSSLContextFactory : public TLSContextFactory { | 14 | class OpenSSLContextFactory : public TLSContextFactory { |
| 15 | public: | 15 | public: |
| 16 | bool canCreate() const; | 16 | bool canCreate() const; |
| 17 | virtual TLSContext* createTLSContext(); | 17 | virtual TLSContext* createTLSContext(const TLSOptions& tlsOptions); |
| 18 | 18 | ||
| 19 | // Not supported | 19 | // Not supported |
| 20 | virtual void setCheckCertificateRevocation(bool b); | 20 | virtual void setCheckCertificateRevocation(bool b); |
diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp index 86b8c18..5f230ec 100644 --- a/Swiften/TLS/Schannel/SchannelContext.cpp +++ b/Swiften/TLS/Schannel/SchannelContext.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (c) 2012 Isode Limited. | 8 | * Copyright (c) 2012-2015 Isode Limited. |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * See the COPYING file for more information. | 10 | * See the COPYING file for more information. |
| 11 | */ | 11 | */ |
| @@ -21,8 +21,8 @@ namespace Swift { | |||
| 21 | 21 | ||
| 22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
| 23 | 23 | ||
| 24 | SchannelContext::SchannelContext() : m_state(Start), m_secContext(0), m_my_cert_store(NULL), m_cert_store_name("MY"), m_cert_name(), m_smartcard_reader(), checkCertificateRevocation(true) { | 24 | SchannelContext::SchannelContext(bool tls1_0Workaround) : state_(Start), secContext_(0), myCertStore_(NULL), certStoreName_("MY"), certName_(), smartCardReader_(), checkCertificateRevocation_(true), tls1_0Workaround_(tls1_0Workaround) { |
| 25 | m_ctxtFlags = ISC_REQ_ALLOCATE_MEMORY | | 25 | contextFlags_ = ISC_REQ_ALLOCATE_MEMORY | |
| 26 | ISC_REQ_CONFIDENTIALITY | | 26 | ISC_REQ_CONFIDENTIALITY | |
| 27 | ISC_REQ_EXTENDED_ERROR | | 27 | ISC_REQ_EXTENDED_ERROR | |
| 28 | ISC_REQ_INTEGRITY | | 28 | ISC_REQ_INTEGRITY | |
| @@ -31,19 +31,19 @@ SchannelContext::SchannelContext() : m_state(Start), m_secContext(0), m_my_cert_ | |||
| 31 | ISC_REQ_USE_SUPPLIED_CREDS | | 31 | ISC_REQ_USE_SUPPLIED_CREDS | |
| 32 | ISC_REQ_STREAM; | 32 | ISC_REQ_STREAM; |
| 33 | 33 | ||
| 34 | ZeroMemory(&m_streamSizes, sizeof(m_streamSizes)); | 34 | ZeroMemory(&streamSizes_, sizeof(streamSizes_)); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | //------------------------------------------------------------------------ | 37 | //------------------------------------------------------------------------ |
| 38 | 38 | ||
| 39 | SchannelContext::~SchannelContext() { | 39 | SchannelContext::~SchannelContext() { |
| 40 | if (m_my_cert_store) CertCloseStore(m_my_cert_store, 0); | 40 | if (myCertStore_) CertCloseStore(myCertStore_, 0); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | //------------------------------------------------------------------------ | 43 | //------------------------------------------------------------------------ |
| 44 | 44 | ||
| 45 | void SchannelContext::determineStreamSizes() { | 45 | void SchannelContext::determineStreamSizes() { |
| 46 | QueryContextAttributes(m_ctxtHandle, SECPKG_ATTR_STREAM_SIZES, &m_streamSizes); | 46 | QueryContextAttributes(contextHandle_, SECPKG_ATTR_STREAM_SIZES, &streamSizes_); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | //------------------------------------------------------------------------ | 49 | //------------------------------------------------------------------------ |
| @@ -51,20 +51,20 @@ void SchannelContext::determineStreamSizes() { | |||
| 51 | void SchannelContext::connect() { | 51 | void SchannelContext::connect() { |
| 52 | ScopedCertContext pCertContext; | 52 | ScopedCertContext pCertContext; |
| 53 | 53 | ||
| 54 | m_state = Connecting; | 54 | state_ = Connecting; |
| 55 | 55 | ||
| 56 | // If a user name is specified, then attempt to find a client | 56 | // If a user name is specified, then attempt to find a client |
| 57 | // certificate. Otherwise, just create a NULL credential. | 57 | // certificate. Otherwise, just create a NULL credential. |
| 58 | if (!m_cert_name.empty()) { | 58 | if (!certName_.empty()) { |
| 59 | if (m_my_cert_store == NULL) { | 59 | if (myCertStore_ == NULL) { |
| 60 | m_my_cert_store = CertOpenSystemStore(0, m_cert_store_name.c_str()); | 60 | myCertStore_ = CertOpenSystemStore(0, certStoreName_.c_str()); |
| 61 | if (!m_my_cert_store) { | 61 | if (!myCertStore_) { |
| 62 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 62 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 63 | return; | 63 | return; |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | pCertContext = findCertificateInStore( m_my_cert_store, m_cert_name ); | 67 | pCertContext = findCertificateInStore( myCertStore_, certName_ ); |
| 68 | if (pCertContext == NULL) { | 68 | if (pCertContext == NULL) { |
| 69 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 69 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 70 | return; | 70 | return; |
| @@ -77,8 +77,13 @@ void SchannelContext::connect() { | |||
| 77 | SCHANNEL_CRED sc = {0}; | 77 | SCHANNEL_CRED sc = {0}; |
| 78 | sc.dwVersion = SCHANNEL_CRED_VERSION; | 78 | sc.dwVersion = SCHANNEL_CRED_VERSION; |
| 79 | 79 | ||
| 80 | /////SSL3? | 80 | if (tls1_0Workaround_) { |
| 81 | sc.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; | 81 | sc.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT; |
| 82 | } | ||
| 83 | else { | ||
| 84 | sc.grbitEnabledProtocols = /*SP_PROT_SSL3_CLIENT | */SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; | ||
| 85 | } | ||
| 86 | |||
| 82 | sc.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; | 87 | sc.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; |
| 83 | 88 | ||
| 84 | if (pCertContext) { | 89 | if (pCertContext) { |
| @@ -103,9 +108,9 @@ void SchannelContext::connect() { | |||
| 103 | &sc, | 108 | &sc, |
| 104 | NULL, | 109 | NULL, |
| 105 | NULL, | 110 | NULL, |
| 106 | m_credHandle.Reset(), | 111 | credHandle_.Reset(), |
| 107 | NULL); | 112 | NULL); |
| 108 | 113 | ||
| 109 | if (status != SEC_E_OK) { | 114 | if (status != SEC_E_OK) { |
| 110 | // We failed to obtain the credentials handle | 115 | // We failed to obtain the credentials handle |
| 111 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 116 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| @@ -135,17 +140,17 @@ void SchannelContext::connect() { | |||
| 135 | 140 | ||
| 136 | // Create the initial security context | 141 | // Create the initial security context |
| 137 | status = InitializeSecurityContext( | 142 | status = InitializeSecurityContext( |
| 138 | m_credHandle, | 143 | credHandle_, |
| 139 | NULL, | 144 | NULL, |
| 140 | NULL, | 145 | NULL, |
| 141 | m_ctxtFlags, | 146 | contextFlags_, |
| 142 | 0, | 147 | 0, |
| 143 | 0, | 148 | 0, |
| 144 | NULL, | 149 | NULL, |
| 145 | 0, | 150 | 0, |
| 146 | m_ctxtHandle.Reset(), | 151 | contextHandle_.Reset(), |
| 147 | &outBufferDesc, | 152 | &outBufferDesc, |
| 148 | &m_secContext, | 153 | &secContext_, |
| 149 | NULL); | 154 | NULL); |
| 150 | 155 | ||
| 151 | if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { | 156 | if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { |
| @@ -164,7 +169,7 @@ void SchannelContext::connect() { | |||
| 164 | handleCertError(status); | 169 | handleCertError(status); |
| 165 | } | 170 | } |
| 166 | 171 | ||
| 167 | m_state = Connected; | 172 | state_ = Connected; |
| 168 | determineStreamSizes(); | 173 | determineStreamSizes(); |
| 169 | 174 | ||
| 170 | onConnected(); | 175 | onConnected(); |
| @@ -179,7 +184,7 @@ SECURITY_STATUS SchannelContext::validateServerCertificate() { | |||
| 179 | return SEC_E_WRONG_PRINCIPAL; | 184 | return SEC_E_WRONG_PRINCIPAL; |
| 180 | } | 185 | } |
| 181 | 186 | ||
| 182 | const LPSTR usage[] = | 187 | const LPSTR usage[] = |
| 183 | { | 188 | { |
| 184 | szOID_PKIX_KP_SERVER_AUTH, | 189 | szOID_PKIX_KP_SERVER_AUTH, |
| 185 | szOID_SERVER_GATED_CRYPTO, | 190 | szOID_SERVER_GATED_CRYPTO, |
| @@ -193,7 +198,7 @@ SECURITY_STATUS SchannelContext::validateServerCertificate() { | |||
| 193 | chainParams.RequestedUsage.Usage.rgpszUsageIdentifier = const_cast<LPSTR*>(usage); | 198 | chainParams.RequestedUsage.Usage.rgpszUsageIdentifier = const_cast<LPSTR*>(usage); |
| 194 | 199 | ||
| 195 | DWORD chainFlags = CERT_CHAIN_CACHE_END_CERT; | 200 | DWORD chainFlags = CERT_CHAIN_CACHE_END_CERT; |
| 196 | if (checkCertificateRevocation) { | 201 | if (checkCertificateRevocation_) { |
| 197 | chainFlags |= CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; | 202 | chainFlags |= CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; |
| 198 | } | 203 | } |
| 199 | 204 | ||
| @@ -246,9 +251,9 @@ SECURITY_STATUS SchannelContext::validateServerCertificate() { | |||
| 246 | //------------------------------------------------------------------------ | 251 | //------------------------------------------------------------------------ |
| 247 | 252 | ||
| 248 | void SchannelContext::appendNewData(const SafeByteArray& data) { | 253 | void SchannelContext::appendNewData(const SafeByteArray& data) { |
| 249 | size_t originalSize = m_receivedData.size(); | 254 | size_t originalSize = receivedData_.size(); |
| 250 | m_receivedData.resize(originalSize + data.size()); | 255 | receivedData_.resize(originalSize + data.size()); |
| 251 | memcpy(&m_receivedData[0] + originalSize, &data[0], data.size()); | 256 | memcpy(&receivedData_[0] + originalSize, &data[0], data.size()); |
| 252 | } | 257 | } |
| 253 | 258 | ||
| 254 | //------------------------------------------------------------------------ | 259 | //------------------------------------------------------------------------ |
| @@ -256,12 +261,12 @@ void SchannelContext::appendNewData(const SafeByteArray& data) { | |||
| 256 | void SchannelContext::continueHandshake(const SafeByteArray& data) { | 261 | void SchannelContext::continueHandshake(const SafeByteArray& data) { |
| 257 | appendNewData(data); | 262 | appendNewData(data); |
| 258 | 263 | ||
| 259 | while (!m_receivedData.empty()) { | 264 | while (!receivedData_.empty()) { |
| 260 | SecBuffer inBuffers[2]; | 265 | SecBuffer inBuffers[2]; |
| 261 | 266 | ||
| 262 | // Provide Schannel with the remote host's handshake data | 267 | // Provide Schannel with the remote host's handshake data |
| 263 | inBuffers[0].pvBuffer = (char*)(&m_receivedData[0]); | 268 | inBuffers[0].pvBuffer = (char*)(&receivedData_[0]); |
| 264 | inBuffers[0].cbBuffer = (unsigned long)m_receivedData.size(); | 269 | inBuffers[0].cbBuffer = (unsigned long)receivedData_.size(); |
| 265 | inBuffers[0].BufferType = SECBUFFER_TOKEN; | 270 | inBuffers[0].BufferType = SECBUFFER_TOKEN; |
| 266 | 271 | ||
| 267 | inBuffers[1].pvBuffer = NULL; | 272 | inBuffers[1].pvBuffer = NULL; |
| @@ -295,17 +300,17 @@ void SchannelContext::continueHandshake(const SafeByteArray& data) { | |||
| 295 | outBufferDesc.ulVersion = SECBUFFER_VERSION; | 300 | outBufferDesc.ulVersion = SECBUFFER_VERSION; |
| 296 | 301 | ||
| 297 | SECURITY_STATUS status = InitializeSecurityContext( | 302 | SECURITY_STATUS status = InitializeSecurityContext( |
| 298 | m_credHandle, | 303 | credHandle_, |
| 299 | m_ctxtHandle, | 304 | contextHandle_, |
| 300 | NULL, | 305 | NULL, |
| 301 | m_ctxtFlags, | 306 | contextFlags_, |
| 302 | 0, | 307 | 0, |
| 303 | 0, | 308 | 0, |
| 304 | &inBufferDesc, | 309 | &inBufferDesc, |
| 305 | 0, | 310 | 0, |
| 306 | NULL, | 311 | NULL, |
| 307 | &outBufferDesc, | 312 | &outBufferDesc, |
| 308 | &m_secContext, | 313 | &secContext_, |
| 309 | NULL); | 314 | NULL); |
| 310 | 315 | ||
| 311 | if (status == SEC_E_INCOMPLETE_MESSAGE) { | 316 | if (status == SEC_E_INCOMPLETE_MESSAGE) { |
| @@ -315,16 +320,16 @@ void SchannelContext::continueHandshake(const SafeByteArray& data) { | |||
| 315 | else if (status == SEC_I_CONTINUE_NEEDED) { | 320 | else if (status == SEC_I_CONTINUE_NEEDED) { |
| 316 | SecBuffer* pDataBuffer = &outBuffers[0]; | 321 | SecBuffer* pDataBuffer = &outBuffers[0]; |
| 317 | SecBuffer* pExtraBuffer = &inBuffers[1]; | 322 | SecBuffer* pExtraBuffer = &inBuffers[1]; |
| 318 | 323 | ||
| 319 | if (pDataBuffer && pDataBuffer->cbBuffer > 0 && pDataBuffer->pvBuffer != NULL) { | 324 | if (pDataBuffer && pDataBuffer->cbBuffer > 0 && pDataBuffer->pvBuffer != NULL) { |
| 320 | sendDataOnNetwork(pDataBuffer->pvBuffer, pDataBuffer->cbBuffer); | 325 | sendDataOnNetwork(pDataBuffer->pvBuffer, pDataBuffer->cbBuffer); |
| 321 | } | 326 | } |
| 322 | 327 | ||
| 323 | if (pExtraBuffer->BufferType == SECBUFFER_EXTRA) { | 328 | if (pExtraBuffer->BufferType == SECBUFFER_EXTRA) { |
| 324 | m_receivedData.erase(m_receivedData.begin(), m_receivedData.end() - pExtraBuffer->cbBuffer); | 329 | receivedData_.erase(receivedData_.begin(), receivedData_.end() - pExtraBuffer->cbBuffer); |
| 325 | } | 330 | } |
| 326 | else { | 331 | else { |
| 327 | m_receivedData.clear(); | 332 | receivedData_.clear(); |
| 328 | } | 333 | } |
| 329 | 334 | ||
| 330 | break; | 335 | break; |
| @@ -336,19 +341,19 @@ void SchannelContext::continueHandshake(const SafeByteArray& data) { | |||
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | SecBuffer* pExtraBuffer = &inBuffers[1]; | 343 | SecBuffer* pExtraBuffer = &inBuffers[1]; |
| 339 | 344 | ||
| 340 | if (pExtraBuffer && pExtraBuffer->cbBuffer > 0) { | 345 | if (pExtraBuffer && pExtraBuffer->cbBuffer > 0) { |
| 341 | m_receivedData.erase(m_receivedData.begin(), m_receivedData.end() - pExtraBuffer->cbBuffer); | 346 | receivedData_.erase(receivedData_.begin(), receivedData_.end() - pExtraBuffer->cbBuffer); |
| 342 | } | 347 | } |
| 343 | else { | 348 | else { |
| 344 | m_receivedData.clear(); | 349 | receivedData_.clear(); |
| 345 | } | 350 | } |
| 346 | 351 | ||
| 347 | m_state = Connected; | 352 | state_ = Connected; |
| 348 | determineStreamSizes(); | 353 | determineStreamSizes(); |
| 349 | 354 | ||
| 350 | onConnected(); | 355 | onConnected(); |
| 351 | } | 356 | } |
| 352 | else { | 357 | else { |
| 353 | // We failed to initialize the security context | 358 | // We failed to initialize the security context |
| 354 | handleCertError(status); | 359 | handleCertError(status); |
| @@ -360,35 +365,35 @@ void SchannelContext::continueHandshake(const SafeByteArray& data) { | |||
| 360 | 365 | ||
| 361 | //------------------------------------------------------------------------ | 366 | //------------------------------------------------------------------------ |
| 362 | 367 | ||
| 363 | void SchannelContext::handleCertError(SECURITY_STATUS status) | 368 | void SchannelContext::handleCertError(SECURITY_STATUS status) |
| 364 | { | 369 | { |
| 365 | if (status == SEC_E_UNTRUSTED_ROOT || | 370 | if (status == SEC_E_UNTRUSTED_ROOT || |
| 366 | status == CERT_E_UNTRUSTEDROOT || | 371 | status == CERT_E_UNTRUSTEDROOT || |
| 367 | status == CRYPT_E_ISSUER_SERIALNUMBER || | 372 | status == CRYPT_E_ISSUER_SERIALNUMBER || |
| 368 | status == CRYPT_E_SIGNER_NOT_FOUND || | 373 | status == CRYPT_E_SIGNER_NOT_FOUND || |
| 369 | status == CRYPT_E_NO_TRUSTED_SIGNER) { | 374 | status == CRYPT_E_NO_TRUSTED_SIGNER) { |
| 370 | m_verificationError = CertificateVerificationError::Untrusted; | 375 | verificationError_ = CertificateVerificationError::Untrusted; |
| 371 | } | 376 | } |
| 372 | else if (status == SEC_E_CERT_EXPIRED || | 377 | else if (status == SEC_E_CERT_EXPIRED || |
| 373 | status == CERT_E_EXPIRED) { | 378 | status == CERT_E_EXPIRED) { |
| 374 | m_verificationError = CertificateVerificationError::Expired; | 379 | verificationError_ = CertificateVerificationError::Expired; |
| 375 | } | 380 | } |
| 376 | else if (status == CRYPT_E_SELF_SIGNED) { | 381 | else if (status == CRYPT_E_SELF_SIGNED) { |
| 377 | m_verificationError = CertificateVerificationError::SelfSigned; | 382 | verificationError_ = CertificateVerificationError::SelfSigned; |
| 378 | } | 383 | } |
| 379 | else if (status == CRYPT_E_HASH_VALUE || | 384 | else if (status == CRYPT_E_HASH_VALUE || |
| 380 | status == TRUST_E_CERT_SIGNATURE) { | 385 | status == TRUST_E_CERT_SIGNATURE) { |
| 381 | m_verificationError = CertificateVerificationError::InvalidSignature; | 386 | verificationError_ = CertificateVerificationError::InvalidSignature; |
| 382 | } | 387 | } |
| 383 | else if (status == CRYPT_E_REVOKED) { | 388 | else if (status == CRYPT_E_REVOKED) { |
| 384 | m_verificationError = CertificateVerificationError::Revoked; | 389 | verificationError_ = CertificateVerificationError::Revoked; |
| 385 | } | 390 | } |
| 386 | else if (status == CRYPT_E_NO_REVOCATION_CHECK || | 391 | else if (status == CRYPT_E_NO_REVOCATION_CHECK || |
| 387 | status == CRYPT_E_REVOCATION_OFFLINE) { | 392 | status == CRYPT_E_REVOCATION_OFFLINE) { |
| 388 | m_verificationError = CertificateVerificationError::RevocationCheckFailed; | 393 | verificationError_ = CertificateVerificationError::RevocationCheckFailed; |
| 389 | } | 394 | } |
| 390 | else { | 395 | else { |
| 391 | m_verificationError = CertificateVerificationError::UnknownError; | 396 | verificationError_ = CertificateVerificationError::UnknownError; |
| 392 | } | 397 | } |
| 393 | } | 398 | } |
| 394 | 399 | ||
| @@ -416,7 +421,7 @@ void SchannelContext::forwardDataToApplication(const void* pData, size_t dataSiz | |||
| 416 | 421 | ||
| 417 | void SchannelContext::handleDataFromApplication(const SafeByteArray& data) { | 422 | void SchannelContext::handleDataFromApplication(const SafeByteArray& data) { |
| 418 | // Don't attempt to send data until we're fully connected | 423 | // Don't attempt to send data until we're fully connected |
| 419 | if (m_state == Connecting) { | 424 | if (state_ == Connecting) { |
| 420 | return; | 425 | return; |
| 421 | } | 426 | } |
| 422 | 427 | ||
| @@ -427,7 +432,7 @@ void SchannelContext::handleDataFromApplication(const SafeByteArray& data) { | |||
| 427 | //------------------------------------------------------------------------ | 432 | //------------------------------------------------------------------------ |
| 428 | 433 | ||
| 429 | void SchannelContext::handleDataFromNetwork(const SafeByteArray& data) { | 434 | void SchannelContext::handleDataFromNetwork(const SafeByteArray& data) { |
| 430 | switch (m_state) { | 435 | switch (state_) { |
| 431 | case Connecting: | 436 | case Connecting: |
| 432 | { | 437 | { |
| 433 | // We're still establishing the connection, so continue the handshake | 438 | // We're still establishing the connection, so continue the handshake |
| @@ -450,8 +455,8 @@ void SchannelContext::handleDataFromNetwork(const SafeByteArray& data) { | |||
| 450 | //------------------------------------------------------------------------ | 455 | //------------------------------------------------------------------------ |
| 451 | 456 | ||
| 452 | void SchannelContext::indicateError(boost::shared_ptr<TLSError> error) { | 457 | void SchannelContext::indicateError(boost::shared_ptr<TLSError> error) { |
| 453 | m_state = Error; | 458 | state_ = Error; |
| 454 | m_receivedData.clear(); | 459 | receivedData_.clear(); |
| 455 | onError(error); | 460 | onError(error); |
| 456 | } | 461 | } |
| 457 | 462 | ||
| @@ -461,20 +466,20 @@ void SchannelContext::decryptAndProcessData(const SafeByteArray& data) { | |||
| 461 | SecBuffer inBuffers[4] = {0}; | 466 | SecBuffer inBuffers[4] = {0}; |
| 462 | 467 | ||
| 463 | appendNewData(data); | 468 | appendNewData(data); |
| 464 | 469 | ||
| 465 | while (!m_receivedData.empty()) { | 470 | while (!receivedData_.empty()) { |
| 466 | // | 471 | // |
| 467 | // MSDN: | 472 | // MSDN: |
| 468 | // When using the Schannel SSP with contexts that are not connection oriented, on input, | 473 | // When using the Schannel SSP with contexts that are not connection oriented, on input, |
| 469 | // the structure must contain four SecBuffer structures. Exactly one buffer must be of type | 474 | // the structure must contain four SecBuffer structures. Exactly one buffer must be of type |
| 470 | // SECBUFFER_DATA and contain an encrypted message, which is decrypted in place. The remaining | 475 | // SECBUFFER_DATA and contain an encrypted message, which is decrypted in place. The remaining |
| 471 | // buffers are used for output and must be of type SECBUFFER_EMPTY. For connection-oriented | 476 | // buffers are used for output and must be of type SECBUFFER_EMPTY. For connection-oriented |
| 472 | // contexts, a SECBUFFER_DATA type buffer must be supplied, as noted for nonconnection-oriented | 477 | // contexts, a SECBUFFER_DATA type buffer must be supplied, as noted for nonconnection-oriented |
| 473 | // contexts. Additionally, a second SECBUFFER_TOKEN type buffer that contains a security token | 478 | // contexts. Additionally, a second SECBUFFER_TOKEN type buffer that contains a security token |
| 474 | // must also be supplied. | 479 | // must also be supplied. |
| 475 | // | 480 | // |
| 476 | inBuffers[0].pvBuffer = (char*)(&m_receivedData[0]); | 481 | inBuffers[0].pvBuffer = (char*)(&receivedData_[0]); |
| 477 | inBuffers[0].cbBuffer = (unsigned long)m_receivedData.size(); | 482 | inBuffers[0].cbBuffer = (unsigned long)receivedData_.size(); |
| 478 | inBuffers[0].BufferType = SECBUFFER_DATA; | 483 | inBuffers[0].BufferType = SECBUFFER_DATA; |
| 479 | 484 | ||
| 480 | inBuffers[1].BufferType = SECBUFFER_EMPTY; | 485 | inBuffers[1].BufferType = SECBUFFER_EMPTY; |
| @@ -486,22 +491,22 @@ void SchannelContext::decryptAndProcessData(const SafeByteArray& data) { | |||
| 486 | inBufferDesc.pBuffers = inBuffers; | 491 | inBufferDesc.pBuffers = inBuffers; |
| 487 | inBufferDesc.ulVersion = SECBUFFER_VERSION; | 492 | inBufferDesc.ulVersion = SECBUFFER_VERSION; |
| 488 | 493 | ||
| 489 | size_t inData = m_receivedData.size(); | 494 | size_t inData = receivedData_.size(); |
| 490 | SECURITY_STATUS status = DecryptMessage(m_ctxtHandle, &inBufferDesc, 0, NULL); | 495 | SECURITY_STATUS status = DecryptMessage(contextHandle_, &inBufferDesc, 0, NULL); |
| 491 | 496 | ||
| 492 | if (status == SEC_E_INCOMPLETE_MESSAGE) { | 497 | if (status == SEC_E_INCOMPLETE_MESSAGE) { |
| 493 | // Wait for more data to arrive | 498 | // Wait for more data to arrive |
| 494 | break; | 499 | break; |
| 495 | } | 500 | } |
| 496 | else if (status == SEC_I_RENEGOTIATE) { | 501 | else if (status == SEC_I_RENEGOTIATE) { |
| 497 | // TODO: Handle renegotiation scenarios | 502 | // TODO: Handle renegotiation scenarios |
| 498 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 503 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 499 | break; | 504 | break; |
| 500 | } | 505 | } |
| 501 | else if (status == SEC_I_CONTEXT_EXPIRED) { | 506 | else if (status == SEC_I_CONTEXT_EXPIRED) { |
| 502 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 507 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 503 | break; | 508 | break; |
| 504 | } | 509 | } |
| 505 | else if (status != SEC_E_OK) { | 510 | else if (status != SEC_E_OK) { |
| 506 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 511 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 507 | break; | 512 | break; |
| @@ -524,11 +529,11 @@ void SchannelContext::decryptAndProcessData(const SafeByteArray& data) { | |||
| 524 | 529 | ||
| 525 | // If there is extra data left over from the decryption operation, we call DecryptMessage() again | 530 | // If there is extra data left over from the decryption operation, we call DecryptMessage() again |
| 526 | if (pExtraBuffer) { | 531 | if (pExtraBuffer) { |
| 527 | m_receivedData.erase(m_receivedData.begin(), m_receivedData.end() - pExtraBuffer->cbBuffer); | 532 | receivedData_.erase(receivedData_.begin(), receivedData_.end() - pExtraBuffer->cbBuffer); |
| 528 | } | 533 | } |
| 529 | else { | 534 | else { |
| 530 | // We're done | 535 | // We're done |
| 531 | m_receivedData.erase(m_receivedData.begin(), m_receivedData.begin() + inData); | 536 | receivedData_.erase(receivedData_.begin(), receivedData_.begin() + inData); |
| 532 | } | 537 | } |
| 533 | } | 538 | } |
| 534 | } | 539 | } |
| @@ -536,43 +541,43 @@ void SchannelContext::decryptAndProcessData(const SafeByteArray& data) { | |||
| 536 | //------------------------------------------------------------------------ | 541 | //------------------------------------------------------------------------ |
| 537 | 542 | ||
| 538 | void SchannelContext::encryptAndSendData(const SafeByteArray& data) { | 543 | void SchannelContext::encryptAndSendData(const SafeByteArray& data) { |
| 539 | if (m_streamSizes.cbMaximumMessage == 0) { | 544 | if (streamSizes_.cbMaximumMessage == 0) { |
| 540 | return; | 545 | return; |
| 541 | } | 546 | } |
| 542 | 547 | ||
| 543 | SecBuffer outBuffers[4] = {0}; | 548 | SecBuffer outBuffers[4] = {0}; |
| 544 | 549 | ||
| 545 | // Calculate the largest required size of the send buffer | 550 | // Calculate the largest required size of the send buffer |
| 546 | size_t messageBufferSize = (data.size() > m_streamSizes.cbMaximumMessage) | 551 | size_t messageBufferSize = (data.size() > streamSizes_.cbMaximumMessage) |
| 547 | ? m_streamSizes.cbMaximumMessage | 552 | ? streamSizes_.cbMaximumMessage |
| 548 | : data.size(); | 553 | : data.size(); |
| 549 | 554 | ||
| 550 | // Allocate a packet for the encrypted data | 555 | // Allocate a packet for the encrypted data |
| 551 | SafeByteArray sendBuffer; | 556 | SafeByteArray sendBuffer; |
| 552 | sendBuffer.resize(m_streamSizes.cbHeader + messageBufferSize + m_streamSizes.cbTrailer); | 557 | sendBuffer.resize(streamSizes_.cbHeader + messageBufferSize + streamSizes_.cbTrailer); |
| 553 | 558 | ||
| 554 | size_t bytesSent = 0; | 559 | size_t bytesSent = 0; |
| 555 | do { | 560 | do { |
| 556 | size_t bytesLeftToSend = data.size() - bytesSent; | 561 | size_t bytesLeftToSend = data.size() - bytesSent; |
| 557 | 562 | ||
| 558 | // Calculate how much of the send buffer we'll be using for this chunk | 563 | // Calculate how much of the send buffer we'll be using for this chunk |
| 559 | size_t bytesToSend = (bytesLeftToSend > m_streamSizes.cbMaximumMessage) | 564 | size_t bytesToSend = (bytesLeftToSend > streamSizes_.cbMaximumMessage) |
| 560 | ? m_streamSizes.cbMaximumMessage | 565 | ? streamSizes_.cbMaximumMessage |
| 561 | : bytesLeftToSend; | 566 | : bytesLeftToSend; |
| 562 | 567 | ||
| 563 | // Copy the plain text data into the send buffer | 568 | // Copy the plain text data into the send buffer |
| 564 | memcpy(&sendBuffer[0] + m_streamSizes.cbHeader, &data[0] + bytesSent, bytesToSend); | 569 | memcpy(&sendBuffer[0] + streamSizes_.cbHeader, &data[0] + bytesSent, bytesToSend); |
| 565 | 570 | ||
| 566 | outBuffers[0].pvBuffer = &sendBuffer[0]; | 571 | outBuffers[0].pvBuffer = &sendBuffer[0]; |
| 567 | outBuffers[0].cbBuffer = m_streamSizes.cbHeader; | 572 | outBuffers[0].cbBuffer = streamSizes_.cbHeader; |
| 568 | outBuffers[0].BufferType = SECBUFFER_STREAM_HEADER; | 573 | outBuffers[0].BufferType = SECBUFFER_STREAM_HEADER; |
| 569 | 574 | ||
| 570 | outBuffers[1].pvBuffer = &sendBuffer[0] + m_streamSizes.cbHeader; | 575 | outBuffers[1].pvBuffer = &sendBuffer[0] + streamSizes_.cbHeader; |
| 571 | outBuffers[1].cbBuffer = (unsigned long)bytesToSend; | 576 | outBuffers[1].cbBuffer = (unsigned long)bytesToSend; |
| 572 | outBuffers[1].BufferType = SECBUFFER_DATA; | 577 | outBuffers[1].BufferType = SECBUFFER_DATA; |
| 573 | 578 | ||
| 574 | outBuffers[2].pvBuffer = &sendBuffer[0] + m_streamSizes.cbHeader + bytesToSend; | 579 | outBuffers[2].pvBuffer = &sendBuffer[0] + streamSizes_.cbHeader + bytesToSend; |
| 575 | outBuffers[2].cbBuffer = m_streamSizes.cbTrailer; | 580 | outBuffers[2].cbBuffer = streamSizes_.cbTrailer; |
| 576 | outBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER; | 581 | outBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER; |
| 577 | 582 | ||
| 578 | outBuffers[3].pvBuffer = 0; | 583 | outBuffers[3].pvBuffer = 0; |
| @@ -584,7 +589,7 @@ void SchannelContext::encryptAndSendData(const SafeByteArray& data) { | |||
| 584 | outBufferDesc.pBuffers = outBuffers; | 589 | outBufferDesc.pBuffers = outBuffers; |
| 585 | outBufferDesc.ulVersion = SECBUFFER_VERSION; | 590 | outBufferDesc.ulVersion = SECBUFFER_VERSION; |
| 586 | 591 | ||
| 587 | SECURITY_STATUS status = EncryptMessage(m_ctxtHandle, 0, &outBufferDesc, 0); | 592 | SECURITY_STATUS status = EncryptMessage(contextHandle_, 0, &outBufferDesc, 0); |
| 588 | if (status != SEC_E_OK) { | 593 | if (status != SEC_E_OK) { |
| 589 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); | 594 | indicateError(boost::make_shared<TLSError>(TLSError::UnknownError)); |
| 590 | return; | 595 | return; |
| @@ -604,14 +609,14 @@ bool SchannelContext::setClientCertificate(CertificateWithKey::ref certificate) | |||
| 604 | return false; | 609 | return false; |
| 605 | } | 610 | } |
| 606 | 611 | ||
| 607 | userCertificate = capiCertificate; | 612 | userCertificate_ = capiCertificate; |
| 608 | 613 | ||
| 609 | // We assume that the Certificate Store Name/Certificate Name | 614 | // We assume that the Certificate Store Name/Certificate Name |
| 610 | // are valid at this point | 615 | // are valid at this point |
| 611 | m_cert_store_name = capiCertificate->getCertStoreName(); | 616 | certStoreName_ = capiCertificate->getCertStoreName(); |
| 612 | m_cert_name = capiCertificate->getCertName(); | 617 | certName_ = capiCertificate->getCertName(); |
| 613 | ////At the moment this is only useful for logging: | 618 | ////At the moment this is only useful for logging: |
| 614 | m_smartcard_reader = capiCertificate->getSmartCardReaderName(); | 619 | smartCardReader_ = capiCertificate->getSmartCardReaderName(); |
| 615 | 620 | ||
| 616 | capiCertificate->onCertificateCardRemoved.connect(boost::bind(&SchannelContext::handleCertificateCardRemoved, this)); | 621 | capiCertificate->onCertificateCardRemoved.connect(boost::bind(&SchannelContext::handleCertificateCardRemoved, this)); |
| 617 | 622 | ||
| @@ -630,7 +635,7 @@ std::vector<Certificate::ref> SchannelContext::getPeerCertificateChain() const { | |||
| 630 | ScopedCertContext pServerCert; | 635 | ScopedCertContext pServerCert; |
| 631 | ScopedCertContext pIssuerCert; | 636 | ScopedCertContext pIssuerCert; |
| 632 | ScopedCertContext pCurrentCert; | 637 | ScopedCertContext pCurrentCert; |
| 633 | SECURITY_STATUS status = QueryContextAttributes(m_ctxtHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, pServerCert.Reset()); | 638 | SECURITY_STATUS status = QueryContextAttributes(contextHandle_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, pServerCert.Reset()); |
| 634 | 639 | ||
| 635 | if (status != SEC_E_OK) { | 640 | if (status != SEC_E_OK) { |
| 636 | return certificateChain; | 641 | return certificateChain; |
| @@ -655,14 +660,14 @@ std::vector<Certificate::ref> SchannelContext::getPeerCertificateChain() const { | |||
| 655 | //------------------------------------------------------------------------ | 660 | //------------------------------------------------------------------------ |
| 656 | 661 | ||
| 657 | CertificateVerificationError::ref SchannelContext::getPeerCertificateVerificationError() const { | 662 | CertificateVerificationError::ref SchannelContext::getPeerCertificateVerificationError() const { |
| 658 | return m_verificationError ? boost::make_shared<CertificateVerificationError>(*m_verificationError) : CertificateVerificationError::ref(); | 663 | return verificationError_ ? boost::make_shared<CertificateVerificationError>(*verificationError_) : CertificateVerificationError::ref(); |
| 659 | } | 664 | } |
| 660 | 665 | ||
| 661 | //------------------------------------------------------------------------ | 666 | //------------------------------------------------------------------------ |
| 662 | 667 | ||
| 663 | ByteArray SchannelContext::getFinishMessage() const { | 668 | ByteArray SchannelContext::getFinishMessage() const { |
| 664 | SecPkgContext_Bindings bindings; | 669 | SecPkgContext_Bindings bindings; |
| 665 | int ret = QueryContextAttributes(m_ctxtHandle, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings); | 670 | int ret = QueryContextAttributes(contextHandle_, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings); |
| 666 | if (ret == SEC_E_OK) { | 671 | if (ret == SEC_E_OK) { |
| 667 | return createByteArray(((unsigned char*) bindings.Bindings) + bindings.Bindings->dwApplicationDataOffset + 11 /* tls-unique:*/, bindings.Bindings->cbApplicationDataLength - 11); | 672 | return createByteArray(((unsigned char*) bindings.Bindings) + bindings.Bindings->dwApplicationDataOffset + 11 /* tls-unique:*/, bindings.Bindings->cbApplicationDataLength - 11); |
| 668 | } | 673 | } |
| @@ -672,7 +677,7 @@ ByteArray SchannelContext::getFinishMessage() const { | |||
| 672 | //------------------------------------------------------------------------ | 677 | //------------------------------------------------------------------------ |
| 673 | 678 | ||
| 674 | void SchannelContext::setCheckCertificateRevocation(bool b) { | 679 | void SchannelContext::setCheckCertificateRevocation(bool b) { |
| 675 | checkCertificateRevocation = b; | 680 | checkCertificateRevocation_ = b; |
| 676 | } | 681 | } |
| 677 | 682 | ||
| 678 | 683 | ||
diff --git a/Swiften/TLS/Schannel/SchannelContext.h b/Swiften/TLS/Schannel/SchannelContext.h index 3a068f2..19cc473 100644 --- a/Swiften/TLS/Schannel/SchannelContext.h +++ b/Swiften/TLS/Schannel/SchannelContext.h | |||
| @@ -37,7 +37,7 @@ namespace Swift | |||
| 37 | typedef boost::shared_ptr<SchannelContext> sp_t; | 37 | typedef boost::shared_ptr<SchannelContext> sp_t; |
| 38 | 38 | ||
| 39 | public: | 39 | public: |
| 40 | SchannelContext(); | 40 | SchannelContext(bool tls1_0Workaround); |
| 41 | 41 | ||
| 42 | ~SchannelContext(); | 42 | ~SchannelContext(); |
| 43 | 43 | ||
| @@ -86,23 +86,24 @@ namespace Swift | |||
| 86 | 86 | ||
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | SchannelState m_state; | 89 | SchannelState state_; |
| 90 | boost::optional<CertificateVerificationError> m_verificationError; | 90 | boost::optional<CertificateVerificationError> verificationError_; |
| 91 | 91 | ||
| 92 | ULONG m_secContext; | 92 | ULONG secContext_; |
| 93 | ScopedCredHandle m_credHandle; | 93 | ScopedCredHandle credHandle_; |
| 94 | ScopedCtxtHandle m_ctxtHandle; | 94 | ScopedCtxtHandle contextHandle_; |
| 95 | DWORD m_ctxtFlags; | 95 | DWORD contextFlags_; |
| 96 | SecPkgContext_StreamSizes m_streamSizes; | 96 | SecPkgContext_StreamSizes streamSizes_; |
| 97 | 97 | ||
| 98 | std::vector<char> m_receivedData; | 98 | std::vector<char> receivedData_; |
| 99 | 99 | ||
| 100 | HCERTSTORE m_my_cert_store; | 100 | HCERTSTORE myCertStore_; |
| 101 | std::string m_cert_store_name; | 101 | std::string certStoreName_; |
| 102 | std::string m_cert_name; | 102 | std::string certName_; |
| 103 | ////Not needed, most likely | 103 | ////Not needed, most likely |
| 104 | std::string m_smartcard_reader; //Can be empty string for non SmartCard certificates | 104 | std::string smartCardReader_; //Can be empty string for non SmartCard certificates |
| 105 | boost::shared_ptr<CAPICertificate> userCertificate; | 105 | boost::shared_ptr<CAPICertificate> userCertificate_; |
| 106 | bool checkCertificateRevocation; | 106 | bool checkCertificateRevocation_; |
| 107 | bool tls1_0Workaround_; | ||
| 107 | }; | 108 | }; |
| 108 | } | 109 | } |
diff --git a/Swiften/TLS/Schannel/SchannelContextFactory.cpp b/Swiften/TLS/Schannel/SchannelContextFactory.cpp index 8b0044c..6e83b0d 100644 --- a/Swiften/TLS/Schannel/SchannelContextFactory.cpp +++ b/Swiften/TLS/Schannel/SchannelContextFactory.cpp | |||
| @@ -4,6 +4,12 @@ | |||
| 4 | * See Documentation/Licenses/BSD-simplified.txt for more information. | 4 | * See Documentation/Licenses/BSD-simplified.txt for more information. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | /* | ||
| 8 | * Copyright (c) 2015 Isode Limited. | ||
| 9 | * All rights reserved. | ||
| 10 | * See the COPYING file for more information. | ||
| 11 | */ | ||
| 12 | |||
| 7 | #include "Swiften/TLS/Schannel/SchannelContextFactory.h" | 13 | #include "Swiften/TLS/Schannel/SchannelContextFactory.h" |
| 8 | #include "Swiften/TLS/Schannel/SchannelContext.h" | 14 | #include "Swiften/TLS/Schannel/SchannelContext.h" |
| 9 | 15 | ||
| @@ -16,8 +22,8 @@ bool SchannelContextFactory::canCreate() const { | |||
| 16 | return true; | 22 | return true; |
| 17 | } | 23 | } |
| 18 | 24 | ||
| 19 | TLSContext* SchannelContextFactory::createTLSContext() { | 25 | TLSContext* SchannelContextFactory::createTLSContext(const TLSOptions& tlsOptions) { |
| 20 | SchannelContext* context = new SchannelContext(); | 26 | SchannelContext* context = new SchannelContext(tlsOptions.schannelTLS1_0Workaround); |
| 21 | context->setCheckCertificateRevocation(checkCertificateRevocation); | 27 | context->setCheckCertificateRevocation(checkCertificateRevocation); |
| 22 | return context; | 28 | return context; |
| 23 | } | 29 | } |
diff --git a/Swiften/TLS/Schannel/SchannelContextFactory.h b/Swiften/TLS/Schannel/SchannelContextFactory.h index 9dc835c..789d15f 100644 --- a/Swiften/TLS/Schannel/SchannelContextFactory.h +++ b/Swiften/TLS/Schannel/SchannelContextFactory.h | |||
| @@ -4,9 +4,15 @@ | |||
| 4 | * See Documentation/Licenses/BSD-simplified.txt for more information. | 4 | * See Documentation/Licenses/BSD-simplified.txt for more information. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | /* | ||
| 8 | * Copyright (c) 2015 Isode Limited. | ||
| 9 | * All rights reserved. | ||
| 10 | * See the COPYING file for more information. | ||
| 11 | */ | ||
| 12 | |||
| 7 | #pragma once | 13 | #pragma once |
| 8 | 14 | ||
| 9 | #include "Swiften/TLS/TLSContextFactory.h" | 15 | #include <Swiften/TLS/TLSContextFactory.h> |
| 10 | 16 | ||
| 11 | namespace Swift { | 17 | namespace Swift { |
| 12 | class SchannelContextFactory : public TLSContextFactory { | 18 | class SchannelContextFactory : public TLSContextFactory { |
| @@ -14,7 +20,7 @@ namespace Swift { | |||
| 14 | SchannelContextFactory(); | 20 | SchannelContextFactory(); |
| 15 | 21 | ||
| 16 | bool canCreate() const; | 22 | bool canCreate() const; |
| 17 | virtual TLSContext* createTLSContext(); | 23 | virtual TLSContext* createTLSContext(const TLSOptions& tlsOptions); |
| 18 | 24 | ||
| 19 | virtual void setCheckCertificateRevocation(bool b); | 25 | virtual void setCheckCertificateRevocation(bool b); |
| 20 | 26 | ||
diff --git a/Swiften/TLS/TLSContextFactory.h b/Swiften/TLS/TLSContextFactory.h index 10c5577..90da4a1 100644 --- a/Swiften/TLS/TLSContextFactory.h +++ b/Swiften/TLS/TLSContextFactory.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #pragma once | 7 | #pragma once |
| 8 | 8 | ||
| 9 | #include <Swiften/Base/API.h> | 9 | #include <Swiften/Base/API.h> |
| 10 | #include <Swiften/TLS/TLSOptions.h> | ||
| 10 | 11 | ||
| 11 | namespace Swift { | 12 | namespace Swift { |
| 12 | class TLSContext; | 13 | class TLSContext; |
| @@ -17,7 +18,7 @@ namespace Swift { | |||
| 17 | 18 | ||
| 18 | virtual bool canCreate() const = 0; | 19 | virtual bool canCreate() const = 0; |
| 19 | 20 | ||
| 20 | virtual TLSContext* createTLSContext() = 0; | 21 | virtual TLSContext* createTLSContext(const TLSOptions& tlsOptions) = 0; |
| 21 | virtual void setCheckCertificateRevocation(bool b) = 0; | 22 | virtual void setCheckCertificateRevocation(bool b) = 0; |
| 22 | }; | 23 | }; |
| 23 | } | 24 | } |
diff --git a/Swiften/TLS/TLSOptions.h b/Swiften/TLS/TLSOptions.h new file mode 100644 index 0000000..ca84829 --- /dev/null +++ b/Swiften/TLS/TLSOptions.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2015 Isode Limited. | ||
| 3 | * All rights reserved. | ||
| 4 | * See the COPYING file for more information. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #pragma once | ||
| 8 | |||
| 9 | namespace Swift { | ||
| 10 | |||
| 11 | struct TLSOptions { | ||
| 12 | TLSOptions() : schannelTLS1_0Workaround(false) { | ||
| 13 | |||
| 14 | } | ||
| 15 | |||
| 16 | /** | ||
| 17 | * A bug in the Windows SChannel TLS stack, combined with | ||
| 18 | * overly-restrictive server stacks means it's sometimes necessary to | ||
| 19 | * not use TLS>1.0. This option has no effect unless compiled on | ||
| 20 | * Windows against SChannel (OpenSSL users are unaffected). | ||
| 21 | */ | ||
| 22 | bool schannelTLS1_0Workaround; | ||
| 23 | |||
| 24 | }; | ||
| 25 | } | ||
Swift