summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/MainController.cpp94
-rw-r--r--Swift/Controllers/MainController.h5
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindow.h2
-rw-r--r--Swift/QtUI/QtLoginWindow.cpp13
-rw-r--r--Swift/QtUI/QtLoginWindow.h1
-rw-r--r--Swift/QtUI/QtSwift.cpp7
-rw-r--r--Swiften/Base/Algorithm.h1
-rw-r--r--Swiften/Client/ClientOptions.h12
-rw-r--r--Swiften/Client/CoreClient.cpp24
-rw-r--r--Swiften/Client/CoreClient.h1
-rw-r--r--Swiften/SASL/ClientAuthenticator.cpp5
11 files changed, 129 insertions, 36 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 6cc862e..1e388d5 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <Swiften/Base/format.h>
+#include <Swiften/Base/Algorithm.h>
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/UIInterfaces/UIFactory.h>
#include "Swiften/Network/TimerFactory.h"
@@ -86,7 +87,8 @@ MainController::MainController(
Dock* dock,
Notifier* notifier,
URIHandler* uriHandler,
- bool useDelayForLatency) :
+ bool useDelayForLatency,
+ bool eagleMode) :
eventLoop_(eventLoop),
networkFactories_(networkFactories),
uiFactory_(uiFactories),
@@ -96,7 +98,8 @@ MainController::MainController(
settings_(settings),
uriHandler_(uriHandler),
loginWindow_(NULL) ,
- useDelayForLatency_(useDelayForLatency) {
+ useDelayForLatency_(useDelayForLatency),
+ eagleMode_(eagleMode) {
storages_ = NULL;
certificateStorage_ = NULL;
statusTracker_ = NULL;
@@ -130,19 +133,25 @@ MainController::MainController(
bool loginAutomatically = settings_->getBoolSetting("loginAutomatically", false);
std::string cachedPassword;
std::string cachedCertificate;
- foreach (std::string profile, settings->getAvailableProfiles()) {
- ProfileSettingsProvider profileSettings(profile, settings);
- std::string password = profileSettings.getStringSetting("pass");
- std::string certificate = profileSettings.getStringSetting("certificate");
- std::string jid = profileSettings.getStringSetting("jid");
- loginWindow_->addAvailableAccount(jid, password, certificate);
- if (jid == selectedLoginJID) {
- cachedPassword = password;
- cachedCertificate = certificate;
+ if (!eagleMode_) {
+ foreach (std::string profile, settings->getAvailableProfiles()) {
+ ProfileSettingsProvider profileSettings(profile, settings);
+ std::string password = eagleMode ? "" : profileSettings.getStringSetting("pass");
+ std::string certificate = profileSettings.getStringSetting("certificate");
+ std::string jid = profileSettings.getStringSetting("jid");
+ loginWindow_->addAvailableAccount(jid, password, certificate);
+ if (jid == selectedLoginJID) {
+ cachedPassword = password;
+ cachedCertificate = certificate;
+ }
}
+ loginWindow_->selectUser(selectedLoginJID);
+ loginWindow_->setLoginAutomatically(loginAutomatically);
+ } else {
+ loginWindow_->setRememberingAllowed(false);
}
- loginWindow_->selectUser(selectedLoginJID);
- loginWindow_->setLoginAutomatically(loginAutomatically);
+
+
loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5));
loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1));
loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this));
@@ -166,6 +175,7 @@ MainController::MainController(
}
MainController::~MainController() {
+ purgeCachedCredentials();
//setManagersOffline();
eventController_->disconnectAll();
@@ -180,7 +190,12 @@ MainController::~MainController() {
delete uiEventStream_;
}
+void MainController::purgeCachedCredentials() {
+ safeClear(password_);
+}
+
void MainController::resetClient() {
+ purgeCachedCredentials();
resetCurrentError();
resetPendingReconnects();
vCardPhotoHash_.clear();
@@ -243,6 +258,9 @@ void MainController::handleConnected() {
loginWindow_->setIsLoggingIn(false);
resetCurrentError();
resetPendingReconnects();
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
bool freshLogin = rosterController_ == NULL;
myStatusLooksOnline_ = true;
if (freshLogin) {
@@ -370,12 +388,14 @@ void MainController::handleLoginRequest(const std::string &username, const std::
loginWindow_->setMessage("");
loginWindow_->setIsLoggingIn(true);
profileSettings_ = new ProfileSettingsProvider(username, settings_);
- profileSettings_->storeString("jid", username);
- profileSettings_->storeString("certificate", certificateFile);
- profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
- settings_->storeString("lastLoginJID", username);
- settings_->storeBool("loginAutomatically", loginAutomatically);
- loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"));
+ if (!eagleMode_) {
+ profileSettings_->storeString("jid", username);
+ profileSettings_->storeString("certificate", certificateFile);
+ profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
+ settings_->storeString("lastLoginJID", username);
+ settings_->storeBool("loginAutomatically", loginAutomatically);
+ loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"));
+ }
password_ = password;
certificateFile_ = certificateFile;
@@ -389,6 +409,10 @@ void MainController::handlePurgeSavedLoginRequest(const std::string& username) {
}
void MainController::performLoginFromCachedCredentials() {
+ if (eagleMode_ && password_.empty()) {
+ /* Then we can't try to login again. */
+ return;
+ }
/* If we logged in with a bare JID, and we have a full bound JID, re-login with the
* bound JID to try and keep dynamically assigned resources */
JID clientJID = jid_;
@@ -434,11 +458,15 @@ void MainController::performLoginFromCachedCredentials() {
if (rosterController_) {
rosterController_->getWindow()->setConnecting();
}
-
- client_->connect();
+ ClientOptions clientOptions;
+ clientOptions.forgetPassword = eagleMode_;
+ client_->connect(clientOptions);
}
void MainController::handleDisconnected(const boost::optional<ClientError>& error) {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
if (quitRequested_) {
resetClient();
loginWindow_->quit();
@@ -498,15 +526,19 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
loginWindow_->setIsLoggingIn(false);
} else {
logout();
- setReconnectTimer();
- if (lastDisconnectError_) {
- message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
- lastDisconnectError_->conclude();
+ if (eagleMode_) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message);
} else {
- message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
+ setReconnectTimer();
+ if (lastDisconnectError_) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
+ lastDisconnectError_->conclude();
+ } else {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
+ }
+ lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message));
+ eventController_->handleIncomingEvent(lastDisconnectError_);
}
- lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message));
- eventController_->handleIncomingEvent(lastDisconnectError_);
}
}
else if (!rosterController_) { //hasn't been logged in yet
@@ -533,6 +565,9 @@ void MainController::handleCancelLoginRequest() {
}
void MainController::signOut() {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
eventController_->clear();
logout();
loginWindow_->loggedOut();
@@ -540,6 +575,9 @@ void MainController::signOut() {
}
void MainController::logout() {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
systemTrayController_->setMyStatusType(StatusShow::None);
if (clientInitialized_ /*&& client_->isAvailable()*/) {
client_->disconnect();
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 757abb8..21460ec 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -81,7 +81,8 @@ namespace Swift {
Dock* dock,
Notifier* notifier,
URIHandler* uriHandler,
- bool useDelayForLatency);
+ bool useDelayForLatency,
+ bool eagleMode);
~MainController();
@@ -111,6 +112,7 @@ namespace Swift {
void setManagersOffline();
void handleNotificationClicked(const JID& jid);
void handleForceQuit();
+ void purgeCachedCredentials();
private:
EventLoop* eventLoop_;
@@ -160,5 +162,6 @@ namespace Swift {
bool myStatusLooksOnline_;
bool quitRequested_;
static const int SecondsToWaitBeforeForceQuitting;
+ bool eagleMode_;
};
}
diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h
index 61fcaa1..fcaeb42 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindow.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindow.h
@@ -27,6 +27,8 @@ namespace Swift {
boost::signal<void (const std::string&, const std::string&, const std::string& /* certificateFile */, bool /* remember password*/, bool /* login automatically */)> onLoginRequest;
virtual void setLoginAutomatically(bool loginAutomatically) = 0;
virtual void quit() = 0;
+ /** Disable any GUI elements that suggest saving of passwords. */
+ virtual void setRememberingAllowed(bool allowed) = 0;
/** Blocking request whether a cert should be permanently trusted.*/
virtual bool askUserToTrustCertificatePermanently(const std::string& message, Certificate::ref) = 0;
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp
index 4302c10..45d7c7e 100644
--- a/Swift/QtUI/QtLoginWindow.cpp
+++ b/Swift/QtUI/QtLoginWindow.cpp
@@ -197,6 +197,15 @@ QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream) : QMainWindow() {
this->show();
}
+void QtLoginWindow::setRememberingAllowed(bool allowed) {
+ remember_->setEnabled(allowed);
+ loginAutomatically_->setEnabled(allowed);
+ if (!allowed) {
+ remember_->setChecked(false);
+ loginAutomatically_->setChecked(false);
+ }
+}
+
bool QtLoginWindow::eventFilter(QObject *obj, QEvent *event) {
if (obj == username_->view() && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
@@ -304,6 +313,10 @@ void QtLoginWindow::setIsLoggingIn(bool loggingIn) {
void QtLoginWindow::loginClicked() {
if (username_->isEnabled()) {
onLoginRequest(Q2PSTRING(username_->currentText()), Q2PSTRING(password_->text()), Q2PSTRING(certificateFile_), remember_->isChecked(), loginAutomatically_->isChecked());
+ if (!remember_->isEnabled()) { /* Mustn't remember logins */
+ username_->clearEditText();
+ password_->setText("");
+ }
} else {
onCancelLoginRequest();
}
diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h
index b667a4b..410ed0a 100644
--- a/Swift/QtUI/QtLoginWindow.h
+++ b/Swift/QtUI/QtLoginWindow.h
@@ -36,6 +36,7 @@ namespace Swift {
virtual void removeAvailableAccount(const std::string& jid);
virtual void setLoginAutomatically(bool loginAutomatically);
virtual void setIsLoggingIn(bool loggingIn);
+ virtual void setRememberingAllowed(bool allowed);
void selectUser(const std::string& user);
bool askUserToTrustCertificatePermanently(const std::string& message, Certificate::ref certificate);
void hide();
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index d7a1f78..f0c876c 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -73,6 +73,7 @@ po::options_description QtSwift::getOptionsDescription() {
("latency-debug", "use latency debugging (unsupported)")
("multi-account", po::value<int>()->default_value(1), "number of accounts to open windows for (unsupported)")
("start-minimized", "don't show the login/roster window at startup")
+ ("eagle-mode", "Settings more suitable for military/secure deployments")
;
return result;
}
@@ -103,6 +104,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa
tabs_ = options.count("no-tabs") && !(splitter_ > 0) ? NULL : new QtChatTabs();
bool startMinimized = options.count("start-minimized") > 0;
+ bool eagleMode = options.count("eagle-mode") > 0;
settings_ = new QtSettingsProvider();
applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME);
storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir());
@@ -162,7 +164,8 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa
dock_,
notifier_,
uriHandler_,
- options.count("latency-debug") > 0);
+ options.count("latency-debug") > 0,
+ eagleMode);
mainControllers_.push_back(mainController);
}
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h
index cd6f9dc..b7459ed 100644
--- a/Swiften/Base/Algorithm.h
+++ b/Swiften/Base/Algorithm.h
@@ -12,6 +12,7 @@
#include <algorithm>
namespace Swift {
+
/*
* Generic erase()
*/
diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h
index 1155b46..cc80dc2 100644
--- a/Swiften/Client/ClientOptions.h
+++ b/Swiften/Client/ClientOptions.h
@@ -12,7 +12,7 @@ struct ClientOptions {
UseTLSWhenAvailable
};
- ClientOptions() : useStreamCompression(true), useTLS(UseTLSWhenAvailable), useStreamResumption(false) {
+ ClientOptions() : useStreamCompression(true), useTLS(UseTLSWhenAvailable), useStreamResumption(false), forgetPassword(false) {
}
/**
@@ -35,5 +35,15 @@ struct ClientOptions {
* Default: false
*/
bool useStreamResumption;
+
+ /**
+ * Forget the password once it's used.
+ * This makes the Client useless after the first login attempt.
+ *
+ * FIXME: This is a temporary workaround.
+ *
+ * Default: false
+ */
+ bool forgetPassword;
};
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 9521bd9..8684de2 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -9,6 +9,10 @@
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/Base/IDGenerator.h>
+#include <Swiften/Base/Log.h>
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/Algorithm.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/TLS/PlatformTLSFactories.h>
#include <Swiften/TLS/CertificateVerificationError.h>
@@ -17,10 +21,7 @@
#include <Swiften/TLS/PKCS12Certificate.h>
#include <Swiften/Session/BasicSessionStream.h>
#include <Swiften/Queries/IQRouter.h>
-#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Client/ClientSessionStanzaChannel.h>
-#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Network/PlatformProxyProvider.h>
#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
@@ -50,6 +51,7 @@ CoreClient::~CoreClient() {
stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&CoreClient::handlePresenceReceived, this, _1));
stanzaChannel_->onStanzaAcked.disconnect(boost::bind(&CoreClient::handleStanzaAcked, this, _1));
delete stanzaChannel_;
+ purgePassword();
}
void CoreClient::connect(const ClientOptions& o) {
@@ -88,6 +90,9 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio
}
if (!connection) {
+ if (options.forgetPassword) {
+ purgePassword();
+ }
onDisconnected(disconnectRequested_ ? boost::optional<ClientError>() : boost::optional<ClientError>(ClientError::ConnectionError));
}
else {
@@ -121,6 +126,9 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio
}
void CoreClient::disconnect() {
+ if (options.forgetPassword) {
+ purgePassword();
+ }
// FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between
// connector finishing without a connection due to an error or because of a disconnect.
disconnectRequested_ = true;
@@ -137,6 +145,9 @@ void CoreClient::setCertificate(const std::string& certificate) {
}
void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
+ if (options.forgetPassword) {
+ purgePassword();
+ }
session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this));
@@ -248,6 +259,9 @@ void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
void CoreClient::handleNeedCredentials() {
assert(session_);
session_->sendCredentials(password_);
+ if (options.forgetPassword) {
+ purgePassword();
+ }
}
void CoreClient::handleDataRead(const std::string& data) {
@@ -318,4 +332,8 @@ const JID& CoreClient::getJID() const {
}
}
+void CoreClient::purgePassword() {
+ safeClear(password_);
+}
+
}
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index 6dc8392..9806d35 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -199,6 +199,7 @@ namespace Swift {
void handlePresenceReceived(boost::shared_ptr<Presence>);
void handleMessageReceived(boost::shared_ptr<Message>);
void handleStanzaAcked(boost::shared_ptr<Stanza>);
+ void purgePassword();
private:
JID jid_;
diff --git a/Swiften/SASL/ClientAuthenticator.cpp b/Swiften/SASL/ClientAuthenticator.cpp
index b882d04..12636e2 100644
--- a/Swiften/SASL/ClientAuthenticator.cpp
+++ b/Swiften/SASL/ClientAuthenticator.cpp
@@ -1,17 +1,20 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2011 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/SASL/ClientAuthenticator.h>
+#include <Swiften/Base/Algorithm.h>
+
namespace Swift {
ClientAuthenticator::ClientAuthenticator(const std::string& name) : name(name) {
}
ClientAuthenticator::~ClientAuthenticator() {
+ safeClear(password);
}
}