SASL support
authorChris Fuenty <zimmy@zimmy.co.uk>
Sat, 13 Feb 2010 12:43:30 +0000 (13:43 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 14 Feb 2010 20:59:18 +0000 (21:59 +0100)
src/common/network.cpp
src/common/network.h
src/core/corenetwork.cpp
src/core/ircserverhandler.cpp
src/core/ircserverhandler.h
src/core/postgresqlstorage.cpp
src/core/sqlitestorage.cpp
src/qtui/settingspages/networkssettingspage.cpp
src/qtui/settingspages/networkssettingspage.ui

index 0dae357..67ebe91 100644 (file)
@@ -47,6 +47,7 @@ Network::Network(const NetworkId &networkid, QObject *parent)
     _prefixModes(QString()),
     _useRandomServer(false),
     _useAutoIdentify(false),
     _prefixModes(QString()),
     _useRandomServer(false),
     _useAutoIdentify(false),
+    _useSasl(false),
     _useAutoReconnect(false),
     _autoReconnectInterval(60),
     _autoReconnectRetries(10),
     _useAutoReconnect(false),
     _autoReconnectInterval(60),
     _autoReconnectRetries(10),
@@ -87,6 +88,9 @@ NetworkInfo Network::networkInfo() const {
   info.useAutoIdentify = useAutoIdentify();
   info.autoIdentifyService = autoIdentifyService();
   info.autoIdentifyPassword = autoIdentifyPassword();
   info.useAutoIdentify = useAutoIdentify();
   info.autoIdentifyService = autoIdentifyService();
   info.autoIdentifyPassword = autoIdentifyPassword();
+  info.useSasl = useSasl();
+  info.saslAccount = saslAccount();
+  info.saslPassword = saslPassword();
   info.useAutoReconnect = useAutoReconnect();
   info.autoReconnectInterval = autoReconnectInterval();
   info.autoReconnectRetries = autoReconnectRetries();
   info.useAutoReconnect = useAutoReconnect();
   info.autoReconnectInterval = autoReconnectInterval();
   info.autoReconnectRetries = autoReconnectRetries();
@@ -108,6 +112,9 @@ void Network::setNetworkInfo(const NetworkInfo &info) {
   if(info.useAutoIdentify != useAutoIdentify()) setUseAutoIdentify(info.useAutoIdentify);
   if(info.autoIdentifyService != autoIdentifyService()) setAutoIdentifyService(info.autoIdentifyService);
   if(info.autoIdentifyPassword != autoIdentifyPassword()) setAutoIdentifyPassword(info.autoIdentifyPassword);
   if(info.useAutoIdentify != useAutoIdentify()) setUseAutoIdentify(info.useAutoIdentify);
   if(info.autoIdentifyService != autoIdentifyService()) setAutoIdentifyService(info.autoIdentifyService);
   if(info.autoIdentifyPassword != autoIdentifyPassword()) setAutoIdentifyPassword(info.autoIdentifyPassword);
+  if(info.useSasl != useSasl()) setUseSasl(info.useSasl);
+  if(info.saslAccount != saslAccount()) setSaslAccount(info.saslAccount);
+  if(info.saslPassword != saslPassword()) setSaslPassword(info.saslPassword);
   if(info.useAutoReconnect != useAutoReconnect()) setUseAutoReconnect(info.useAutoReconnect);
   if(info.autoReconnectInterval != autoReconnectInterval()) setAutoReconnectInterval(info.autoReconnectInterval);
   if(info.autoReconnectRetries != autoReconnectRetries()) setAutoReconnectRetries(info.autoReconnectRetries);
   if(info.useAutoReconnect != useAutoReconnect()) setUseAutoReconnect(info.useAutoReconnect);
   if(info.autoReconnectInterval != autoReconnectInterval()) setAutoReconnectInterval(info.autoReconnectInterval);
   if(info.autoReconnectRetries != autoReconnectRetries()) setAutoReconnectRetries(info.autoReconnectRetries);
@@ -566,6 +573,24 @@ void Network::setAutoIdentifyPassword(const QString &password) {
   emit configChanged();
 }
 
   emit configChanged();
 }
 
+void Network::setUseSasl(bool use) {
+    _useSasl = use;
+    SYNC(ARG(use))
+    emit configChanged();
+}
+
+void Network::setSaslAccount(const QString &account) {
+    _saslAccount = account;
+    SYNC(ARG(account))
+    emit configChanged();
+}
+
+void Network::setSaslPassword(const QString &password) {
+    _saslPassword = password;
+    SYNC(ARG(password))
+    emit configChanged();
+}
+
 void Network::setUseAutoReconnect(bool use) {
   _useAutoReconnect = use;
   SYNC(ARG(use))
 void Network::setUseAutoReconnect(bool use) {
   _useAutoReconnect = use;
   SYNC(ARG(use))
@@ -758,6 +783,7 @@ NetworkInfo::NetworkInfo()
   useRandomServer(false),
   useAutoIdentify(false),
   autoIdentifyService("NickServ"),
   useRandomServer(false),
   useAutoIdentify(false),
   autoIdentifyService("NickServ"),
+  useSasl(false),
   useAutoReconnect(true),
   autoReconnectInterval(60),
   autoReconnectRetries(20),
   useAutoReconnect(true),
   autoReconnectInterval(60),
   autoReconnectRetries(20),
@@ -780,6 +806,9 @@ bool NetworkInfo::operator==(const NetworkInfo &other) const {
   if(useAutoIdentify != other.useAutoIdentify) return false;
   if(autoIdentifyService != other.autoIdentifyService) return false;
   if(autoIdentifyPassword != other.autoIdentifyPassword) return false;
   if(useAutoIdentify != other.useAutoIdentify) return false;
   if(autoIdentifyService != other.autoIdentifyService) return false;
   if(autoIdentifyPassword != other.autoIdentifyPassword) return false;
+  if(useSasl != other.useSasl) return false;
+  if(saslAccount != other.saslAccount) return false;
+  if(saslPassword != other.saslPassword) return false;
   if(useAutoReconnect != other.useAutoReconnect) return false;
   if(autoReconnectInterval != other.autoReconnectInterval) return false;
   if(autoReconnectRetries != other.autoReconnectRetries) return false;
   if(useAutoReconnect != other.useAutoReconnect) return false;
   if(autoReconnectInterval != other.autoReconnectInterval) return false;
   if(autoReconnectRetries != other.autoReconnectRetries) return false;
@@ -806,6 +835,9 @@ QDataStream &operator<<(QDataStream &out, const NetworkInfo &info) {
   i["UseAutoIdentify"] = info.useAutoIdentify;
   i["AutoIdentifyService"] = info.autoIdentifyService;
   i["AutoIdentifyPassword"] = info.autoIdentifyPassword;
   i["UseAutoIdentify"] = info.useAutoIdentify;
   i["AutoIdentifyService"] = info.autoIdentifyService;
   i["AutoIdentifyPassword"] = info.autoIdentifyPassword;
+  i["UseSasl"] = info.useSasl;
+  i["SaslAccount"] = info.saslAccount;
+  i["SaslPassword"] = info.saslPassword;
   i["UseAutoReconnect"] = info.useAutoReconnect;
   i["AutoReconnectInterval"] = info.autoReconnectInterval;
   i["AutoReconnectRetries"] = info.autoReconnectRetries;
   i["UseAutoReconnect"] = info.useAutoReconnect;
   i["AutoReconnectInterval"] = info.autoReconnectInterval;
   i["AutoReconnectRetries"] = info.autoReconnectRetries;
@@ -830,6 +862,9 @@ QDataStream &operator>>(QDataStream &in, NetworkInfo &info) {
   info.useAutoIdentify = i["UseAutoIdentify"].toBool();
   info.autoIdentifyService = i["AutoIdentifyService"].toString();
   info.autoIdentifyPassword = i["AutoIdentifyPassword"].toString();
   info.useAutoIdentify = i["UseAutoIdentify"].toBool();
   info.autoIdentifyService = i["AutoIdentifyService"].toString();
   info.autoIdentifyPassword = i["AutoIdentifyPassword"].toString();
+  info.useSasl = i["UseSasl"].toBool();
+  info.saslAccount = i["SaslAccount"].toString();
+  info.saslPassword = i["SaslPassword"].toString();
   info.useAutoReconnect = i["UseAutoReconnect"].toBool();
   info.autoReconnectInterval = i["AutoReconnectInterval"].toUInt();
   info.autoReconnectRetries = i["AutoReconnectRetries"].toInt();
   info.useAutoReconnect = i["UseAutoReconnect"].toBool();
   info.autoReconnectInterval = i["AutoReconnectInterval"].toUInt();
   info.autoReconnectRetries = i["AutoReconnectRetries"].toInt();
@@ -843,7 +878,8 @@ QDebug operator<<(QDebug dbg, const NetworkInfo &i) {
                << " codecForServer = " << i.codecForServer << " codecForEncoding = " << i.codecForEncoding << " codecForDecoding = " << i.codecForDecoding
                << " serverList = " << i.serverList << " useRandomServer = " << i.useRandomServer << " perform = " << i.perform
                << " useAutoIdentify = " << i.useAutoIdentify << " autoIdentifyService = " << i.autoIdentifyService << " autoIdentifyPassword = " << i.autoIdentifyPassword
                << " codecForServer = " << i.codecForServer << " codecForEncoding = " << i.codecForEncoding << " codecForDecoding = " << i.codecForDecoding
                << " serverList = " << i.serverList << " useRandomServer = " << i.useRandomServer << " perform = " << i.perform
                << " useAutoIdentify = " << i.useAutoIdentify << " autoIdentifyService = " << i.autoIdentifyService << " autoIdentifyPassword = " << i.autoIdentifyPassword
-               << " useAutoReconnect = " << i.useAutoReconnect << " autoReconnectInterval = " << i.autoReconnectInterval
+                << " useSasl = " << i.useSasl << " saslAccount = " << i.saslAccount << " saslPassword = " << i.saslPassword
+                << " useAutoReconnect = " << i.useAutoReconnect << " autoReconnectInterval = " << i.autoReconnectInterval
                << " autoReconnectRetries = " << i.autoReconnectRetries << " unlimitedReconnectRetries = " << i.unlimitedReconnectRetries
                << " rejoinChannels = " << i.rejoinChannels << ")";
   return dbg.space();
                << " autoReconnectRetries = " << i.autoReconnectRetries << " unlimitedReconnectRetries = " << i.unlimitedReconnectRetries
                << " rejoinChannels = " << i.rejoinChannels << ")";
   return dbg.space();
index 4c5baf6..f0bd112 100644 (file)
@@ -64,6 +64,9 @@ class Network : public SyncableObject {
   Q_PROPERTY(bool useAutoIdentify READ useAutoIdentify WRITE setUseAutoIdentify STORED false)
   Q_PROPERTY(QString autoIdentifyService READ autoIdentifyService WRITE setAutoIdentifyService STORED false)
   Q_PROPERTY(QString autoIdentifyPassword READ autoIdentifyPassword WRITE setAutoIdentifyPassword STORED false)
   Q_PROPERTY(bool useAutoIdentify READ useAutoIdentify WRITE setUseAutoIdentify STORED false)
   Q_PROPERTY(QString autoIdentifyService READ autoIdentifyService WRITE setAutoIdentifyService STORED false)
   Q_PROPERTY(QString autoIdentifyPassword READ autoIdentifyPassword WRITE setAutoIdentifyPassword STORED false)
+  Q_PROPERTY(bool useSasl READ useSasl WRITE setUseSasl STORED false)
+  Q_PROPERTY(QString saslAccount READ saslAccount WRITE setSaslAccount STORED false)
+  Q_PROPERTY(QString saslPassword READ saslPassword WRITE setSaslPassword STORED false)
   Q_PROPERTY(bool useAutoReconnect READ useAutoReconnect WRITE setUseAutoReconnect STORED false)
   Q_PROPERTY(quint32 autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval STORED false)
   Q_PROPERTY(quint16 autoReconnectRetries READ autoReconnectRetries WRITE setAutoReconnectRetries STORED false)
   Q_PROPERTY(bool useAutoReconnect READ useAutoReconnect WRITE setUseAutoReconnect STORED false)
   Q_PROPERTY(quint32 autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval STORED false)
   Q_PROPERTY(quint16 autoReconnectRetries READ autoReconnectRetries WRITE setAutoReconnectRetries STORED false)
@@ -153,6 +156,9 @@ public:
   inline bool useAutoIdentify() const { return _useAutoIdentify; }
   inline const QString &autoIdentifyService() const { return _autoIdentifyService; }
   inline const QString &autoIdentifyPassword() const { return _autoIdentifyPassword; }
   inline bool useAutoIdentify() const { return _useAutoIdentify; }
   inline const QString &autoIdentifyService() const { return _autoIdentifyService; }
   inline const QString &autoIdentifyPassword() const { return _autoIdentifyPassword; }
+  inline bool useSasl() const { return _useSasl; }
+  inline const QString &saslAccount() const { return _saslAccount; }
+  inline const QString &saslPassword() const { return _saslPassword; }
   inline bool useAutoReconnect() const { return _useAutoReconnect; }
   inline quint32 autoReconnectInterval() const { return _autoReconnectInterval; }
   inline quint16 autoReconnectRetries() const { return _autoReconnectRetries; }
   inline bool useAutoReconnect() const { return _useAutoReconnect; }
   inline quint32 autoReconnectInterval() const { return _autoReconnectInterval; }
   inline quint16 autoReconnectRetries() const { return _autoReconnectRetries; }
@@ -223,6 +229,9 @@ public slots:
   void setUseAutoIdentify(bool);
   void setAutoIdentifyService(const QString &);
   void setAutoIdentifyPassword(const QString &);
   void setUseAutoIdentify(bool);
   void setAutoIdentifyService(const QString &);
   void setAutoIdentifyPassword(const QString &);
+  void setUseSasl(bool);
+  void setSaslAccount(const QString &);
+  void setSaslPassword(const QString &);
   virtual void setUseAutoReconnect(bool);
   virtual void setAutoReconnectInterval(quint32);
   virtual void setAutoReconnectRetries(quint16);
   virtual void setUseAutoReconnect(bool);
   virtual void setAutoReconnectInterval(quint32);
   virtual void setAutoReconnectRetries(quint16);
@@ -339,6 +348,10 @@ private:
   QString _autoIdentifyService;
   QString _autoIdentifyPassword;
 
   QString _autoIdentifyService;
   QString _autoIdentifyPassword;
 
+  bool _useSasl;
+  QString _saslAccount;
+  QString _saslPassword;
+
   bool _useAutoReconnect;
   quint32 _autoReconnectInterval;
   quint16 _autoReconnectRetries;
   bool _useAutoReconnect;
   quint32 _autoReconnectInterval;
   quint16 _autoReconnectRetries;
@@ -386,6 +399,10 @@ struct NetworkInfo {
   QString autoIdentifyService;
   QString autoIdentifyPassword;
 
   QString autoIdentifyService;
   QString autoIdentifyPassword;
 
+  bool useSasl;
+  QString saslAccount;
+  QString saslPassword;
+
   bool useAutoReconnect;
   quint32 autoReconnectInterval;
   quint16 autoReconnectRetries;
   bool useAutoReconnect;
   quint32 autoReconnectInterval;
   quint16 autoReconnectRetries;
index 596a598..959b3c4 100644 (file)
@@ -333,6 +333,9 @@ void CoreNetwork::socketInitialized() {
   _tokenBucket = _burstSize; // init with a full bucket
   _tokenBucketTimer.start(_messageDelay);
 
   _tokenBucket = _burstSize; // init with a full bucket
   _tokenBucketTimer.start(_messageDelay);
 
+  if(networkInfo().useSasl) {
+    putRawLine(serverEncode(QString("CAP REQ :sasl")));
+  }
   if(!server.password.isEmpty()) {
     putRawLine(serverEncode(QString("PASS %1").arg(server.password)));
   }
   if(!server.password.isEmpty()) {
     putRawLine(serverEncode(QString("PASS %1").arg(server.password)));
   }
index 97e0058..445ca7c 100644 (file)
@@ -84,6 +84,12 @@ void IrcServerHandler::handleServerMsg(QByteArray msg) {
 
   QString foo = serverDecode(params.takeFirst());
 
 
   QString foo = serverDecode(params.takeFirst());
 
+  // with SASL, the command is 'AUTHENTICATE +' and we should check for this here.
+  if(foo == QString("AUTHENTICATE +")) {
+    handleAuthenticate();
+    return;
+  }
+
   // a colon as the first chars indicates the existence of a prefix
   if(foo[0] == ':') {
     foo.remove(0, 1);
   // a colon as the first chars indicates the existence of a prefix
   if(foo[0] == ':') {
     foo.remove(0, 1);
@@ -160,6 +166,11 @@ void IrcServerHandler::defaultHandler(QString cmd, const QString &prefix, const
       case 321: case 366: case 376:
         break;
 
       case 321: case 366: case 376:
         break;
 
+      case 903: case 904: case 905: case 906: case 907:
+      {
+        network()->putRawLine("CAP END");
+        emit displayMsg(Message::Info, BufferInfo::StatusBuffer, "", "CAP: " + params.join(""));
+      }
       // Everything else will be marked in red, so we can add them somewhere.
       default:
         if(_whois) {
       // Everything else will be marked in red, so we can add them somewhere.
       default:
         if(_whois) {
@@ -542,6 +553,31 @@ void IrcServerHandler::handleTopic(const QString &prefix, const QList<QByteArray
   emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel->name(), tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel->name()).arg(topic));
 }
 
   emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel->name(), tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel->name()).arg(topic));
 }
 
+void IrcServerHandler::handleCap(const QString &prefix, const QList<QByteArray> &params) {
+    // for SASL, there will only be a single param of 'sasl', however you can check here for
+    // additional CAP messages (ls, multi-prefix, et cetera).
+
+    Q_UNUSED(prefix);
+
+    if(params.size() == 3) {
+        QString param = serverDecode(params[2]);
+        if(param == QString("sasl")) {  // SASL Ready
+            network()->putRawLine(serverEncode("AUTHENTICATE PLAIN"));  // Only working with PLAIN atm, blowfish later
+        }
+    }
+}
+
+void IrcServerHandler::handleAuthenticate() {
+    QString construct = network()->saslAccount();
+    construct.append(QChar(QChar::Null));
+    construct.append(network()->saslAccount());
+    construct.append(QChar(QChar::Null));
+    construct.append(network()->saslPassword());
+    QByteArray saslData = QByteArray(construct.toAscii().toBase64());
+    saslData.prepend(QString("AUTHENTICATE ").toAscii());
+    network()->putRawLine(saslData);
+}
+
 /* RPL_WELCOME */
 void IrcServerHandler::handle001(const QString &prefix, const QList<QByteArray> &params) {
   network()->setCurrentServer(prefix);
 /* RPL_WELCOME */
 void IrcServerHandler::handle001(const QString &prefix, const QList<QByteArray> &params) {
   network()->setCurrentServer(prefix);
index 86eaff2..3b2b875 100644 (file)
@@ -45,7 +45,8 @@ public slots:
   void handlePrivmsg(const QString &prefix, const QList<QByteArray> &params);
   void handleQuit(const QString &prefix, const QList<QByteArray> &params);
   void handleTopic(const QString &prefix, const QList<QByteArray> &params);
   void handlePrivmsg(const QString &prefix, const QList<QByteArray> &params);
   void handleQuit(const QString &prefix, const QList<QByteArray> &params);
   void handleTopic(const QString &prefix, const QList<QByteArray> &params);
-
+  void handleCap(const QString &prefix, const QList<QByteArray> &params);   // CAP framework
+  void handleAuthenticate();                                                // SASL auth - no params
   void handle001(const QString &prefix, const QList<QByteArray> &params);   // RPL_WELCOME
   void handle005(const QString &prefix, const QList<QByteArray> &params);   // RPL_ISUPPORT
   void handle221(const QString &prefix, const QList<QByteArray> &params);   // RPL_UMODEIS
   void handle001(const QString &prefix, const QList<QByteArray> &params);   // RPL_WELCOME
   void handle005(const QString &prefix, const QList<QByteArray> &params);   // RPL_ISUPPORT
   void handle221(const QString &prefix, const QList<QByteArray> &params);   // RPL_UMODEIS
index 2505373..c942b4a 100644 (file)
@@ -568,6 +568,9 @@ void PostgreSqlStorage::bindNetworkInfo(QSqlQuery &query, const NetworkInfo &inf
   query.bindValue(":useautoidentify", info.useAutoIdentify);
   query.bindValue(":autoidentifyservice", info.autoIdentifyService);
   query.bindValue(":autoidentifypassword", info.autoIdentifyPassword);
   query.bindValue(":useautoidentify", info.useAutoIdentify);
   query.bindValue(":autoidentifyservice", info.autoIdentifyService);
   query.bindValue(":autoidentifypassword", info.autoIdentifyPassword);
+  query.bindValue(":usesasl", info.useSasl);
+  query.bindValue(":saslaccount", info.saslAccount);
+  query.bindValue(":saslpassword", info.saslPassword);
   query.bindValue(":useautoreconnect", info.useAutoReconnect);
   query.bindValue(":autoreconnectinterval", info.autoReconnectInterval);
   query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
   query.bindValue(":useautoreconnect", info.useAutoReconnect);
   query.bindValue(":autoreconnectinterval", info.autoReconnectInterval);
   query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
@@ -707,6 +710,9 @@ QList<NetworkInfo> PostgreSqlStorage::networks(UserId user) {
     net.autoReconnectRetries = networksQuery.value(13).toInt();
     net.unlimitedReconnectRetries = networksQuery.value(14).toBool();
     net.rejoinChannels = networksQuery.value(15).toBool();
     net.autoReconnectRetries = networksQuery.value(13).toInt();
     net.unlimitedReconnectRetries = networksQuery.value(14).toBool();
     net.rejoinChannels = networksQuery.value(15).toBool();
+    net.useSasl = networksQuery.value(16).toBool();
+    net.saslAccount = networksQuery.value(17).toString();
+    net.saslPassword = networksQuery.value(18).toString();
 
     serversQuery.bindValue(":networkid", net.networkId.toInt());
     safeExec(serversQuery);
 
     serversQuery.bindValue(":networkid", net.networkId.toInt());
     safeExec(serversQuery);
index 6462a97..c962e8f 100644 (file)
@@ -591,6 +591,9 @@ void SqliteStorage::bindNetworkInfo(QSqlQuery &query, const NetworkInfo &info) {
   query.bindValue(":useautoidentify", info.useAutoIdentify ? 1 : 0);
   query.bindValue(":autoidentifyservice", info.autoIdentifyService);
   query.bindValue(":autoidentifypassword", info.autoIdentifyPassword);
   query.bindValue(":useautoidentify", info.useAutoIdentify ? 1 : 0);
   query.bindValue(":autoidentifyservice", info.autoIdentifyService);
   query.bindValue(":autoidentifypassword", info.autoIdentifyPassword);
+  query.bindValue(":usesasl", info.useSasl ? 1 : 0);
+  query.bindValue(":saslaccount", info.saslAccount);
+  query.bindValue(":saslpassword", info.saslPassword);
   query.bindValue(":useautoreconnect", info.useAutoReconnect ? 1 : 0);
   query.bindValue(":autoreconnectinterval", info.autoReconnectInterval);
   query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
   query.bindValue(":useautoreconnect", info.useAutoReconnect ? 1 : 0);
   query.bindValue(":autoreconnectinterval", info.autoReconnectInterval);
   query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
@@ -780,6 +783,9 @@ QList<NetworkInfo> SqliteStorage::networks(UserId user) {
         net.autoReconnectRetries = networksQuery.value(13).toInt();
         net.unlimitedReconnectRetries = networksQuery.value(14).toInt() == 1 ? true : false;
         net.rejoinChannels = networksQuery.value(15).toInt() == 1 ? true : false;
         net.autoReconnectRetries = networksQuery.value(13).toInt();
         net.unlimitedReconnectRetries = networksQuery.value(14).toInt() == 1 ? true : false;
         net.rejoinChannels = networksQuery.value(15).toInt() == 1 ? true : false;
+        net.useSasl = networksQuery.value(16).toInt() == 1 ? true : false;
+        net.saslAccount = networksQuery.value(17).toString();
+        net.saslPassword = networksQuery.value(18).toString();
 
         serversQuery.bindValue(":networkid", net.networkId.toInt());
         safeExec(serversQuery);
 
         serversQuery.bindValue(":networkid", net.networkId.toInt());
         safeExec(serversQuery);
index 1b20c2a..2ea60db 100644 (file)
@@ -78,6 +78,9 @@ NetworksSettingsPage::NetworksSettingsPage(QWidget *parent)
   connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
   connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
   connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
   connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
   connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
   connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
+  connect(ui.sasl, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
+  connect(ui.saslAccount, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged()));
+  connect(ui.saslPassword, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged()));
   connect(ui.useCustomEncodings, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
   connect(ui.sendEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
   connect(ui.recvEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
   connect(ui.useCustomEncodings, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
   connect(ui.sendEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
   connect(ui.recvEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
@@ -429,6 +432,9 @@ void NetworksSettingsPage::displayNetwork(NetworkId id) {
     ui.autoIdentify->setChecked(info.useAutoIdentify);
     ui.autoIdentifyService->setText(info.autoIdentifyService);
     ui.autoIdentifyPassword->setText(info.autoIdentifyPassword);
     ui.autoIdentify->setChecked(info.useAutoIdentify);
     ui.autoIdentifyService->setText(info.autoIdentifyService);
     ui.autoIdentifyPassword->setText(info.autoIdentifyPassword);
+    ui.sasl->setChecked(info.useSasl);
+    ui.saslAccount->setText(info.saslAccount);
+    ui.saslPassword->setText(info.saslPassword);
     if(info.codecForEncoding.isEmpty()) {
       ui.sendEncoding->setCurrentIndex(ui.sendEncoding->findText(Network::defaultCodecForEncoding()));
       ui.recvEncoding->setCurrentIndex(ui.recvEncoding->findText(Network::defaultCodecForDecoding()));
     if(info.codecForEncoding.isEmpty()) {
       ui.sendEncoding->setCurrentIndex(ui.sendEncoding->findText(Network::defaultCodecForEncoding()));
       ui.recvEncoding->setCurrentIndex(ui.recvEncoding->findText(Network::defaultCodecForDecoding()));
@@ -452,6 +458,8 @@ void NetworksSettingsPage::displayNetwork(NetworkId id) {
     ui.performEdit->clear();
     ui.autoIdentifyService->clear();
     ui.autoIdentifyPassword->clear();
     ui.performEdit->clear();
     ui.autoIdentifyService->clear();
     ui.autoIdentifyPassword->clear();
+    ui.saslAccount->clear();
+    ui.saslPassword->clear();
     setWidgetStates();
   }
   _ignoreWidgetChanges = false;
     setWidgetStates();
   }
   _ignoreWidgetChanges = false;
@@ -465,6 +473,9 @@ void NetworksSettingsPage::saveToNetworkInfo(NetworkInfo &info) {
   info.useAutoIdentify = ui.autoIdentify->isChecked();
   info.autoIdentifyService = ui.autoIdentifyService->text();
   info.autoIdentifyPassword = ui.autoIdentifyPassword->text();
   info.useAutoIdentify = ui.autoIdentify->isChecked();
   info.autoIdentifyService = ui.autoIdentifyService->text();
   info.autoIdentifyPassword = ui.autoIdentifyPassword->text();
+  info.useSasl = ui.sasl->isChecked();
+  info.saslAccount = ui.saslAccount->text();
+  info.saslPassword = ui.saslPassword->text();
   if(!ui.useCustomEncodings->isChecked()) {
     info.codecForEncoding.clear();
     info.codecForDecoding.clear();
   if(!ui.useCustomEncodings->isChecked()) {
     info.codecForEncoding.clear();
     info.codecForDecoding.clear();
index 41bcfb9..4bbafba 100644 (file)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>515</width>
     <x>0</x>
     <y>0</y>
     <width>515</width>
-    <height>453</height>
+    <height>503</height>
    </rect>
   </property>
   <property name="windowTitle">
    </rect>
   </property>
   <property name="windowTitle">
@@ -547,6 +547,64 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne
             </layout>
            </widget>
           </item>
             </layout>
            </widget>
           </item>
+          <item>
+           <widget class="QGroupBox" name="sasl">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="title">
+             <string>Use SASL Authentication</string>
+            </property>
+            <property name="checkable">
+             <bool>true</bool>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+            <layout class="QGridLayout" name="gridLayout_2">
+             <item row="0" column="1">
+              <widget class="QLineEdit" name="saslAccount">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="text">
+                <string/>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="1">
+              <widget class="QLineEdit" name="saslPassword">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="echoMode">
+                <enum>QLineEdit::Password</enum>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0">
+              <widget class="QLabel" name="label_11">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="text">
+                <string>Password:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_10">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="text">
+                <string>Account:</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
           <item>
            <spacer name="verticalSpacer_2">
             <property name="orientation">
           <item>
            <spacer name="verticalSpacer_2">
             <property name="orientation">
@@ -718,7 +776,6 @@ Unless you *really* know what you do, leave this as ISO-8859-1!</string>
   <tabstop>reconnectRetries</tabstop>
   <tabstop>unlimitedRetries</tabstop>
   <tabstop>rejoinOnReconnect</tabstop>
   <tabstop>reconnectRetries</tabstop>
   <tabstop>unlimitedRetries</tabstop>
   <tabstop>rejoinOnReconnect</tabstop>
-  <tabstop>autoIdentify</tabstop>
   <tabstop>autoIdentifyService</tabstop>
   <tabstop>autoIdentifyPassword</tabstop>
   <tabstop>useCustomEncodings</tabstop>
   <tabstop>autoIdentifyService</tabstop>
   <tabstop>autoIdentifyPassword</tabstop>
   <tabstop>useCustomEncodings</tabstop>
@@ -735,12 +792,12 @@ Unless you *really* know what you do, leave this as ISO-8859-1!</string>
    <slot>setDisabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
    <slot>setDisabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>173</x>
-     <y>296</y>
+     <x>317</x>
+     <y>331</y>
     </hint>
     <hint type="destinationlabel">
     </hint>
     <hint type="destinationlabel">
-     <x>118</x>
-     <y>294</y>
+     <x>209</x>
+     <y>334</y>
     </hint>
    </hints>
   </connection>
     </hint>
    </hints>
   </connection>