diff --git a/3rdparty/gloox/client.cpp b/3rdparty/gloox/client.cpp index 7b8dc8ef9..31d1c4df5 100644 --- a/3rdparty/gloox/client.cpp +++ b/3rdparty/gloox/client.cpp @@ -361,6 +361,9 @@ namespace gloox if( tag->hasChildWithCData( mech, "NTLM" ) ) mechs |= SaslMechNTLM; + if( tag->hasChildWithCData( mech, "X-GOOGLE-TOKEN" ) ) + mechs |= SaslMechGoogleToken; + return mechs; } @@ -393,6 +396,13 @@ namespace gloox notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechPlain ); } + else if( m_streamFeatures & SaslMechGoogleToken && + m_availableSaslMechs & SaslMechGoogleToken + && !m_forceNonSasl ) + { + notifyStreamEvent( StreamEventAuthentication ); + startSASL( SaslMechGoogleToken ); + } else if( m_streamFeatures & StreamFeatureIqAuth || m_forceNonSasl ) { notifyStreamEvent( StreamEventAuthentication ); diff --git a/3rdparty/gloox/clientbase.cpp b/3rdparty/gloox/clientbase.cpp index 1619107be..3b06840f7 100644 --- a/3rdparty/gloox/clientbase.cpp +++ b/3rdparty/gloox/clientbase.cpp @@ -515,6 +515,17 @@ namespace gloox #endif break; } + case SaslMechGoogleToken: + { + a->addAttribute("mechanism", "X-GOOGLE-TOKEN"); + std::string tmp; + tmp += '\0'; + tmp += m_jid.username(); + tmp += '\0'; + tmp += m_password; + a->setCData( Base64::encode64( tmp ) ); + break; + } default: break; } diff --git a/3rdparty/gloox/gloox.h b/3rdparty/gloox/gloox.h index b86462ee8..ba14d13c4 100644 --- a/3rdparty/gloox/gloox.h +++ b/3rdparty/gloox/gloox.h @@ -719,6 +719,7 @@ namespace gloox SaslMechExternal = 2048, /**< SASL EXTERNAL according to RFC 2222 Section 7.4. */ SaslMechGssapi = 4096, /**< SASL GSSAPI (Win32 only). */ SaslMechNTLM = 8192, /**< SASL NTLM (Win32 only). */ + SaslMechGoogleToken = 16384, /**< SASL X-GOOGLE-TOKEN. */ SaslMechAll = 65535 /**< Includes all supported SASL mechanisms. */ }; diff --git a/3rdparty/libxrme/CMakeLists.txt b/3rdparty/libxrme/CMakeLists.txt index e6b27bae2..30c1bf942 100644 --- a/3rdparty/libxrme/CMakeLists.txt +++ b/3rdparty/libxrme/CMakeLists.txt @@ -30,6 +30,8 @@ target_link_libraries(xrme ${QT_LIBRARIES} ) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) + # Install library install(TARGETS xrme RUNTIME DESTINATION bin diff --git a/3rdparty/libxrme/connection.cpp b/3rdparty/libxrme/connection.cpp index 843b4bb44..920c4b40e 100644 --- a/3rdparty/libxrme/connection.cpp +++ b/3rdparty/libxrme/connection.cpp @@ -49,8 +49,8 @@ struct Connection::Private : public gloox::ConnectionListener, media_player_(NULL), remote_control_(NULL), spontaneous_disconnect_(true), - media_player_extension_(new MediaPlayerExtension()), - remote_control_extension_(new RemoteControlExtension()) {} + media_player_extension_(NULL), + remote_control_extension_(NULL) {} static const char* kDefaultServer; static const char* kDefaultJIDResource; @@ -251,6 +251,8 @@ bool Connection::Connect() { d->client_->disco()->setVersion(d->agent_name_.toUtf8().constData(), std::string()); d->client_->disco()->addFeature(kXmlnsXrme); + d->media_player_extension_ = new MediaPlayerExtension; + d->remote_control_extension_ = new RemoteControlExtension; d->client_->registerStanzaExtension(d->media_player_extension_); d->client_->registerStanzaExtension(d->remote_control_extension_); @@ -262,6 +264,8 @@ bool Connection::Connect() { // Set presence d->client_->setPresence(gloox::Presence::Available, -128); + d->client_->setSASLMechanisms(gloox::SaslMechGoogleToken); + // Connect if (!d->client_->connect(false)) { d->client_.reset(); diff --git a/CMakeLists.txt b/CMakeLists.txt index f84bf425c..8c2128a78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,6 +243,8 @@ if(ENABLE_REMOTE AND HAVE_GNUTLS) set(HAVE_REMOTE ON) add_subdirectory(3rdparty/gloox) add_subdirectory(3rdparty/libxrme) + include_directories(3rdparty) + include_directories(3rdparty/libxrme) endif(ENABLE_REMOTE AND HAVE_GNUTLS) set(HAVE_STATIC_SQLITE ${STATIC_SQLITE}) diff --git a/src/remote/remote.cpp b/src/remote/remote.cpp index 3cc631d23..e441718c1 100644 --- a/src/remote/remote.cpp +++ b/src/remote/remote.cpp @@ -52,7 +52,7 @@ void Remote::ReloadSettings() { s.beginGroup(RemoteConfig::kSettingsGroup); QString username = s.value("username").toString(); - QString password = s.value("password").toString(); + QString password = s.value("token").toString(); QString agent_name = s.value("agent_name", RemoteConfig::DefaultAgentName()).toString(); // Have the settings changed? diff --git a/src/remote/remoteconfig.cpp b/src/remote/remoteconfig.cpp index cb871055e..6cc852519 100644 --- a/src/remote/remoteconfig.cpp +++ b/src/remote/remoteconfig.cpp @@ -84,19 +84,27 @@ void RemoteConfig::ValidateFinished() { QNetworkReply* reply = qobject_cast(sender()); Q_ASSERT(reply); reply->deleteLater(); + QString data = QString::fromUtf8(reply->readAll()); - QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); - if (reply->error() != QNetworkReply::NoError || !status_code.isValid() || status_code.toInt() != 200) { - AuthenticationComplete(false); - return; + QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + if (reply->error() == QNetworkReply::NoError && status_code.isValid() && status_code.toInt() == 200) { + QStringList params = data.split('\n'); + foreach (const QString& param, params) { + if (param.startsWith("Auth=")) { + AuthenticationComplete(param.split('=')[1]); + return; + } + } } - AuthenticationComplete(true); + AuthenticationComplete(QString::null); } -void RemoteConfig::AuthenticationComplete(bool success) { +void RemoteConfig::AuthenticationComplete(const QString& token) { if (!waiting_for_auth_) return; // Wasn't us that was waiting for auth + const bool success = !token.isNull(); + ui_->busy->hide(); waiting_for_auth_ = false; @@ -106,6 +114,7 @@ void RemoteConfig::AuthenticationComplete(bool success) { QSettings s; s.beginGroup(kSettingsGroup); s.setValue("password", ui_->password->text()); + s.setValue("token", token); ui_->password->clear(); } diff --git a/src/remote/remoteconfig.h b/src/remote/remoteconfig.h index 5a5e1b405..f9964f459 100644 --- a/src/remote/remoteconfig.h +++ b/src/remote/remoteconfig.h @@ -46,7 +46,7 @@ class RemoteConfig : public QWidget { void ValidationComplete(bool success); private slots: - void AuthenticationComplete(bool success); + void AuthenticationComplete(const QString& token); void SignOut(); void ValidateFinished();