boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) { NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.getLeaseInSeconds(), mapping.getPublicPort(), mapping.getLocalPort()) < 0) { SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl; return boost::optional<NATPortMapping>(); } int r = 0; natpmpresp_t response; do { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(p->natpmp.s, &fds); getnatpmprequesttimeout(&p->natpmp, &timeout); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); r = readnatpmpresponseorretry(&p->natpmp, &response); } while(r == NATPMP_TRYAGAIN); if (r == 0) { NATPortMapping result(response.pnu.newportmapping.privateport, response.pnu.newportmapping.mappedpublicport, NATPortMapping::TCP, response.pnu.newportmapping.lifetime); return result; } else { SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl; return boost::optional<NATPortMapping>(); } }
boost::optional<HostAddress> NATPMPInterface::getPublicIP() { if (sendpublicaddressrequest(&p->natpmp) < 0) { SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl; return boost::optional<HostAddress>(); } int r = 0; natpmpresp_t response; do { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(p->natpmp.s, &fds); getnatpmprequesttimeout(&p->natpmp, &timeout); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); r = readnatpmpresponseorretry(&p->natpmp, &response); } while (r == NATPMP_TRYAGAIN); if (r == 0) { return boost::optional<HostAddress>(HostAddress(reinterpret_cast<const unsigned char*>(&(response.pnu.publicaddress.addr)), 4)); } else { SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl; return boost::optional<HostAddress>(); } }
bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) { if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.getLocalPort()) < 0) { SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl; return false; } int r = 0; natpmpresp_t response; do { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(p->natpmp.s, &fds); getnatpmprequesttimeout(&p->natpmp, &timeout); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); r = readnatpmpresponseorretry(&p->natpmp, &response); } while(r == NATPMP_TRYAGAIN); if (r == 0) { return true; } else { SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl; return false; } }
virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, IBB::ref ibb) { if (from == session->from && ibb->getStreamID() == session->id) { if (ibb->getAction() == IBB::Data) { if (sequenceNumber == ibb->getSequenceNumber()) { session->onDataReceived(ibb->getData()); receivedSize += ibb->getData().size(); sequenceNumber++; sendResponse(from, id, IBB::ref()); if (receivedSize >= session->size) { if (receivedSize > session->size) { std::cerr << "Warning: Received more data than expected" << std::endl; } session->finish(boost::optional<FileTransferError>()); } } else { SWIFT_LOG(warning) << "Received data out of order" << std::endl; sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); session->finish(FileTransferError(FileTransferError::ClosedError)); } } else if (ibb->getAction() == IBB::Open) { SWIFT_LOG(debug) << "IBB open received" << std::endl; sendResponse(from, id, IBB::ref()); } else if (ibb->getAction() == IBB::Close) { SWIFT_LOG(debug) << "IBB close received" << std::endl; sendResponse(from, id, IBB::ref()); session->finish(FileTransferError(FileTransferError::ClosedError)); } return true; } SWIFT_LOG(debug) << "wrong from/sessionID: " << from << " == " << session->from << " / " <<ibb->getStreamID() << " == " << session->id << std::endl; return false; }
NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() const { #ifdef HAVE_LIBMINIUPNPC if (boost::logic::indeterminate(miniUPnPSupported)) { miniUPnPInterface = new MiniUPnPInterface(); miniUPnPSupported = miniUPnPInterface->isAvailable(); } SWIFT_LOG(debug) << "UPnP NAT traversal supported: " << miniUPnPSupported << std::endl; if (miniUPnPSupported) { return miniUPnPInterface; } #endif #ifdef HAVE_LIBNATPMP if (boost::logic::indeterminate(natPMPSupported)) { natPMPInterface = new NATPMPInterface(); natPMPSupported = natPMPInterface->isAvailable(); } SWIFT_LOG(debug) << "NAT-PMP NAT traversal supported: " << natPMPSupported << std::endl; if (natPMPSupported) { return natPMPInterface; } #endif return nullNATTraversalInterface; }
void CoreClient::forceReset() { if (connector_) { SWIFT_LOG(warning) << "Client not disconnected properly: Connector still active" << std::endl; resetConnector(); } if (sessionStream_ || connection_) { SWIFT_LOG(warning) << "Client not disconnected properly: Session still active" << std::endl; resetSession(); } }
DWORD WindowsServicePrincipalName::dsMakeSpn(DWORD* length, wchar_t* value) { DWORD status; #ifdef UNICODE SWIFT_LOG(debug) << "UNICODE is defined" << std::endl; #else SWIFT_LOG(debug) << "UNICODE is not defined" << std::endl; #endif SWIFT_LOG(debug) << "serviceClass_: " << convertWStringToString(serviceClass_.c_str()) << std::endl; SWIFT_LOG(debug) << "serviceName_: " << convertWStringToString(serviceName_.c_str()) << std::endl; SWIFT_LOG(debug) << "instanceName_: " << convertWStringToString(instanceName_.c_str()) << std::endl; SWIFT_LOG(debug) << "referrer_: " << convertWStringToString(referrer_.c_str()) << std::endl; SWIFT_LOG(debug) << "instancePort_: " << instancePort_ << std::endl; SWIFT_LOG(debug) << "length: " << *length << std::endl; /* Call the Unicode function because that is recommended: https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407%28v=vs.85%29.aspx */ status = DsMakeSpnW( serviceClass_.c_str(), serviceName_.c_str(), instanceName_.empty() ? NULL : instanceName_.c_str(), instancePort_, referrer_.empty() ? NULL : referrer_.c_str(), length, value); if (status != ERROR_SUCCESS) { boost::system::error_code errorCode(status, boost::system::system_category()); SWIFT_LOG(debug) << std::hex << "status: 0x" << status << ": " << errorCode.message() << std::endl; } return status; }
void WindowsGSSAPIClientAuthenticator::buildSecurityContext(const boost::optional<ByteArray>& inputToken) { ULONG contextSupported; /* An XMPP server may not support Kerberos encryption or SASL security layer so not requesting integrity or confidentiality */ errorCode_ = initializeSecurityContext(inputToken, servicePrincipalNameString_, &credentialsHandle_, haveContextHandle_, &contextHandle_, ISC_REQ_MUTUAL_AUTH, &contextSupported, &haveCompleteContext_, response_); if (isError()) { return; } haveContextHandle_ = true; if (!haveCompleteContext_) { return; } if (contextSupported & ISC_REQ_MUTUAL_AUTH == 0) { SWIFT_LOG(debug) << "Mutual authentication not supported" << std::endl; error_ = true; return; } errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_SIZES, &sizes_); if (isError()) { return; } /* Commenting this out as it gives the error code 0x80090302: The function requested is not supported errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_STREAM_SIZES, &streamSizes_); if (isError()) { return; }*/ SecPkgContext_Names names; errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_NAMES, &names); if (isError()) { return; } userName_ = names.sUserName; SWIFT_LOG(debug) << "User name: " << userName_ << std::endl; std::size_t position = userName_.find("\\"); clientName_ = userName_.substr(position + 1); SWIFT_LOG(debug) << "Client name: " << clientName_ << std::endl; serverName_ = userName_.substr(0, position); SWIFT_LOG(debug) << "Server name: " << serverName_ << std::endl; freeContextBuffer(names.sUserName); step_ = SecurityLayerNegotiation; }
boost::optional<std::string> CombinedAvatarProvider::getCombinedAvatarAndCache(const JID& jid) const { SWIFT_LOG(debug) << "JID: " << jid << std::endl; boost::optional<std::string> hash; for (size_t i = 0; i < providers.size() && !hash; ++i) { hash = providers[i]->getAvatarHash(jid); SWIFT_LOG(debug) << "Provider " << providers[i] << ": " << (hash ? hash.get() : "NULL") << std::endl; } if (hash) { avatars[jid] = *hash; } else { avatars[jid] = ""; } return hash; }
void Connector::tryConnect(const HostAddressPort& target) { assert(!currentConnection); SWIFT_LOG(debug) << "Trying to connect to " << target.getAddress().toString() << ":" << target.getPort() << std::endl; currentConnection = connectionFactory->createConnection(); currentConnection->onConnectFinished.connect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1)); currentConnection->connect(target); }
void ClientSessionStanzaChannel::send(std::shared_ptr<Stanza> stanza) { if (!isAvailable()) { SWIFT_LOG(warning) << "Client: Trying to send a stanza while disconnected." << std::endl; return; } session->sendStanza(stanza); }
QString QtScaledAvatarCache::getScaledAvatarPath(const QString& path) { QFileInfo avatarFile(path); if (avatarFile.exists()) { if (!avatarFile.dir().exists(QString::number(size))) { if (!avatarFile.dir().mkdir(QString::number(size))) { return path; } } QDir targetDir(avatarFile.dir().absoluteFilePath(QString::number(size))); QString targetFile = targetDir.absoluteFilePath(avatarFile.baseName()); if (!QFileInfo(targetFile).exists()) { QPixmap avatarPixmap; if (avatarPixmap.load(path)) { QPixmap maskedAvatar(avatarPixmap.size()); maskedAvatar.fill(QColor(0, 0, 0, 0)); QPainter maskPainter(&maskedAvatar); maskPainter.setBrush(Qt::black); maskPainter.drawRoundedRect(maskedAvatar.rect(), 25.0, 25.0, Qt::RelativeSize); maskPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); maskPainter.drawPixmap(0, 0, avatarPixmap); maskPainter.end(); if (!maskedAvatar.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(targetFile, "PNG")) { return path; } } else { SWIFT_LOG(debug) << "Failed to load " << Q2PSTRING(path) << std::endl; } } return targetFile; } else { return path; } }
void LocalJingleTransportCandidateGenerator::handleS5BServerInitialized(bool success) { if (s5bServerResourceUser_) { s5bServerResourceUser_->onSuccessfulInitialized.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleS5BServerInitialized, this, _1)); } triedServerInit_ = true; if (success) { if (options_.isAssistedAllowed()) { // try to setup port forwarding s5bServerPortForwardingUser_ = s5bServerManager->aquirePortForwardingUser(); s5bServerPortForwardingUser_->onSetup.connect(boost::bind(&LocalJingleTransportCandidateGenerator::handlePortForwardingSetup, this, _1)); if (s5bServerPortForwardingUser_->isForwardingSetup()) { handlePortForwardingSetup(true); } } } else { SWIFT_LOG(warning) << "Unable to start SOCKS5 server" << std::endl; if (s5bServerResourceUser_) { s5bServerResourceUser_->onSuccessfulInitialized.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleS5BServerInitialized, this, _1)); } s5bServerResourceUser_.reset(); handlePortForwardingSetup(false); } checkS5BCandidatesReady(); }
void Connector::start() { SWIFT_LOG(debug) << "Starting connector for " << hostname << std::endl; assert(!currentConnection); assert(!serviceQuery); assert(!timer); queriedAllServices = false; auto hostAddress = HostAddress::fromString(hostname); if (timeoutMilliseconds > 0) { timer = timerFactory->createTimer(timeoutMilliseconds); timer->onTick.connect(boost::bind(&Connector::handleTimeout, shared_from_this())); } if (serviceLookupPrefix) { serviceQuery = resolver->createServiceQuery(*serviceLookupPrefix, hostname); serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1)); serviceQuery->run(); } else if (hostAddress) { // hostname is already a valid address; skip name lookup. foundSomeDNS = true; addressQueryResults.push_back(hostAddress.get()); tryNextAddress(); } else { queryAddress(hostname); } }
bool IncomingFileTransferManager::handleIncomingJingleSession( JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient) { if (JingleContentPayload::ref content = Jingle::getContentWithDescription<JingleFileTransferDescription>(contents)) { if (content->getTransport<JingleS5BTransportPayload>() || content->getTransport<JingleIBBTransportPayload>()) { JingleFileTransferDescription::ref description = content->getDescription<JingleFileTransferDescription>(); if (description) { IncomingJingleFileTransfer::ref transfer = std::make_shared<IncomingJingleFileTransfer>( recipient, session, content, transporterFactory, timerFactory, crypto); onIncomingFileTransfer(transfer); } else { SWIFT_LOG(warning) << "Received a file-transfer request with no file description."; session->sendTerminate(JinglePayload::Reason::FailedApplication); } } else { session->sendTerminate(JinglePayload::Reason::UnsupportedTransports); } return true; } else { return false; } }
void Connector::tryNextServiceOrFallback() { if (queriedAllServices) { SWIFT_LOG(debug) << "Queried all services" << std::endl; finish(boost::shared_ptr<Connection>()); } else if (serviceQueryResults.empty()) { SWIFT_LOG(debug) << "Falling back on A resolution" << std::endl; // Fall back on simple address resolving queriedAllServices = true; queryAddress(hostname); } else { SWIFT_LOG(debug) << "Querying next address" << std::endl; queryAddress(serviceQueryResults.front().hostname); } }
std::string WindowsServicePrincipalName::toString() { DWORD length = 512; DWORD status = ERROR_BUFFER_OVERFLOW; bool firstCall = true; std::string str; while (status == ERROR_BUFFER_OVERFLOW) { std::vector<wchar_t> value(length); /* length after this call will contain the required length if current length is not enough - so the next call should succeed */ status = dsMakeSpn(&length, vecptr(value)); if (status == ERROR_SUCCESS) { str = convertWStringToString(std::wstring(vecptr(value), length-1 /* trailing 0 character */)); break; } if ((firstCall == false) || (status != ERROR_BUFFER_OVERFLOW)) { std::stringstream errorString; boost::system::error_code errorCode(status, boost::system::system_category()); errorString << "Error creating Service Principal Name: status: 0x" << std::hex << status << ": " << errorCode.message(); /* Any other error will be a programming error */ throw std::runtime_error(errorString.str()); } firstCall = false; } SWIFT_LOG(debug) << "SPN: " << str << std::endl; return str; }
void SOCKS5BytestreamClientSession::handleConnectFinished(bool error) { connectFinishedConnection.disconnect(); if (error) { SWIFT_LOG(debug) << "Failed to connect via TCP to " << addressPort.toString() << "." << std::endl; finish(true); } else { SWIFT_LOG(debug) << "Successfully connected via TCP" << addressPort.toString() << "." << std::endl; disconnectedConnection = connection->onDisconnected.connect( boost::bind(&SOCKS5BytestreamClientSession::handleDisconnected, this, _1)); dataReadConnection = connection->onDataRead.connect( boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); weFailedTimeout->stop(); weFailedTimeout->start(); process(); } }
void SOCKS5BytestreamClientSession::start() { assert(state == Initial); SWIFT_LOG(debug) << "Trying to connect via TCP to " << addressPort.toString() << "." << std::endl; weFailedTimeout->start(); connectFinishedConnection = connection->onConnectFinished.connect( boost::bind(&SOCKS5BytestreamClientSession::handleConnectFinished, this, _1)); connection->connect(addressPort); }
bool BOSHConnection::setClientCertificate(CertificateWithKey::ref cert) { if (tlsLayer_) { SWIFT_LOG(debug) << "set client certificate" << std::endl; return tlsLayer_->setClientCertificate(cert); } else { return false; } }
void Connector::handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) { SWIFT_LOG(debug) << result.size() << " SRV result(s)" << std::endl; serviceQueryResults = std::deque<DomainNameServiceQuery::Result>(result.begin(), result.end()); serviceQuery.reset(); if (!serviceQueryResults.empty()) { foundSomeDNS = true; } tryNextServiceOrFallback(); }
void BoostConnection::handleConnectFinished(const boost::system::error_code& error) { SWIFT_LOG(debug) << "Connect finished: " << error << std::endl; if (!error) { eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), false), shared_from_this()); doRead(); } else if (error != boost::asio::error::operation_aborted) { eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), true), shared_from_this()); } }
void IBBReceiveSession::stop() { SWIFT_LOG(debug) << "receive session stopped" << std::endl; responder->stop(); if (active) { if (router->isAvailable()) { IBBRequest::create(to, from, IBB::createIBBClose(id), router)->send(); } finish(boost::optional<FileTransferError>()); } }
void SOCKS5BytestreamClientSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) { SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data->size() << std::endl; if (state != Reading) { append(unprocessedData, *data); process(); } else { writeBytestream->write(createByteArray(vecptr(*data), data->size())); //onBytesReceived(data->size()); } }
void SOCKS5BytestreamClientSession::startSending(boost::shared_ptr<ReadBytestream> readStream) { if (state == Ready) { state = Writing; readBytestream = readStream; dataWrittenConnection = connection->onDataWritten.connect( boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); sendData(); } else { SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; } }
void SOCKS5BytestreamClientSession::startReceiving(boost::shared_ptr<WriteBytestream> writeStream) { if (state == Ready) { state = Reading; writeBytestream = writeStream; writeBytestream->write(unprocessedData); //onBytesReceived(unprocessedData.size()); unprocessedData.clear(); } else { SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; } }
void SOCKS5BytestreamClientSession::authenticate() { SWIFT_LOG(debug) << std::endl; SafeByteArray header = createSafeByteArray("\x05\x01\x00\x03", 4); SafeByteArray message = header; append(message, createSafeByteArray(boost::numeric_cast<char>(destination.size()))); authenticateAddress = createByteArray(destination); append(message, authenticateAddress); append(message, createSafeByteArray("\x00\x00", 2)); // 2 byte for port connection->write(message); state = Authenticating; }
CoreComponent::~CoreComponent() { if (session_ || connection_) { SWIFT_LOG(warning) << "Component not disconnected properly" << std::endl; } delete iqRouter_; stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&CoreComponent::handleStanzaChannelAvailableChanged, this, _1)); stanzaChannel_->onMessageReceived.disconnect(boost::ref(onMessageReceived)); stanzaChannel_->onPresenceReceived.disconnect(boost::ref(onPresenceReceived)); delete stanzaChannel_; }
void BOSHConnection::write(const SafeByteArray& data, bool streamRestart, bool terminate) { assert(connectionReady_); assert(!sid_.empty()); SafeByteArray safeHeader = createHTTPRequest(data, streamRestart, terminate, rid_, sid_, boshURL_).first; onBOSHDataWritten(safeHeader); writeData(safeHeader); pending_ = true; SWIFT_LOG(debug) << "write data: " << safeByteArrayToString(safeHeader) << std::endl; }
void SOCKS5BytestreamClientSession::stop() { SWIFT_LOG(debug) << std::endl; if (state < Ready) { weFailedTimeout->stop(); } if (state == Finished) { return; } closeConnection(); readBytestream.reset(); state = Finished; }