summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Network/BOSHConnection.cpp')
-rw-r--r--Swiften/Network/BOSHConnection.cpp104
1 files changed, 98 insertions, 6 deletions
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp
index 298b015..9a836cb 100644
--- a/Swiften/Network/BOSHConnection.cpp
+++ b/Swiften/Network/BOSHConnection.cpp
@@ -21,25 +21,35 @@
#include <Swiften/Base/ByteArray.h>
#include <Swiften/Base/Concat.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Parser/BOSHBodyExtractor.h>
+#include <Swiften/StreamStack/DummyStreamLayer.h>
+#include <Swiften/StreamStack/TLSLayer.h>
+#include <Swiften/TLS/TLSContext.h>
+#include <Swiften/TLS/TLSOptions.h>
namespace Swift {
-BOSHConnection::BOSHConnection(const URL& boshURL, Connector::ref connector, XMLParserFactory* parserFactory)
+BOSHConnection::BOSHConnection(const URL& boshURL, Connector::ref connector, XMLParserFactory* parserFactory, TLSContextFactory* tlsContextFactory, const TLSOptions& tlsOptions)
: boshURL_(boshURL),
connector_(connector),
parserFactory_(parserFactory),
sid_(),
waitingForStartResponse_(false),
rid_(~0ULL),
pending_(false),
connectionReady_(false)
{
+ if (boshURL_.getScheme() == "https") {
+ tlsLayer_ = boost::make_shared<TLSLayer>(tlsContextFactory, tlsOptions);
+ // The following dummyLayer_ is needed as the TLSLayer will pass the decrypted data to its parent layer.
+ // The dummyLayer_ will serve as the parent layer.
+ dummyLayer_ = boost::make_shared<DummyStreamLayer>(tlsLayer_.get());
+ }
}
BOSHConnection::~BOSHConnection() {
cancelConnector();
if (connection_) {
connection_->onDataRead.disconnect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
@@ -58,12 +68,45 @@ void BOSHConnection::cancelConnector() {
connector_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectFinished, shared_from_this(), _1));
connector_->stop();
connector_.reset();
}
}
+void BOSHConnection::handleTLSConnected() {
+ SWIFT_LOG(debug) << std::endl;
+ onConnectFinished(false);
+}
+
+void BOSHConnection::handleTLSApplicationDataRead(const SafeByteArray& data) {
+ SWIFT_LOG(debug) << std::endl;
+ handleDataRead(boost::make_shared<SafeByteArray>(data));
+}
+
+void BOSHConnection::handleTLSNetowrkDataWriteRequest(const SafeByteArray& data) {
+ SWIFT_LOG(debug) << std::endl;
+ connection_->write(data);
+}
+
+void BOSHConnection::handleRawDataRead(boost::shared_ptr<SafeByteArray> data) {
+ SWIFT_LOG(debug) << std::endl;
+ tlsLayer_->handleDataRead(*data.get());
+}
+
+void BOSHConnection::handleTLSError(boost::shared_ptr<TLSError> error) {
+
+}
+
+void BOSHConnection::writeData(const SafeByteArray& data) {
+ if (tlsLayer_) {
+ tlsLayer_->writeData(data);
+ }
+ else {
+ connection_->write(data);
+ }
+}
+
void BOSHConnection::disconnect() {
if (connection_) {
connection_->disconnect();
sid_ = "";
}
else {
@@ -73,12 +116,46 @@ void BOSHConnection::disconnect() {
}
void BOSHConnection::restartStream() {
write(createSafeByteArray(""), true, false);
}
+bool BOSHConnection::setClientCertificate(CertificateWithKey::ref cert) {
+ if (tlsLayer_) {
+ SWIFT_LOG(debug) << "set client certificate" << std::endl;
+ return tlsLayer_->setClientCertificate(cert);
+ }
+ else {
+ return false;
+ }
+}
+
+Certificate::ref BOSHConnection::getPeerCertificate() const {
+ Certificate::ref peerCertificate;
+ if (tlsLayer_) {
+ peerCertificate = tlsLayer_->getPeerCertificate();
+ }
+ return peerCertificate;
+}
+
+std::vector<Certificate::ref> BOSHConnection::getPeerCertificateChain() const {
+ std::vector<Certificate::ref> peerCertificateChain;
+ if (tlsLayer_) {
+ peerCertificateChain = tlsLayer_->getPeerCertificateChain();
+ }
+ return peerCertificateChain;
+}
+
+CertificateVerificationError::ref BOSHConnection::getPeerCertificateVerificationError() const {
+ CertificateVerificationError::ref verificationError;
+ if (tlsLayer_) {
+ verificationError = tlsLayer_->getPeerCertificateVerificationError();
+ }
+ return verificationError;
+}
+
void BOSHConnection::terminateStream() {
write(createSafeByteArray(""), false, true);
}
void BOSHConnection::write(const SafeByteArray& data) {
@@ -126,27 +203,42 @@ void BOSHConnection::write(const SafeByteArray& data, bool streamRestart, bool t
assert(connectionReady_);
assert(!sid_.empty());
SafeByteArray safeHeader = createHTTPRequest(data, streamRestart, terminate, rid_, sid_, boshURL_).first;
onBOSHDataWritten(safeHeader);
- connection_->write(safeHeader);
+ writeData(safeHeader);
pending_ = true;
SWIFT_LOG(debug) << "write data: " << safeByteArrayToString(safeHeader) << std::endl;
}
void BOSHConnection::handleConnectFinished(Connection::ref connection) {
cancelConnector();
connectionReady_ = !!connection;
if (connectionReady_) {
connection_ = connection;
- connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ if (tlsLayer_) {
+ connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleRawDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+
+ tlsLayer_->getContext()->onDataForNetwork.connect(boost::bind(&BOSHConnection::handleTLSNetowrkDataWriteRequest, shared_from_this(), _1));
+ tlsLayer_->getContext()->onDataForApplication.connect(boost::bind(&BOSHConnection::handleTLSApplicationDataRead, shared_from_this(), _1));
+ tlsLayer_->onConnected.connect(boost::bind(&BOSHConnection::handleTLSConnected, shared_from_this()));
+ tlsLayer_->onError.connect(boost::bind(&BOSHConnection::handleTLSError, shared_from_this(), _1));
+ tlsLayer_->connect();
+ }
+ else {
+ connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ }
+ }
+
+ if (!connectionReady_ || !tlsLayer_) {
+ onConnectFinished(!connectionReady_);
}
- onConnectFinished(!connectionReady_);
}
void BOSHConnection::startStream(const std::string& to, unsigned long long rid) {
assert(connectionReady_);
// Session Creation Request
std::stringstream content;
@@ -177,13 +269,13 @@ void BOSHConnection::startStream(const std::string& to, unsigned long long rid)
<< "Content-Length: " << contentString.size() << "\r\n\r\n"
<< contentString;
waitingForStartResponse_ = true;
SafeByteArray safeHeader = createSafeByteArray(header.str());
onBOSHDataWritten(safeHeader);
- connection_->write(safeHeader);
+ writeData(safeHeader);
SWIFT_LOG(debug) << "write stream header: " << safeByteArrayToString(safeHeader) << std::endl;
}
void BOSHConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
onBOSHDataRead(*data);
buffer_ = concat(buffer_, *data);