diff options
Diffstat (limited to 'Swift/Controllers')
-rw-r--r-- | Swift/Controllers/ConnectionSettings.h | 40 | ||||
-rw-r--r-- | Swift/Controllers/MainController.cpp | 103 | ||||
-rw-r--r-- | Swift/Controllers/MainController.h | 5 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/LoginWindow.h | 5 |
4 files changed, 144 insertions, 9 deletions
diff --git a/Swift/Controllers/ConnectionSettings.h b/Swift/Controllers/ConnectionSettings.h new file mode 100644 index 0000000..c02c5d4 --- /dev/null +++ b/Swift/Controllers/ConnectionSettings.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> + +struct ConnectionSettings { + enum Method { + Automatic, + Manual, + BOSH + }; + enum ProxyType { + None, + System, + SOCKS5, + HTTPConnect + }; + + Method method; + struct { + bool useManualServer; + std::string manualServerHostname; + int manualServerPort; + ProxyType proxyType; + bool useManualProxy; + std::string manualProxyHostname; + int manualProxyPort; + } manualSettings; + struct { + std::string boshURI; + bool useManualProxy; + std::string manualProxyHostname; + int manualProxyPort; + } boshSettings; +}; diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 2c02ba8..f3a0226 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -15,6 +15,8 @@ #include <Swiften/Base/format.h> #include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/String.h> +#include <Swiften/StringCodecs/Base64.h> #include <Swift/Controllers/Intl.h> #include <Swift/Controllers/UIInterfaces/UIFactory.h> #include "Swiften/Network/TimerFactory.h" @@ -145,6 +147,7 @@ MainController::MainController( bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY); std::string cachedPassword; std::string cachedCertificate; + ClientOptions cachedOptions; bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); if (!eagle) { foreach (std::string profile, settings->getAvailableProfiles()) { @@ -152,10 +155,12 @@ MainController::MainController( std::string password = profileSettings.getStringSetting("pass"); std::string certificate = profileSettings.getStringSetting("certificate"); std::string jid = profileSettings.getStringSetting("jid"); - loginWindow_->addAvailableAccount(jid, password, certificate); + ClientOptions clientOptions = parseClientOptions(profileSettings.getStringSetting("options")); + loginWindow_->addAvailableAccount(jid, password, certificate, clientOptions); if (jid == selectedLoginJID) { cachedPassword = password; cachedCertificate = certificate; + cachedOptions = clientOptions; } } loginWindow_->selectUser(selectedLoginJID); @@ -163,7 +168,7 @@ MainController::MainController( } - loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6)); + loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6, _7)); loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1)); loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this)); loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this)); @@ -180,7 +185,7 @@ MainController::MainController( if (loginAutomatically) { profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_); /* FIXME: deal with autologin with a cert*/ - handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), true, true); + handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), cachedOptions, true, true); } else { profileSettings_ = NULL; } @@ -445,7 +450,7 @@ void MainController::handleShowCertificateRequest() { rosterController_->getWindow()->openCertificateDialog(chain); } -void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificatePath, CertificateWithKey::ref certificate, bool remember, bool loginAutomatically) { +void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically) { jid_ = JID(username); if (!jid_.isValid() || jid_.getNode().empty()) { loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'")); @@ -458,13 +463,15 @@ void MainController::handleLoginRequest(const std::string &username, const std:: profileSettings_->storeString("jid", username); profileSettings_->storeString("certificate", certificatePath); profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : ""); + profileSettings_->storeString("options", serializeClientOptions(options)); settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username); settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically); - loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate")); + loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"), options); } password_ = password; certificate_ = certificate; + clientOptions_ = options; performLoginFromCachedCredentials(); } } @@ -524,7 +531,7 @@ void MainController::performLoginFromCachedCredentials() { if (rosterController_) { rosterController_->getWindow()->setConnecting(); } - ClientOptions clientOptions; + ClientOptions clientOptions = clientOptions_; bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); clientOptions.forgetPassword = eagle; clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : ClientOptions::UseTLSWhenAvailable; @@ -731,4 +738,88 @@ void MainController::handleQuitRequest() { } } +#define SERIALIZE_BOOL(option) result += options.option ? "1" : "0"; result += ","; +#define SERIALIZE_INT(option) result += boost::lexical_cast<std::string>(options.option); result += ","; +#define SERIALIZE_STRING(option) result += Base64::encode(createByteArray(options.option)); result += ","; +#define SERIALIZE_SAFE_STRING(option) result += safeByteArrayToString(Base64::encode(options.option)); result += ","; +#define SERIALIZE_URL(option) SERIALIZE_STRING(option.getScheme()) SERIALIZE_STRING(option.getHost()) SERIALIZE_INT(option.getPort()) SERIALIZE_STRING(option.getPath()) + +std::string MainController::serializeClientOptions(const ClientOptions& options) { + std::string result; + SERIALIZE_BOOL(useStreamCompression); + switch (options.useTLS) { + case ClientOptions::NeverUseTLS: result += "1";break; + case ClientOptions::UseTLSWhenAvailable: result += "2";break; + case ClientOptions::RequireTLS: result += "3";break; + } + result += ","; + SERIALIZE_BOOL(allowPLAINWithoutTLS); + SERIALIZE_BOOL(useStreamResumption); + SERIALIZE_BOOL(useAcks); + SERIALIZE_STRING(manualHostname); + SERIALIZE_INT(manualPort); + switch (options.proxyType) { + case ClientOptions::NoProxy: result += "1";break; + case ClientOptions::SystemConfiguredProxy: result += "2";break; + case ClientOptions::SOCKS5Proxy: result += "3";break; + case ClientOptions::HTTPConnectProxy: result += "4";break; + } + result += ","; + SERIALIZE_STRING(manualProxyHostname); + SERIALIZE_INT(manualProxyPort); + SERIALIZE_URL(boshURL); + SERIALIZE_URL(boshHTTPConnectProxyURL); + SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID); + SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); + return result; +} + +#define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;} +#define PARSE_INT_RAW CHECK_PARSE_LENGTH intVal = 0; try {intVal = boost::lexical_cast<int>(segments[i]);} catch(const boost::bad_lexical_cast&) {};i++; +#define PARSE_STRING_RAW CHECK_PARSE_LENGTH stringVal = byteArrayToString(Base64::decode(segments[i]));i++; + +#define PARSE_BOOL(option) PARSE_INT_RAW; result.option = (intVal == 1); +#define PARSE_INT(option) PARSE_INT_RAW; result.option = intVal; +#define PARSE_STRING(option) PARSE_STRING_RAW; result.option = stringVal; +#define PARSE_SAFE_STRING(option) PARSE_STRING_RAW; result.option = SafeString(createSafeByteArray(stringVal)); +#define PARSE_URL(option) {PARSE_STRING_RAW; std::string scheme = stringVal; PARSE_STRING_RAW; std::string host = stringVal; PARSE_INT_RAW; int port = intVal; PARSE_STRING_RAW; std::string path = stringVal; result.option = !scheme.empty() && !host.empty() ? URL(scheme, host, port, path) : URL();} + + +ClientOptions MainController::parseClientOptions(const std::string& optionString) { + ClientOptions result; + size_t i = 0; + int intVal = 0; + std::string stringVal; + std::vector<std::string> segments = String::split(optionString, ','); + + PARSE_BOOL(useStreamCompression); + PARSE_INT_RAW; + switch (intVal) { + case 1: result.useTLS = ClientOptions::NeverUseTLS;break; + case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable;break; + case 3: result.useTLS = ClientOptions::RequireTLS;break; + default:; + } + PARSE_BOOL(allowPLAINWithoutTLS); + PARSE_BOOL(useStreamResumption); + PARSE_BOOL(useAcks); + PARSE_STRING(manualHostname); + PARSE_INT(manualPort); + PARSE_INT_RAW; + switch (intVal) { + case 1: result.proxyType = ClientOptions::NoProxy;break; + case 2: result.proxyType = ClientOptions::SystemConfiguredProxy;break; + case 3: result.proxyType = ClientOptions::SOCKS5Proxy;break; + case 4: result.proxyType = ClientOptions::HTTPConnectProxy;break; + } + PARSE_STRING(manualProxyHostname); + PARSE_INT(manualProxyPort); + PARSE_URL(boshURL); + PARSE_URL(boshHTTPConnectProxyURL); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); + + return result; +} + } diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index 8f04f6c..6f7482e 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -93,7 +93,7 @@ namespace Swift { private: void resetClient(); void handleConnected(); - void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, bool remember, bool loginAutomatically); + void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically); void handleCancelLoginRequest(); void handleQuitRequest(); void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText); @@ -118,6 +118,8 @@ namespace Swift { void handleNotificationClicked(const JID& jid); void handleForceQuit(); void purgeCachedCredentials(); + std::string serializeClientOptions(const ClientOptions& options); + ClientOptions parseClientOptions(const std::string& optionString); private: EventLoop* eventLoop_; @@ -159,6 +161,7 @@ namespace Swift { std::string vCardPhotoHash_; std::string password_; CertificateWithKey::ref certificate_; + ClientOptions clientOptions_; boost::shared_ptr<ErrorEvent> lastDisconnectError_; bool useDelayForLatency_; UserSearchController* userSearchControllerChat_; diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h index f1c2ce1..dbc77c4 100644 --- a/Swift/Controllers/UIInterfaces/LoginWindow.h +++ b/Swift/Controllers/UIInterfaces/LoginWindow.h @@ -12,6 +12,7 @@ #include <string> #include <Swiften/TLS/Certificate.h> #include <Swiften/TLS/CertificateWithKey.h> +#include <Swiften/Client/ClientOptions.h> namespace Swift { class MainWindow; @@ -24,10 +25,10 @@ namespace Swift { virtual void setShowNotificationToggle(bool) = 0; virtual void setMessage(const std::string&) = 0; virtual void setIsLoggingIn(bool loggingIn) = 0; - virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate) = 0; + virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) = 0; virtual void removeAvailableAccount(const std::string& jid) = 0; /** The certificate is what is used for login, the certificatePath is used for remembering paths to populate the loginwindow with*/ - boost::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, bool /* remember password*/, bool /* login automatically */)> onLoginRequest; + boost::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, const ClientOptions& /*options*/, bool /* remember password*/, bool /* login automatically */)> onLoginRequest; virtual void setLoginAutomatically(bool loginAutomatically) = 0; virtual void quit() = 0; /** Blocking request whether a cert should be permanently trusted.*/ |