diff options
| author | 2010-02-12 12:13:14 +0000 | |
|---|---|---|
| committer | 2010-02-12 12:13:14 +0000 | |
| commit | 4ac4cca26dad417ff9a3a2b92963f6f2d09d1fe7 (patch) | |
| tree | bc1988090af0dec1f6aca3db27d050915ea2662d /src | |
| parent | fix for #703 (diff) | |
| download | KVIrc-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
Diffstat (limited to 'src')
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnection.cpp | 94 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnection.h | 31 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnectionserverinfo.cpp | 8 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnectionserverinfo.h | 7 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_irccontext.cpp | 1 | ||||
| -rw-r--r-- | src/kvirc/sparser/kvi_sp_literal.cpp | 7 | ||||
| -rw-r--r-- | src/kvirc/sparser/kvi_sp_numeric.cpp | 7 |
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(); } |
