aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Fabio Bas2010-02-12 12:13:14 +0000
committerGravatar Fabio Bas2010-02-12 12:13:14 +0000
commit4ac4cca26dad417ff9a3a2b92963f6f2d09d1fe7 (patch)
treebc1988090af0dec1f6aca3db27d050915ea2662d
parentfix for #703 (diff)
downloadKVIrc-4ac4cca26dad417ff9a3a2b92963f6f2d09d1fe7.tar.gz
KVIrc-4ac4cca26dad417ff9a3a2b92963f6f2d09d1fe7.tar.bz2
KVIrc-4ac4cca26dad417ff9a3a2b92963f6f2d09d1fe7.zip
Try to check server extended capabilities using CAP LS and use STARTTLS if enabled
tested working on: ircnet efnet undernet freenode chatspike azzurra git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@3957 17fca916-40b9-46aa-a4ea-0a15b648b75c
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.cpp94
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.h31
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp8
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionserverinfo.h7
-rw-r--r--src/kvirc/kernel/kvi_irccontext.cpp1
-rw-r--r--src/kvirc/sparser/kvi_sp_literal.cpp7
-rw-r--r--src/kvirc/sparser/kvi_sp_numeric.cpp7
7 files changed, 77 insertions, 78 deletions
diff --git a/src/kvirc/kernel/kvi_ircconnection.cpp b/src/kvirc/kernel/kvi_ircconnection.cpp
index 8ca8d138e..d736fe5ed 100644
--- a/src/kvirc/kernel/kvi_ircconnection.cpp
+++ b/src/kvirc/kernel/kvi_ircconnection.cpp
@@ -77,6 +77,7 @@ KviIrcConnection::KviIrcConnection(KviIrcContext * pContext,KviIrcConnectionTarg
: QObject()
{
m_bIdentdAttached = false;
+ m_bInsideCapLsRequest = false;
m_pContext = pContext;
m_pConsole = pContext->console();
m_pTarget = pTarget;
@@ -314,23 +315,45 @@ void KviIrcConnection::linkEstabilished()
// FIXME: With STARTTLS this is called TWICE!
context()->connectionEstabilished();
+ // Ok...we're loggin in now
+ resolveLocalHost();
+
+ // HACK: this is needed to avoid timeouts connecting
+ // This MUST go as one network packet to avoid possible handshake problems
+ // on slow connections.
+
+ // And, probably, NICK hack is better then PING hack as soon as freenode
+ // not answer to ping!
+ m_bInsideCapLsRequest = true;
+ sendFmtData("CAP LS\r\nPING :%s",target()->server()->hostName().data());
+}
+
+void KviIrcConnection::handleCapLs()
+{
+ qDebug("handleCapLs");
+ m_bInsideCapLsRequest = false;
#ifdef COMPILE_SSL_SUPPORT
if(
KVI_OPTION_BOOL(KviOption_boolUseStartTlsIfAvailable) &&
- target()->server()->supportsSTARTTLS() &&
- (!link()->socket()->usingSSL())
+ (!link()->socket()->usingSSL()) &&
+ (serverInfo()->supportedCaps().contains("tls",Qt::CaseInsensitive) ||
+ target()->server()->supportsSTARTTLS())
)
{
trySTARTTLS();
- } else {
-#endif
- // Ok...we're loggin in now
- resolveLocalHost();
-
- loginToIrcServer();
-#ifdef COMPILE_SSL_SUPPORT
+ return;
}
#endif
+
+ sendFmtData("CAP END");
+ loginToIrcServer();
+}
+
+void KviIrcConnection::handleFailedCapLs()
+{
+ qDebug("handleFailedCapLs");
+ m_bInsideCapLsRequest = false;
+ loginToIrcServer();
}
void KviIrcConnection::linkTerminated()
@@ -933,57 +956,19 @@ void KviIrcConnection::hostNameLookupTerminated(KviDns *)
m_pLocalhostDns = 0;
}
-void KviIrcConnection::checkCapSupport()
-{
- debug("Sending CAP LS command...");
-
- // Check if the server supports CAP module to discover protocols
- if(!sendFmtData("CAP LS"))
- {
- // Cannot send command
- m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Impossible to send CAP LS command to the IRC server. Your connection will NOT be encrypted"));
- return;
- }
-}
-
-void KviIrcConnection::closeCap()
-{
- // Closing CAPabilies discovery
- if(!sendFmtData("CAP END"))
- {
- // Cannot send command
- m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Impossible to send CAP END command to the IRC server. Your connection will NOT be encrypted"));
- }
-
- // Ok, login the user
- return loginToIrcServer();
-}
-
#ifdef COMPILE_SSL_SUPPORT
void KviIrcConnection::trySTARTTLS()
{
// Check if the server supports STARTTLS protocol and we want to
// connect through it
- debug("Checking STARTTLS support...");
- KviServer * pServer = target()->server();
-
- if(pServer->supportsSTARTTLS())
+ debug("Sending STARTTLS command...");
+ if(!sendFmtData("STARTTLS"))
{
- debug("Sending STARTTLS command...");
- // HACK: this is needed to avoid timeouts connecting
- // This MUST go as one network packet to avoid possible handshake problems
- // on slow connections.
-
- // And, probably, NICK hack is better then PING hack as soon as freenode
- // not answer to ping!
- if(!sendFmtData("STARTTLS\n\rPING :%s",pServer->hostName().data()))
- {
- // Cannot send command
- m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Impossible to send STARTTLS command to the IRC server. Your connection will NOT be encrypted"));
- return;
- }
- m_pStateData->setSentStartTls();
+ // Cannot send command
+ m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Impossible to send STARTTLS command to the IRC server. Your connection will NOT be encrypted"));
+ return;
}
+ m_pStateData->setSentStartTls();
}
void KviIrcConnection::enableStartTlsSupport(bool bEnable)
@@ -997,8 +982,6 @@ void KviIrcConnection::enableStartTlsSupport(bool bEnable)
} else {
// The server does not support STARTTLS
m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("The server does not support STARTTLS command. Your connection will NOT be encrypted"));
-
- loginToIrcServer();
}
}
#endif // COMPILE_SSL_SUPPORT
@@ -1109,7 +1092,6 @@ void KviIrcConnection::loginToIrcServer()
m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Logging in as %Q!%Q :%Q"),
&(m_pUserInfo->nickName()),&(m_pUserInfo->userName()),&(m_pUserInfo->realName()));
-
// spity, 27.03.2005: follow the RFC2812 suggested order for connection registration
// first the PASS, then NICK and then USER
diff --git a/src/kvirc/kernel/kvi_ircconnection.h b/src/kvirc/kernel/kvi_ircconnection.h
index f469bcdb0..9944ea219 100644
--- a/src/kvirc/kernel/kvi_ircconnection.h
+++ b/src/kvirc/kernel/kvi_ircconnection.h
@@ -179,6 +179,7 @@ private:
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
@@ -221,6 +222,12 @@ public:
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.
*
* The database contains ALL the users KVIrc can "see" in this connection.
@@ -682,18 +689,6 @@ protected:
*/
void resolveLocalHost();
- /**
- * \brief Checks if the server supports the CAPabilities protocol
- * \return void
- */
- void checkCapSupport();
-
- /**
- * \brief Called to close the CAPabilities negotiation
- * \return void
- */
- void closeCap();
-
#ifdef COMPILE_SSL_SUPPORT
void trySTARTTLS();
void enableStartTlsSupport(bool bEnable);
@@ -736,6 +731,18 @@ protected:
void serverInfoReceived(const QString & szServerName, const QString & szUserModes, const QString & szChanModes);
/**
+ * \brief Called when CAP LS answer is received
+ * \return void
+ */
+ void handleCapLs();
+
+ /**
+ * \brief Called when CAP LS negotiation fails
+ * \return void
+ */
+ void handleFailedCapLs();
+
+ /**
* \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 d00e58aa3..ca8f91286 100644
--- a/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp
+++ b/src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp
@@ -40,6 +40,7 @@ KviIrcConnectionServerInfo::KviIrcConnectionServerInfo()
m_bSupportsModesIe = true;
m_bSupportsWatchList = false;
m_bSupportsCodePages = false;
+ m_bSupportsCap = false;
m_iMaxTopicLen=-1;
m_szListModes="";
m_szPlainModes="";
@@ -53,6 +54,13 @@ KviIrcConnectionServerInfo::~KviIrcConnectionServerInfo()
if(m_pModePrefixTable) kvi_free(m_pModePrefixTable);
}
+void KviIrcConnectionServerInfo::setSupportsCaps(QString szCaps)
+{
+ m_bSupportsCap=true;
+ qDebug("server support caps: %s",szCaps.toUtf8().data());
+ m_szaCap = szCaps.split(' ', QString::SkipEmptyParts);
+}
+
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 eea8baf98..d1f1bdc84 100644
--- a/src/kvirc/kernel/kvi_ircconnectionserverinfo.h
+++ b/src/kvirc/kernel/kvi_ircconnectionserverinfo.h
@@ -28,6 +28,8 @@
#include "kvi_qstring.h"
#include "kvi_inttypes.h"
+#include <QStringList>
+
class KVIRC_API KviBasicIrcServerInfo
{
protected:
@@ -97,6 +99,8 @@ private:
int m_iMaxModeChanges;
QString m_szListModes;
QString m_szPlainModes;
+ bool m_bSupportsCap;
+ QStringList m_szaCap;
public:
char registerModeChar() { return m_pServInfo ? m_pServInfo->getRegisterModeChar() : 0; };
const QString & name(){ return m_szName; };
@@ -109,6 +113,8 @@ public:
const QString & supportedPlainModes(){ return m_szPlainModes; };
bool supportsModesIe(){ return m_bSupportsModesIe; };
bool supportsModeq(){ return m_bSupportsModeq; };
+ bool supportsCap(){ return m_bSupportsCap; };
+ QStringList supportedCaps(){ return m_szaCap; };
bool supportsWatchList(){ return m_bSupportsWatchList; };
bool supportsCodePages(){ return m_bSupportsCodePages; };
@@ -134,6 +140,7 @@ protected:
void setSupportedChannelTypes(const QString &szSupportedChannelTypes){ m_szSupportedChannelTypes = szSupportedChannelTypes; };
void setSupportsWatchList(bool bSupportsWatchList){ m_bSupportsWatchList = bSupportsWatchList; };
void setSupportsCodePages(bool bSupportsCodePages){ m_bSupportsCodePages = bSupportsCodePages; };
+ void setSupportsCaps(QString szCaps);
void setMaxTopicLen( int iTopLen ) { m_iMaxTopicLen=iTopLen; };
void setMaxModeChanges(int iModes ) { m_iMaxModeChanges=iModes; };
private:
diff --git a/src/kvirc/kernel/kvi_irccontext.cpp b/src/kvirc/kernel/kvi_irccontext.cpp
index b5c88c1d3..c723b8ba8 100644
--- a/src/kvirc/kernel/kvi_irccontext.cpp
+++ b/src/kvirc/kernel/kvi_irccontext.cpp
@@ -666,6 +666,7 @@ enter_idle_state:
void KviIrcContext::connectionEstabilished()
{
+ qDebug("context::connectionEstabilished");
//
// The connection has been estabilished, the
// KviIrcConnection will attempt to login now
diff --git a/src/kvirc/sparser/kvi_sp_literal.cpp b/src/kvirc/sparser/kvi_sp_literal.cpp
index 91907a3bc..0eb384424 100644
--- a/src/kvirc/sparser/kvi_sp_literal.cpp
+++ b/src/kvirc/sparser/kvi_sp_literal.cpp
@@ -1998,12 +1998,9 @@ void KviServerParser::parseLiteralCap(KviIrcMessage *msg)
debug("Prefix: %s\nPar1: %s\nPar2: %s",szPrefix.toUtf8().data(),szCmd.toUtf8().data(),szProtocols.toUtf8().data());
- bool bEnable = false;
if(szCmd == "LS")
{
- QStringList szList = szProtocols.split(" ");
- if(szList.contains("tls")) bEnable = true;
+ msg->connection()->serverInfo()->setSupportsCaps(szProtocols);
+ msg->connection()->handleCapLs();
}
-
- //msg->connection()->checkStartTlsSupport(bEnable);
}
diff --git a/src/kvirc/sparser/kvi_sp_numeric.cpp b/src/kvirc/sparser/kvi_sp_numeric.cpp
index 57090b7e0..f946682fc 100644
--- a/src/kvirc/sparser/kvi_sp_numeric.cpp
+++ b/src/kvirc/sparser/kvi_sp_numeric.cpp
@@ -2193,9 +2193,6 @@ void KviServerParser::parseNumericNotRegistered(KviIrcMessage * msg)
// 451: ERR_NOTREGISTERED
// :prefix 451 PING :You have not registered
- KviIrcConnectionStateData * pStateData = msg->connection()->stateData();
- #ifdef COMPILE_SSL_SUPPORT
- if(pStateData->sentStartTls())
- msg->connection()->enableStartTlsSupport(false);
- #endif
+ if(msg->connection()->isInsideCapLsRequest())
+ msg->connection()->handleFailedCapLs();
}