aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kvilib/irc/kvi_ircserver.cpp37
-rw-r--r--src/kvilib/irc/kvi_ircserver.h60
-rw-r--r--src/kvilib/irc/kvi_ircserverdb.cpp4
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.cpp62
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.h26
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp21
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionserverinfo.h8
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionstatedata.cpp1
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionstatedata.h4
-rw-r--r--src/kvirc/kernel/kvi_irccontext.cpp6
-rw-r--r--src/kvirc/kernel/kvi_options.cpp6
-rw-r--r--src/kvirc/kernel/kvi_options.h5
-rw-r--r--src/kvirc/kernel/kvi_out.h3
-rw-r--r--src/kvirc/sparser/kvi_numeric.h9
-rw-r--r--src/kvirc/sparser/kvi_sp_literal.cpp47
-rw-r--r--src/kvirc/sparser/kvi_sp_numeric.cpp46
-rw-r--r--src/kvirc/sparser/kvi_sp_tables.cpp47
-rw-r--r--src/kvirc/sparser/kvi_sparser.h8
-rw-r--r--src/modules/options/optw_connection.cpp6
-rw-r--r--src/modules/options/optw_servers.cpp49
-rw-r--r--src/modules/options/optw_servers.h5
21 files changed, 377 insertions, 83 deletions
diff --git a/src/kvilib/irc/kvi_ircserver.cpp b/src/kvilib/irc/kvi_ircserver.cpp
index ff81d171a..598fe99fc 100644
--- a/src/kvilib/irc/kvi_ircserver.cpp
+++ b/src/kvilib/irc/kvi_ircserver.cpp
@@ -87,6 +87,8 @@ KviServer::KviServer(const KviServer & serv)
m_iProxy = serv.m_iProxy;
m_szUserIdentityId = serv.m_szUserIdentityId;
m_bAutoConnect = serv.m_bAutoConnect;
+ m_szSaslNick = serv.m_szSaslNick;
+ m_szSaslPass = serv.m_szSaslPass;
if(serv.m_pAutoJoinChannelList)
m_pAutoJoinChannelList = new QStringList(*(serv.m_pAutoJoinChannelList));
@@ -118,6 +120,8 @@ void KviServer::operator=(const KviServer & serv)
m_szUserIdentityId = serv.m_szUserIdentityId;
m_iProxy = serv.m_iProxy;
m_bAutoConnect = serv.m_bAutoConnect;
+ m_szSaslNick = serv.m_szSaslNick;
+ m_szSaslPass = serv.m_szSaslPass;
if(m_pAutoJoinChannelList) delete m_pAutoJoinChannelList;
if(serv.m_pAutoJoinChannelList)
@@ -154,7 +158,7 @@ void KviServer::generateUniqueId()
QString KviServer::ircUri()
{
QString szUri("irc");
- if(useSSL() || supportsSTARTTLS()) szUri += "s";
+ if(useSSL()) szUri += "s";
if(isIPv6()) szUri += "6";
szUri += "://";
szUri += m_szHostname;
@@ -192,6 +196,10 @@ bool KviServer::load(KviConfig * cfg, const QString & szPrefix)
m_szPass = cfg->readQStringEntry(szTmp);
KviQString::sprintf(szTmp,"%QNick",&szPrefix);
m_szNick = cfg->readQStringEntry(szTmp);
+ KviQString::sprintf(szTmp,"%QSaslPass",&szPrefix);
+ m_szSaslPass = cfg->readQStringEntry(szTmp);
+ KviQString::sprintf(szTmp,"%QSaslNick",&szPrefix);
+ m_szSaslNick = cfg->readQStringEntry(szTmp);
KviQString::sprintf(szTmp,"%QRealName",&szPrefix);
m_szRealName = cfg->readQStringEntry(szTmp);
KviQString::sprintf(szTmp,"%QInitUmode",&szPrefix);
@@ -224,8 +232,10 @@ bool KviServer::load(KviConfig * cfg, const QString & szPrefix)
setCacheIp(cfg->readBoolEntry(szTmp,false)); // true ?
KviQString::sprintf(szTmp,"%QSSL",&szPrefix);
setUseSSL(cfg->readBoolEntry(szTmp,false));
- KviQString::sprintf(szTmp,"%QSupportsSTARTTLS",&szPrefix);
- setSupportsSTARTTLS(cfg->readBoolEntry(szTmp,false));
+ KviQString::sprintf(szTmp,"%QEnabledSTARTTLS",&szPrefix);
+ setEnabledSTARTTLS(cfg->readBoolEntry(szTmp,true));
+ KviQString::sprintf(szTmp,"%QEnabledSASL",&szPrefix);
+ setEnabledSASL(cfg->readBoolEntry(szTmp,false));
KviQString::sprintf(szTmp,"%QProxy",&szPrefix);
setProxy(cfg->readIntEntry(szTmp,-2));
KviQString::sprintf(szTmp,"%QUserIdentityId",&szPrefix);
@@ -265,6 +275,16 @@ void KviServer::save(KviConfig * cfg, const QString & szPrefix)
KviQString::sprintf(szTmp,"%QNick",&szPrefix);
cfg->writeEntry(szTmp,m_szNick);
}
+ if(!m_szSaslPass.isEmpty())
+ {
+ KviQString::sprintf(szTmp,"%QSaslPass",&szPrefix);
+ cfg->writeEntry(szTmp,m_szSaslPass);
+ }
+ if(!m_szSaslNick.isEmpty())
+ {
+ KviQString::sprintf(szTmp,"%QSaslNick",&szPrefix);
+ cfg->writeEntry(szTmp,m_szSaslNick);
+ }
if(!m_szRealName.isEmpty())
{
KviQString::sprintf(szTmp,"%QRealName",&szPrefix);
@@ -330,10 +350,15 @@ void KviServer::save(KviConfig * cfg, const QString & szPrefix)
KviQString::sprintf(szTmp,"%QSSL",&szPrefix);
cfg->writeEntry(szTmp,useSSL());
}
- if(supportsSTARTTLS())
+ if(!enabledSTARTTLS())
+ {
+ KviQString::sprintf(szTmp,"%QEnabledSTARTTLS",&szPrefix);
+ cfg->writeEntry(szTmp,enabledSTARTTLS());
+ }
+ if(enabledSASL())
{
- KviQString::sprintf(szTmp,"%QSupportsSTARTTLS",&szPrefix);
- cfg->writeEntry(szTmp,supportsSTARTTLS());
+ KviQString::sprintf(szTmp,"%QEnabledSASL",&szPrefix);
+ cfg->writeEntry(szTmp,enabledSASL());
}
if(proxy()!=-2)
{
diff --git a/src/kvilib/irc/kvi_ircserver.h b/src/kvilib/irc/kvi_ircserver.h
index abadae0f6..cbfe24f24 100644
--- a/src/kvilib/irc/kvi_ircserver.h
+++ b/src/kvilib/irc/kvi_ircserver.h
@@ -32,7 +32,8 @@
* \def KVI_IRCSERVER_FLAG_IPV6 Defines if the server uses IPv6
* \def KVI_IRCSERVER_FLAG_CACHEIP Defines if the server caches the IP
* \def KVI_IRCSERVER_FLAG_SSL Defines if the server uses SSL
-* \def KVI_IRCSERVER_FLAG_STARTTLS Defines if the server uses STARTTLS
+* \def KVI_IRCSERVER_FLAG_STARTTLS Defines if the server can use STARTTLS
+* \def KVI_IRCSERVER_FLAG_SASL Defines if the server can use SASL
*/
#include "kvi_settings.h"
@@ -52,6 +53,7 @@ class KviServer;
#define KVI_IRCSERVER_FLAG_CACHEIP 2
#define KVI_IRCSERVER_FLAG_SSL 4
#define KVI_IRCSERVER_FLAG_STARTTLS 8
+#define KVI_IRCSERVER_FLAG_SASL 16
/**
* \class KviServerReconnectInfo
@@ -135,6 +137,9 @@ public:
bool m_bAutoConnect; // autoconnect
QString m_szId; // the server's may-be-unique id, may be auto-generated
int m_iProxy; // proxy server's id
+ QString m_szSaslNick; // nickname for sasl auth
+ QString m_szSaslPass; // password for sasl auth
+
public:
/**
* \brief Returns the proxy server's id
@@ -162,6 +167,18 @@ public:
inline const QString & password() const { return m_szPass; };
/**
+ * \brief Returns the nickname used for sasl auth
+ * \return const QString &
+ */
+ inline const QString & saslNick() const { return m_szSaslNick; };
+
+ /**
+ * \brief Returns the password used for sasl auth
+ * \return const QString &
+ */
+ inline const QString & saslPass() const { return m_szSaslPass; };
+
+ /**
* \brief Returns the nickname of the user associated to the server
* \return const QString &
*/
@@ -273,10 +290,16 @@ public:
inline bool useSSL() const { return (m_uFlags & KVI_IRCSERVER_FLAG_SSL); };
/**
- * \brief Returns true if the server supports the STARTTLS protocol
+ * \brief Returns true if the STARTTLS protocol is enabled for this server
* \return bool
*/
- inline bool supportsSTARTTLS() const { return (m_uFlags & KVI_IRCSERVER_FLAG_STARTTLS); };
+ inline bool enabledSTARTTLS() const { return (m_uFlags & KVI_IRCSERVER_FLAG_STARTTLS); };
+
+ /**
+ * \brief Returns true if the SASL protocol is enabled for this server
+ * \return bool
+ */
+ inline bool enabledSASL() const { return (m_uFlags & KVI_IRCSERVER_FLAG_SASL); };
/**
* \brief Returns true if the server caches the IP
@@ -348,6 +371,20 @@ public:
inline void setNickName(const QString & szNick){ m_szNick = szNick; };
/**
+ * \brief Sets the password used for sasl auth
+ * \param szPass The password of the user
+ * \return void
+ */
+ inline void setSaslPass(const QString & szPass){ m_szSaslPass = szPass; };
+
+ /**
+ * \brief Sets the nickname used for sasl auth
+ * \param szNick The nick name of the user
+ * \return void
+ */
+ inline void setSaslNick(const QString & szNick){ m_szSaslNick = szNick; };
+
+ /**
* \brief Sets the realname of the user associated to the server
* \param szReal The real name of the user
* \return void
@@ -445,17 +482,28 @@ public:
};
/**
- * \brief Sets if the server supports the STARTTLS protocol
- * \param bSet Whether to set the support for STARTTLS
+ * \brief Sets if STARTTLS support is enabled/disabled for this server
+ * \param bSet Whether to enable the support for STARTTLS
* \return void
*/
- inline void setSupportsSTARTTLS(bool bSet)
+ inline void setEnabledSTARTTLS(bool bSet)
{
if(bSet)m_uFlags |= KVI_IRCSERVER_FLAG_STARTTLS;
else m_uFlags &= ((unsigned short)~KVI_IRCSERVER_FLAG_STARTTLS);
};
/**
+ * \brief Sets if SASL support is enabled/disabled for this server
+ * \param bSet Whether to enable the support for SASL
+ * \return void
+ */
+ inline void setEnabledSASL(bool bSet)
+ {
+ if(bSet)m_uFlags |= KVI_IRCSERVER_FLAG_SASL;
+ else m_uFlags &= ((unsigned short)~KVI_IRCSERVER_FLAG_SASL);
+ };
+
+ /**
* \brief Sets if the server caches the IP
* \param bSet Whether to set the cache for the IP
* \return void
diff --git a/src/kvilib/irc/kvi_ircserverdb.cpp b/src/kvilib/irc/kvi_ircserverdb.cpp
index e2f839f2f..8819fe854 100644
--- a/src/kvilib/irc/kvi_ircserverdb.cpp
+++ b/src/kvilib/irc/kvi_ircserverdb.cpp
@@ -201,7 +201,7 @@ bool KviServerDataBase::makeCurrentServer(KviServerDefinition * d, QString & szE
{
if(d->bIPv6 == srv->isIPv6())
{
- if((d->bSSL == srv->useSSL()) || (d->bSTARTTLS == srv->supportsSTARTTLS()))
+ if(d->bSSL == srv->useSSL())
{
if(d->bPortIsValid)
{
@@ -319,7 +319,7 @@ search_finished:
s->m_szInitUMode = d->szInitUMode;
s->setIPv6(d->bIPv6);
s->setUseSSL(d->bSSL);
- s->setSupportsSTARTTLS(d->bSTARTTLS);
+ s->setEnabledSTARTTLS(d->bSTARTTLS);
r->insertServer(s);
m_szCurrentNetwork = r->name();
r->setCurrentServer(s);
diff --git a/src/kvirc/kernel/kvi_ircconnection.cpp b/src/kvirc/kernel/kvi_ircconnection.cpp
index d736fe5ed..347064414 100644
--- a/src/kvirc/kernel/kvi_ircconnection.cpp
+++ b/src/kvirc/kernel/kvi_ircconnection.cpp
@@ -77,7 +77,6 @@ KviIrcConnection::KviIrcConnection(KviIrcContext * pContext,KviIrcConnectionTarg
: QObject()
{
m_bIdentdAttached = false;
- m_bInsideCapLsRequest = false;
m_pContext = pContext;
m_pConsole = pContext->console();
m_pTarget = pTarget;
@@ -324,20 +323,23 @@ void KviIrcConnection::linkEstabilished()
// And, probably, NICK hack is better then PING hack as soon as freenode
// not answer to ping!
- m_bInsideCapLsRequest = true;
+ m_pStateData->setInsideCapLs(true);
sendFmtData("CAP LS\r\nPING :%s",target()->server()->hostName().data());
}
void KviIrcConnection::handleCapLs()
{
qDebug("handleCapLs");
- m_bInsideCapLsRequest = false;
+ m_pStateData->setInsideCapLs(false);
+
+ // STARTTLS support: this has to be checked first because it could imply
+ // a full cap renegotiation
#ifdef COMPILE_SSL_SUPPORT
if(
KVI_OPTION_BOOL(KviOption_boolUseStartTlsIfAvailable) &&
(!link()->socket()->usingSSL()) &&
- (serverInfo()->supportedCaps().contains("tls",Qt::CaseInsensitive) ||
- target()->server()->supportsSTARTTLS())
+ target()->server()->enabledSTARTTLS() &&
+ serverInfo()->supportedCaps().contains("tls",Qt::CaseInsensitive)
)
{
trySTARTTLS();
@@ -345,6 +347,54 @@ void KviIrcConnection::handleCapLs()
}
#endif
+ QString szRequests;
+
+ //SASL
+ if(KVI_OPTION_BOOL(KviOption_boolUseSaslIfAvailable) &&
+ target()->server()->enabledSASL() &&
+ serverInfo()->supportedCaps().contains("sasl",Qt::CaseInsensitive)
+ )
+ {
+ szRequests.append("sasl ");
+ }
+
+ //TODO MULTI-PREFIX, others goes here
+
+ if(szRequests.isEmpty()) endCapLs();
+ else sendFmtData("CAP REQ :%s",szRequests.trimmed().toUtf8().data());
+}
+
+void KviIrcConnection::handleCapAck()
+{
+ qDebug("handleCapAck");
+
+ //SASL
+ if(KVI_OPTION_BOOL(KviOption_boolUseSaslIfAvailable) &&
+ target()->server()->enabledSASL() &&
+ serverInfo()->enabledCaps().contains("sasl",Qt::CaseInsensitive)
+ )
+ {
+ sendFmtData("AUTHENTICATE PLAIN");
+ //server will send us a "AUTHENTICATE +" answer; we won't wait for this extra step
+ QByteArray szAuth = encodeText(target()->server()->saslNick());
+ szAuth.append('\0');
+ szAuth.append(encodeText(target()->server()->saslNick()));
+ szAuth.append('\0');
+ szAuth.append(encodeText(target()->server()->saslPass()));
+ sendFmtData("AUTHENTICATE %s",szAuth.toBase64().data());
+ }
+
+ endCapLs();
+}
+
+void KviIrcConnection::handleCapNak()
+{
+ qDebug("handleCapNak");
+ endCapLs();
+}
+
+void KviIrcConnection::endCapLs()
+{
sendFmtData("CAP END");
loginToIrcServer();
}
@@ -352,7 +402,7 @@ void KviIrcConnection::handleCapLs()
void KviIrcConnection::handleFailedCapLs()
{
qDebug("handleFailedCapLs");
- m_bInsideCapLsRequest = false;
+ m_pStateData->setInsideCapLs(false);
loginToIrcServer();
}
diff --git a/src/kvirc/kernel/kvi_ircconnection.h b/src/kvirc/kernel/kvi_ircconnection.h
index 9944ea219..0928244e3 100644
--- a/src/kvirc/kernel/kvi_ircconnection.h
+++ b/src/kvirc/kernel/kvi_ircconnection.h
@@ -178,8 +178,6 @@ private:
QTextCodec * m_pSrvCodec; // connection codec: never null
QTextCodec * m_pTextCodec; // connection codec: never null
KviRequestQueue * m_pRequestQueue; // owned, never null
-
- bool m_bInsideCapLsRequest;
public:
/**
* \brief Returns a pointer to the owning console
@@ -220,12 +218,6 @@ public:
* \return State
*/
inline State state(){ return m_eState; };
-
- /**
- * \brief Returns true if the connection is waiting for an answer to a "CAP LS" request
- * \return bool
- */
- inline bool isInsideCapLsRequest(){ return m_bInsideCapLsRequest; };
/**
* \brief Returns a pointer to the big connection user database.
@@ -743,6 +735,24 @@ protected:
void handleFailedCapLs();
/**
+ * \brief Called when CAP ACK answer is received
+ * \return void
+ */
+ void handleCapAck();
+
+ /**
+ * \brief Called when CAP NAK answer is received
+ * \return void
+ */
+ void handleCapNak();
+
+ /**
+ * \brief Called when we want to end CAP negotiation and go on wi the login
+ * \return void
+ */
+ void endCapLs();
+
+ /**
* \brief Called to update the away state
* \param bAway Whether we enter the away mode
* \return void
diff --git a/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp b/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp
index ca8f91286..040d309a6 100644
--- a/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp
+++ b/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp
@@ -58,9 +58,28 @@ void KviIrcConnectionServerInfo::setSupportsCaps(QString szCaps)
{
m_bSupportsCap=true;
qDebug("server support caps: %s",szCaps.toUtf8().data());
- m_szaCap = szCaps.split(' ', QString::SkipEmptyParts);
+ m_szaSupportedCaps = szCaps.split(' ', QString::SkipEmptyParts);
}
+void KviIrcConnectionServerInfo::setEnableCaps(QString szCaps)
+{
+ qDebug("server enabled caps: %s",szCaps.toUtf8().data());
+ m_szaEnabledCaps.append(szCaps.split(' ', QString::SkipEmptyParts));
+ m_szaEnabledCaps.removeDuplicates();
+}
+
+void KviIrcConnectionServerInfo::setDisableCaps(QString szCaps)
+{
+ qDebug("server disabled caps: %s",szCaps.toUtf8().data());
+ QStringList szaDisabled = szCaps.split(' ', QString::SkipEmptyParts);
+
+ for (int i = 0; i < szaDisabled.size(); ++i)
+ {
+ m_szaEnabledCaps.removeOne(szaDisabled.at(i));
+ }
+}
+
+
void KviIrcConnectionServerInfo::setSupportedChannelModes(const QString &szSupportedChannelModes)
{
int pos=-1;
diff --git a/src/kvirc/kernel/kvi_ircconnectionserverinfo.h b/src/kvirc/kernel/kvi_ircconnectionserverinfo.h
index d1f1bdc84..293564940 100644
--- a/src/kvirc/kernel/kvi_ircconnectionserverinfo.h
+++ b/src/kvirc/kernel/kvi_ircconnectionserverinfo.h
@@ -100,7 +100,8 @@ private:
QString m_szListModes;
QString m_szPlainModes;
bool m_bSupportsCap;
- QStringList m_szaCap;
+ QStringList m_szaSupportedCaps;
+ QStringList m_szaEnabledCaps;
public:
char registerModeChar() { return m_pServInfo ? m_pServInfo->getRegisterModeChar() : 0; };
const QString & name(){ return m_szName; };
@@ -114,7 +115,8 @@ public:
bool supportsModesIe(){ return m_bSupportsModesIe; };
bool supportsModeq(){ return m_bSupportsModeq; };
bool supportsCap(){ return m_bSupportsCap; };
- QStringList supportedCaps(){ return m_szaCap; };
+ QStringList supportedCaps(){ return m_szaSupportedCaps; };
+ QStringList enabledCaps(){ return m_szaEnabledCaps; };
bool supportsWatchList(){ return m_bSupportsWatchList; };
bool supportsCodePages(){ return m_bSupportsCodePages; };
@@ -141,6 +143,8 @@ protected:
void setSupportsWatchList(bool bSupportsWatchList){ m_bSupportsWatchList = bSupportsWatchList; };
void setSupportsCodePages(bool bSupportsCodePages){ m_bSupportsCodePages = bSupportsCodePages; };
void setSupportsCaps(QString szCaps);
+ void setEnableCaps(QString szCaps);
+ void setDisableCaps(QString szCaps);
void setMaxTopicLen( int iTopLen ) { m_iMaxTopicLen=iTopLen; };
void setMaxModeChanges(int iModes ) { m_iMaxModeChanges=iModes; };
private:
diff --git a/src/kvirc/kernel/kvi_ircconnectionstatedata.cpp b/src/kvirc/kernel/kvi_ircconnectionstatedata.cpp
index 0102a227b..163ad8b28 100644
--- a/src/kvirc/kernel/kvi_ircconnectionstatedata.cpp
+++ b/src/kvirc/kernel/kvi_ircconnectionstatedata.cpp
@@ -30,6 +30,7 @@ KviIrcConnectionStateData::KviIrcConnectionStateData()
{
m_bSentStartTls = false;
m_bSentQuit = false;
+ m_bInsideCapLs = false;
m_uLoginNickIndex = 0;
m_bSimulateUnexpectedDisconnect = false;
m_tLastReceivedChannelWhoReply = kvi_unixTime();
diff --git a/src/kvirc/kernel/kvi_ircconnectionstatedata.h b/src/kvirc/kernel/kvi_ircconnectionstatedata.h
index 790456740..6fcebbef5 100644
--- a/src/kvirc/kernel/kvi_ircconnectionstatedata.h
+++ b/src/kvirc/kernel/kvi_ircconnectionstatedata.h
@@ -44,6 +44,7 @@ public:
KviIrcConnectionStateData();
~KviIrcConnectionStateData();
protected:
+ bool m_bInsideCapLs; // true if there's a CAP LS request pending
bool m_bSentStartTls; // the state of STARTTLS protocol
bool m_bSentQuit; // have we sent the quit message for this connection ?
unsigned int m_uLoginNickIndex; // the index of the identity nicknames used until now (see KviIrcConnection::loginToIrcServer())
@@ -56,6 +57,9 @@ public:
bool sentStartTls(){ return m_bSentStartTls; };
void setSentStartTls(){ m_bSentStartTls = true; };
+ bool isInsideCapLs(){ return m_bInsideCapLs; };
+ void setInsideCapLs(bool bInside){ m_bInsideCapLs = bInside; };
+
bool sentQuit(){ return m_bSentQuit; };
void setSentQuit(){ m_bSentQuit = true; };
diff --git a/src/kvirc/kernel/kvi_irccontext.cpp b/src/kvirc/kernel/kvi_irccontext.cpp
index c723b8ba8..edbbb785f 100644
--- a/src/kvirc/kernel/kvi_irccontext.cpp
+++ b/src/kvirc/kernel/kvi_irccontext.cpp
@@ -570,7 +570,7 @@ void KviIrcContext::connectToCurrentServer()
m_pSavedAsynchronousConnectionData->bPortIsOk = true;
m_pSavedAsynchronousConnectionData->bUseIPv6 = srv->isIPv6();
m_pSavedAsynchronousConnectionData->bUseSSL = srv->useSSL();
- m_pSavedAsynchronousConnectionData->bSTARTTLS = srv->supportsSTARTTLS();
+ m_pSavedAsynchronousConnectionData->bSTARTTLS = srv->enabledSTARTTLS();
m_pSavedAsynchronousConnectionData->szPass = srv->password();
m_pSavedAsynchronousConnectionData->szServerId = srv->id();
m_pSavedAsynchronousConnectionData->szInitUMode = srv->m_szInitUMode;
@@ -627,7 +627,7 @@ void KviIrcContext::connectionFailed(int iError)
d->bPortIsOk = true;
d->bUseIPv6 = oldServer.isIPv6();
d->bUseSSL = oldServer.useSSL();
- d->bSTARTTLS = oldServer.supportsSTARTTLS();
+ d->bSTARTTLS = oldServer.enabledSTARTTLS();
d->szPass = oldServer.password();
d->szNick = oldNickname;
d->szInitUMode = oldServer.m_szInitUMode;
@@ -811,7 +811,7 @@ void KviIrcContext::connectionTerminated()
d->bPortIsOk = true;
d->bUseIPv6 = oldServer.isIPv6();
d->bUseSSL = oldServer.useSSL();
- d->bSTARTTLS = oldServer.supportsSTARTTLS();
+ d->bSTARTTLS = oldServer.enabledSTARTTLS();
d->szPass = oldServer.password();
d->szInitUMode = oldServer.m_szInitUMode;
d->m_pReconnectInfo = new KviServerReconnectInfo(*(pInfo));
diff --git a/src/kvirc/kernel/kvi_options.cpp b/src/kvirc/kernel/kvi_options.cpp
index c8f5ddea2..1c095c1df 100644
--- a/src/kvirc/kernel/kvi_options.cpp
+++ b/src/kvirc/kernel/kvi_options.cpp
@@ -322,7 +322,8 @@ KviBoolOption g_boolOptionsTable[KVI_NUM_BOOL_OPTIONS]=
BOOL_OPTION("FlashDccChatWindowOnNewMessages",true,KviOption_sectFlagFrame),
BOOL_OPTION("PopupNotifierOnNewDccChatMessages",true,KviOption_sectFlagFrame),
BOOL_OPTION("UseAwayMessage",true,KviOption_sectFlagConnection),
- BOOL_OPTION("DisableQuietBanListRequestOnJoin",true,KviOption_sectFlagConnection)
+ BOOL_OPTION("DisableQuietBanListRequestOnJoin",true,KviOption_sectFlagConnection),
+ BOOL_OPTION("UseSaslIfAvailable",true,KviOption_sectFlagConnection)
};
#define STRING_OPTION(_txt,_val,_flags) KviStringOption(KVI_STRING_OPTIONS_PREFIX _txt,_val,_flags)
@@ -854,7 +855,8 @@ KviMsgTypeOption g_msgtypeOptionsTable[KVI_NUM_MSGTYPE_OPTIONS]=
MSGTYPE_OPTION("IrcOp",__tr_no_lookup("IRC Op status set"),KVI_SMALLICON_IRCOP,KVI_MSGTYPE_LEVEL_5),
MSGTYPE_OPTION("DeIrcOp",__tr_no_lookup("IRC Op status unset"),KVI_SMALLICON_DEIRCOP,KVI_MSGTYPE_LEVEL_5),
MSGTYPE_OPTION("MeIrcOp",__tr_no_lookup("Own IRC Op status set"),KVI_SMALLICON_MEIRCOP,KVI_MSGTYPE_LEVEL_5),
- MSGTYPE_OPTION("MeDeIrcOp",__tr_no_lookup("Own IRC Op status unset"),KVI_SMALLICON_MEDEIRCOP,KVI_MSGTYPE_LEVEL_5)
+ MSGTYPE_OPTION("MeDeIrcOp",__tr_no_lookup("Own IRC Op status unset"),KVI_SMALLICON_MEDEIRCOP,KVI_MSGTYPE_LEVEL_5),
+ MSGTYPE_OPTION("Cap",__tr_no_lookup("Extended capability message"),KVI_SMALLICON_SERVERINFO,KVI_MSGTYPE_LEVEL_1)
};
static const char * options_section_table[KVI_NUM_OPTION_SECT_FLAGS] =
diff --git a/src/kvirc/kernel/kvi_options.h b/src/kvirc/kernel/kvi_options.h
index 289149cab..129f77f20 100644
--- a/src/kvirc/kernel/kvi_options.h
+++ b/src/kvirc/kernel/kvi_options.h
@@ -330,8 +330,9 @@ DECLARE_OPTION_STRUCT(KviStringListOption,QStringList)
#define KviOption_boolPopupNotifierOnNewDccChatMessages 236 /* dcc:chat */
#define KviOption_boolUseAwayMessage 237 /* away */
#define KviOption_boolDisableQuietBanListRequestOnJoin 238 /* channel */
+#define KviOption_boolUseSaslIfAvailable 239
-#define KVI_NUM_BOOL_OPTIONS 239
+#define KVI_NUM_BOOL_OPTIONS 240
#define KVI_STRING_OPTIONS_PREFIX "string"
@@ -631,7 +632,7 @@ namespace KviIdentdOutputMode {
#define KVI_MSGTYPE_OPTIONS_PREFIX "msgtype"
#define KVI_MSGTYPE_OPTIONS_PREFIX_LEN 7
-#define KVI_NUM_MSGTYPE_OPTIONS 141
+#define KVI_NUM_MSGTYPE_OPTIONS 142
diff --git a/src/kvirc/kernel/kvi_out.h b/src/kvirc/kernel/kvi_out.h
index 210ad6178..ce0317d77 100644
--- a/src/kvirc/kernel/kvi_out.h
+++ b/src/kvirc/kernel/kvi_out.h
@@ -165,8 +165,9 @@
#define KVI_OUT_DEIRCOP 138
#define KVI_OUT_MEIRCOP 139
#define KVI_OUT_MEDEIRCOP 140
+#define KVI_OUT_CAP 141
-//#define KVI_NUM_MSGTYPE_OPTIONS 141
+//#define KVI_NUM_MSGTYPE_OPTIONS 142
// UPDATE THE TOTAL COUNT IN kvi_options.h !!!!
diff --git a/src/kvirc/sparser/kvi_numeric.h b/src/kvirc/sparser/kvi_numeric.h
index f88ac5285..4692d87be 100644
--- a/src/kvirc/sparser/kvi_numeric.h
+++ b/src/kvirc/sparser/kvi_numeric.h
@@ -368,10 +368,17 @@
#define RPL_ENDOFWATCH 607 /* :End of WATCH <char l=list s=stats> [D] # */
// STARTTLS extension
#define RPL_STARTTLSOK 670 /* :test2.chatspike.net 670 nickname :STARTTLS successful, go ahead with TLS handshake */
-#define RPL_STARTTLSFAIL 671 /* :test2.chatspike.net 671 nickname :STARTTLS failure */
+#define RPL_STARTTLSFAIL 691 /* :test2.chatspike.net 671 nickname :STARTTLS failure */
// WeNet codepage extension
#define RPL_CODEPAGESET 700 /* :irc.wenet.ru 700 Pragma CP1251 :is now your translation scheme # */
#define RPL_WHOISSCHEME 703 /* :interdacom.vgd.wenet.ru 703 Alexey Begemot KOI8-R :translation scheme */
+//SASL EXTENSION
+#define RPL_SASLLOGIN 900 /* :jaguar.test 900 jilles jilles!jilles@localhost.stack.nl jilles :You are now logged in as jilles. */
+#define RPL_SASLSUCCESS 903 /* :jaguar.test 903 jilles :SASL authentication successful */
+#define RPL_SASLFAILED 904 /* :lindbohm.freenode.net 904 * :SASL authentication failed */
+#define RPL_SASLERROR 905 // alternative error message
+#define RPL_SASLABORT 906 // sasl authentication aborted
+#define RPL_SASLALREADYAUTH 907 // can't authenticate: already authenticated
///* 303 */ RPL_ISON, ":",
///* 304 */ RPL_TEXT, (char *)NULL,
diff --git a/src/kvirc/sparser/kvi_sp_literal.cpp b/src/kvirc/sparser/kvi_sp_literal.cpp
index 0eb384424..24ff39e8e 100644
--- a/src/kvirc/sparser/kvi_sp_literal.cpp
+++ b/src/kvirc/sparser/kvi_sp_literal.cpp
@@ -1988,19 +1988,58 @@ void KviServerParser::parseLiteralCap(KviIrcMessage *msg)
// CAP
// CAP LS
// :prefix CAP * LS :tls userhost-in-names multi-prefix sasl
- // Other subcommands:
- // LIST, REQ, ACK, NAK, CLEAR, END
+
+ // Server2client subcommands:
+ // LIST, LS, ACK, NAK
+ // Client2server subcommands:
+ // LIST, LS, REQ, CLEAR, END
debug("Parsing literal CAP...");
QString szPrefix = msg->connection()->decodeText(msg->safePrefix());
QString szCmd = msg->connection()->decodeText(msg->safeParam(1));
QString szProtocols = msg->connection()->decodeText(msg->safeParam(2));
- debug("Prefix: %s\nPar1: %s\nPar2: %s",szPrefix.toUtf8().data(),szCmd.toUtf8().data(),szProtocols.toUtf8().data());
-
if(szCmd == "LS")
{
msg->connection()->serverInfo()->setSupportsCaps(szProtocols);
msg->connection()->handleCapLs();
+ } else if(szCmd == "ACK") {
+ if(!msg->haltOutput())
+ {
+ msg->console()->output(KVI_OUT_CAP,
+ __tr2qs("Enabled CAP Extensions: %Q"),
+ &szProtocols);
+ }
+ msg->connection()->serverInfo()->setEnableCaps(szProtocols);
+ msg->connection()->handleCapAck();
+ } else if(szCmd == "NAK") {
+ if(!msg->haltOutput())
+ {
+ msg->console()->output(KVI_OUT_CAP,
+ __tr2qs("Disabled CAP Extensions: %Q"),
+ &szProtocols);
+ }
+ msg->connection()->serverInfo()->setDisableCaps(szProtocols);
+ msg->connection()->handleCapNak();
+ } else if(szCmd == "LIST") {
+ if(!msg->haltOutput())
+ {
+ msg->console()->output(KVI_OUT_CAP,
+ __tr2qs("Currently enabled CAP Extensions: %Q"),
+ &szProtocols);
+ }
+ } else {
+ if(!msg->haltOutput())
+ {
+ msg->console()->output(KVI_OUT_CAP,
+ __tr2qs("Received unknown extended capability message: %Q %Q"),
+ &szCmd, &szProtocols);
+ }
}
}
+
+void KviServerParser::parseLiteralAuthenticate(KviIrcMessage *)
+{
+ // :prefix AUTHENTICATE +
+ // we don't wait for this when authenticating, so no real handling is needed here
+} \ No newline at end of file
diff --git a/src/kvirc/sparser/kvi_sp_numeric.cpp b/src/kvirc/sparser/kvi_sp_numeric.cpp
index f946682fc..16088be58 100644
--- a/src/kvirc/sparser/kvi_sp_numeric.cpp
+++ b/src/kvirc/sparser/kvi_sp_numeric.cpp
@@ -2193,6 +2193,50 @@ void KviServerParser::parseNumericNotRegistered(KviIrcMessage * msg)
// 451: ERR_NOTREGISTERED
// :prefix 451 PING :You have not registered
- if(msg->connection()->isInsideCapLsRequest())
+ if(msg->connection()->stateData()->isInsideCapLs())
msg->connection()->handleFailedCapLs();
}
+
+// SASL support
+void KviServerParser::parseNumericSaslLogin(KviIrcMessage * msg)
+{
+ // 900: RPL_SASLLOGIN
+ // :prefix 900 <nickname> <usermask> <authuser>: You are now logged in as <authuser>
+ if(!msg->haltOutput())
+ {
+ KviWindow * pOut = (KviWindow *)(msg->console());
+ QString szParam=msg->connection()->decodeText(msg->safeParam(2));
+ pOut->output(KVI_OUT_SERVERINFO,__tr2qs("Authenticated as %Q"),
+ &szParam
+ );
+ }
+}
+
+void KviServerParser::parseNumericSaslSuccess(KviIrcMessage * msg)
+{
+ // 903: RPL_SASLSUCCESS
+ // :prefix 903 <nickname> :SASL authentication successful
+ if(!msg->haltOutput())
+ {
+ KviWindow * pOut = (KviWindow *)(msg->console());
+ pOut->outputNoFmt(KVI_OUT_SERVERINFO,__tr2qs("SASL authentication successful"));
+ }
+}
+
+void KviServerParser::parseNumericSaslFail(KviIrcMessage * msg)
+{
+ // 904: RPL_SASLFAILED
+ // :prefix 904 * :SASL authentication failed
+
+ // 906: RPL_SASLBORTED
+ // :prefix 906 <nickname> :SASL authentication aborted
+
+ if(!msg->haltOutput())
+ {
+ KviWindow * pOut = (KviWindow *)(msg->console());
+ QString szParam=msg->connection()->decodeText(msg->safeTrailing());
+ pOut->output(KVI_OUT_SERVERINFO,__tr2qs("SASL Authentication error: %Q"),
+ &szParam
+ );
+ }
+}
diff --git a/src/kvirc/sparser/kvi_sp_tables.cpp b/src/kvirc/sparser/kvi_sp_tables.cpp
index 7528af073..53d113cfc 100644
--- a/src/kvirc/sparser/kvi_sp_tables.cpp
+++ b/src/kvirc/sparser/kvi_sp_tables.cpp
@@ -29,22 +29,23 @@
KviLiteralMessageParseStruct KviServerParser::m_literalParseProcTable[]=
{
- { "CAP" , PTM(parseLiteralCap) },
- { "ERROR" , PTM(parseLiteralError) },
- { "INVITE" , PTM(parseLiteralInvite) },
- { "JOIN" , PTM(parseLiteralJoin) },
- { "KICK" , PTM(parseLiteralKick) },
- { "MODE" , PTM(parseLiteralMode) },
- { "NICK" , PTM(parseLiteralNick) },
- { "NOTICE" , PTM(parseLiteralNotice) },
- { "PART" , PTM(parseLiteralPart) },
- { "PING" , PTM(parseLiteralPing) },
- { "PONG" , PTM(parseLiteralPong) },
- { "PRIVMSG" , PTM(parseLiteralPrivmsg)},
- { "QUIT" , PTM(parseLiteralQuit) },
- { "TOPIC" , PTM(parseLiteralTopic) },
- { "WALLOPS" , PTM(parseLiteralWallops)},
- { 0 , 0 }
+ { "AUTHENTICATE" , PTM(parseLiteralAuthenticate) },
+ { "CAP" , PTM(parseLiteralCap) },
+ { "ERROR" , PTM(parseLiteralError) },
+ { "INVITE" , PTM(parseLiteralInvite) },
+ { "JOIN" , PTM(parseLiteralJoin) },
+ { "KICK" , PTM(parseLiteralKick) },
+ { "MODE" , PTM(parseLiteralMode) },
+ { "NICK" , PTM(parseLiteralNick) },
+ { "NOTICE" , PTM(parseLiteralNotice) },
+ { "PART" , PTM(parseLiteralPart) },
+ { "PING" , PTM(parseLiteralPing) },
+ { "PONG" , PTM(parseLiteralPong) },
+ { "PRIVMSG" , PTM(parseLiteralPrivmsg) },
+ { "QUIT" , PTM(parseLiteralQuit) },
+ { "TOPIC" , PTM(parseLiteralTopic) },
+ { "WALLOPS" , PTM(parseLiteralWallops) },
+ { 0 , 0 }
};
// FIXME: #warning "Merge these two tables into one"
@@ -987,14 +988,14 @@ messageParseProc KviServerParser::m_numericParseProcTable[1000]=
0, // 897
0, // 898
0, // 899
- 0, // 900
- 0, // 901
+ PTM(parseNumericSaslLogin), // 900 RPL_SASLLOGIN
+ 0, // 901
0, // 902
- 0, // 903
- 0, // 904
- 0, // 905
- 0, // 906
- 0, // 907
+ PTM(parseNumericSaslSuccess), // 903 RPL_SASLSUCCESS
+ PTM(parseNumericSaslFail), // 904 RPL_SASLFAILED
+ PTM(parseNumericSaslFail), // 905 RPL_SASLERROR
+ PTM(parseNumericSaslFail), // 906 RPL_SASLABORT
+ PTM(parseNumericSaslFail), // 907 RPL_SASLALREADYAUTH
0, // 908
0, // 909
0, // 910
diff --git a/src/kvirc/sparser/kvi_sparser.h b/src/kvirc/sparser/kvi_sparser.h
index 2e0777440..9bb928760 100644
--- a/src/kvirc/sparser/kvi_sparser.h
+++ b/src/kvirc/sparser/kvi_sparser.h
@@ -222,7 +222,8 @@ private:
void parseChannelMode(const QString &szNick,const QString &szUser,const QString &szHost,KviChannel * chan,KviStr &modefl,KviIrcMessage *msg,int curParam);
void parseUserMode(KviIrcMessage *msg,const char * modeflptr);
void parseLiteralCap(KviIrcMessage * msg);
-
+ void parseLiteralAuthenticate(KviIrcMessage * msg);
+
void parseCtcpRequest(KviCtcpMessage *msg);
void parseCtcpReply(KviCtcpMessage *msg);
void echoCtcpRequest(KviCtcpMessage *msg);
@@ -249,6 +250,11 @@ private:
// STARTTLS support
void parseNumericStartTls(KviIrcMessage * msg);
void parseNumericNotRegistered(KviIrcMessage * msg);
+ //sasl
+ void parseNumericSaslSuccess(KviIrcMessage * msg);
+ void parseNumericSaslLogin(KviIrcMessage * msg);
+ void parseNumericSaslFail(KviIrcMessage * msg);
+
public:
static void encodeCtcpParameter(const char * param,KviStr &buffer,bool bSpaceBreaks = true);
static void encodeCtcpParameter(const char * param,QString &buffer,bool bSpaceBreaks = true);
diff --git a/src/modules/options/optw_connection.cpp b/src/modules/options/optw_connection.cpp
index 41779fabf..8b09172cc 100644
--- a/src/modules/options/optw_connection.cpp
+++ b/src/modules/options/optw_connection.cpp
@@ -86,7 +86,11 @@ KviConnectionOptionsWidget::KviConnectionOptionsWidget(QWidget * parent)
connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>0 sec</b><br>Maximum value: <b>86400 sec</b></center>","options"));
- addRowSpacer(0,2,4,2);
+ b = addBoolSelector(this,__tr2qs_ctx("Use the SASL authentication protocol if available","options"),&(KVI_OPTION_BOOL(KviOption_boolUseSaslIfAvailable)),true);
+ mergeTip(b,__tr2qs_ctx("<center>When available and enabled of the specific server, KVIrc will try to authenticate the user using the SASL procotol</center>","options"));
+ addWidgetToLayout(b,0,2,0,2);
+
+ addRowSpacer(0,3,4,3);
}
KviConnectionOptionsWidget::~KviConnectionOptionsWidget()
diff --git a/src/modules/options/optw_servers.cpp b/src/modules/options/optw_servers.cpp
index 3f2fdebac..c1c49ff26 100644
--- a/src/modules/options/optw_servers.cpp
+++ b/src/modules/options/optw_servers.cpp
@@ -585,8 +585,6 @@ KviServerDetailsWidget::KviServerDetailsWidget(QWidget * par,KviServer * s)
KviTalToolTip::add(m_pPortEditor,__tr2qs_ctx("<center>This is the default <b>port</b> that this server will be contacted on.<br>Usually <b>6667</b> is OK.</center>","options"));
connect(m_pPortEditor,SIGNAL(textChanged(const QString &)),this,SLOT(portEditorTextChanged(const QString &)));
-
-
l = new QLabel(__tr2qs_ctx("IP address:","options"),tab);
gl->addWidget(l,1,0);
m_pIpEditor = new KviIpEditor(tab,KviIpEditor::IPv4);
@@ -644,14 +642,14 @@ KviServerDetailsWidget::KviServerDetailsWidget(QWidget * par,KviServer * s)
#endif
m_pUseSSLCheck->setChecked(s->useSSL());
- m_pSupportsSTARTTLSCheck = new QCheckBox(__tr2qs_ctx("Supports STARTTLS protocol","options"),tab);
- gl->addWidget(m_pSupportsSTARTTLSCheck,5,0,1,2);
- KviTalToolTip::add(m_pSupportsSTARTTLSCheck,__tr2qs_ctx("<center>This check marks the server as dynamically supporting the <b>Transport Layer Security</b> " \
- "protocol. If you enable the proper global option in the Connection/SSL tab, the TLS protocol will be used for this server.</center>","options"));
+ m_pEnableSTARTTLSCheck = new QCheckBox(__tr2qs_ctx("Enable STARTTLS protocol","options"),tab);
+ gl->addWidget(m_pEnableSTARTTLSCheck,5,0,1,2);
+ KviTalToolTip::add(m_pEnableSTARTTLSCheck,__tr2qs_ctx("<center>This check enables the use of the <b>Transport Layer Security</b> " \
+ "protocol. If you enable the proper global option in the Connection/SSL tab, the TLS protocol will be used for this server if available.</center>","options"));
#ifndef COMPILE_SSL_SUPPORT
- m_pSupportsSTARTTLSCheck->setEnabled(false);
+ m_pEnableSTARTTLSCheck->setEnabled(false);
#endif
- m_pSupportsSTARTTLSCheck->setChecked(s->supportsSTARTTLS());
+ m_pEnableSTARTTLSCheck->setChecked(s->enabledSTARTTLS());
m_pUseAutoConnect = new QCheckBox(__tr2qs_ctx("Connect to this server at startup","options"),tab);
m_pUseAutoConnect->setChecked(s->autoConnect());
@@ -772,11 +770,30 @@ KviServerDetailsWidget::KviServerDetailsWidget(QWidget * par,KviServer * s)
if(m_pProxyEditor->count() > (s->proxy()+2))
m_pProxyEditor->setCurrentIndex(s->proxy()+2);
+ m_pEnableSASLCheck = new QCheckBox(__tr2qs_ctx("Enable SASL authentication","options"),tab);
+ gl->addWidget(m_pEnableSASLCheck,12,0,1,2);
+ KviTalToolTip::add(m_pEnableSASLCheck,__tr2qs_ctx("<center>This check enables the use of the <b>SASL</b> authentication procotol" \
+ "If you enable the proper global option in the Connection/SSL tab and fill the Sasl Nickname and Sasl Password fields in this page, the SASL protocol will be used for this server if available.</center>","options"));
+ m_pEnableSASLCheck->setChecked(s->enabledSASL());
+
+ l = new QLabel(__tr2qs_ctx("Sasl Nickname:","options"),tab);
+ gl->addWidget(l,13,0);
+ m_pSaslNickEditor = new QLineEdit(tab);
+ m_pSaslNickEditor->setText(s->saslNick());
+ KviTalToolTip::add(m_pSaslNickEditor,__tr2qs_ctx("<center>If you want to enable SASL authentication, insert your nickname here.</center>","options"));
+ gl->addWidget(m_pSaslNickEditor,13,1);
+
+ l = new QLabel(__tr2qs_ctx("Sasl Password:","options"),tab);
+ gl->addWidget(l,14,0);
+ m_pSaslPassEditor = new KviPasswordLineEdit(tab);
+ m_pSaslPassEditor->setText(s->saslPass());
+ KviTalToolTip::add(m_pSaslPassEditor,__tr2qs_ctx("<center>If you want to enable SASL authentication, insert your password here.</center>","options"));
+ gl->addWidget(m_pSaslPassEditor,14,1);
l = new QLabel("",tab);
- gl->addWidget(l,12,0,1,2);
+ gl->addWidget(l,15,0,1,2);
- gl->setRowStretch(12,1);
+ gl->setRowStretch(15,1);
tw->addTab(tab,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SOCKETWARNING)),__tr2qs_ctx("Connection","options"));
@@ -925,8 +942,16 @@ void KviServerDetailsWidget::fillData(KviServer * s)
s->setCacheIp(m_pCacheIpCheck->isChecked());
if(m_pUseSSLCheck)
s->setUseSSL(m_pUseSSLCheck->isChecked());
- if(m_pSupportsSTARTTLSCheck)
- s->setSupportsSTARTTLS(m_pSupportsSTARTTLSCheck->isChecked());
+ if(m_pEnableSTARTTLSCheck)
+ s->setEnabledSTARTTLS(m_pEnableSTARTTLSCheck->isChecked());
+
+ s->setSaslNick(m_pSaslNickEditor->text());
+ s->setSaslPass(m_pSaslPassEditor->text());
+ s->setEnabledSASL( m_pEnableSASLCheck->isChecked() &&
+ !m_pSaslNickEditor->text().isEmpty() &&
+ !m_pSaslPassEditor->text().isEmpty()
+ );
+
if(m_pIdEditor)
s->setId(m_pIdEditor->text());
if(s->id().isEmpty())s->generateUniqueId();
diff --git a/src/modules/options/optw_servers.h b/src/modules/options/optw_servers.h
index 9ba0046d4..5b14e8f22 100644
--- a/src/modules/options/optw_servers.h
+++ b/src/modules/options/optw_servers.h
@@ -115,7 +115,9 @@ protected:
KviScriptEditor * m_pOnLoginEditor;
QLineEdit * m_pUserEditor;
KviPasswordLineEdit * m_pPassEditor;
+ KviPasswordLineEdit * m_pSaslPassEditor;
QLineEdit * m_pNickEditor;
+ QLineEdit * m_pSaslNickEditor;
QLineEdit * m_pRealEditor;
QLineEdit * m_pDescEditor;
QLineEdit * m_pIdEditor;
@@ -125,7 +127,8 @@ protected:
KviIpEditor * m_pIpEditor;
QCheckBox * m_pCacheIpCheck;
QCheckBox * m_pUseSSLCheck;
- QCheckBox * m_pSupportsSTARTTLSCheck;
+ QCheckBox * m_pEnableSTARTTLSCheck;
+ QCheckBox * m_pEnableSASLCheck;
QCheckBox * m_pUseDefaultInitUMode;
QCheckBox * m_pIMode;
QCheckBox * m_pWMode;