diff options
| author | 2011-12-21 04:30:08 +0000 | |
|---|---|---|
| committer | 2011-12-21 04:30:08 +0000 | |
| commit | 72e767c54de4dd534d7ceed50f8845dc03870a66 (patch) | |
| tree | fc5e99921e639de0b63d9f0c62ae4e9fb564066c | |
| parent | StartTls and Sasl are now per-server options. These are no longer needed. (diff) | |
| download | KVIrc-72e767c54de4dd534d7ceed50f8845dc03870a66.tar.gz KVIrc-72e767c54de4dd534d7ceed50f8845dc03870a66.tar.bz2 KVIrc-72e767c54de4dd534d7ceed50f8845dc03870a66.zip | |
Allow STARTTLS to be used also without CAP support.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5997 17fca916-40b9-46aa-a4ea-0a15b648b75c
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnection.cpp | 102 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnection.h | 3 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnectionStateData.cpp | 1 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnectionStateData.h | 12 | ||||
| -rw-r--r-- | src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp | 22 | ||||
| -rw-r--r-- | src/modules/options/OptionsWidget_servers.cpp | 28 |
6 files changed, 114 insertions, 54 deletions
diff --git a/src/kvirc/kernel/KviIrcConnection.cpp b/src/kvirc/kernel/KviIrcConnection.cpp index ae94c7f98..922659476 100644 --- a/src/kvirc/kernel/KviIrcConnection.cpp +++ b/src/kvirc/kernel/KviIrcConnection.cpp @@ -365,11 +365,73 @@ void KviIrcConnection::linkEstabilished() // FIXME: The PING method does NOT work with bouncers. We need a timeout here. - sendFmtData("CAP LS\r\nPING :%Q",&(target()->server()->hostName())); + if(sendFmtData("CAP LS\r\nPING :%Q",&(target()->server()->hostName()))) + return; + + m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Failed to send the CAP LS request. Server capabilities will not be detected.")); + } + + if( + (!link()->socket()->usingSSL()) && + target()->server()->enabledSTARTTLS() + ) + { + // STARTTLS without CAP (forced request) + + m_pStateData->setInsideInitialStartTls(true); + m_pStateData->setIgnoreOneYouHaveNotRegisteredError(true); + + // STARTTLS requested but CAP not requested. + if(trySTARTTLS(true)) + return; // STARTTLS negotiation in progress + + m_pStateData->setInsideInitialStartTls(false); + m_pStateData->setIgnoreOneYouHaveNotRegisteredError(false); + } + + loginToIrcServer(); +} + +#ifdef COMPILE_SSL_SUPPORT +bool KviIrcConnection::trySTARTTLS(bool bAppendPing) +{ + // Check if the server supports STARTTLS protocol and we want to + // connect through it + bool bRet = bAppendPing ? sendFmtData("STARTTLS\r\nPING :%Q",&(target()->server()->hostName())) : sendFmtData("STARTTLS"); + + if(!bRet) + { + // Cannot send command + m_pConsole->output(KVI_OUT_SOCKETERROR,__tr2qs("Impossible to send STARTTLS command to the IRC server. Your connection will NOT be encrypted")); + return false; + } + + m_pStateData->setSentStartTls(); + return true; +} + +void KviIrcConnection::handleFailedInitialStartTls() +{ + m_pStateData->setInsideInitialStartTls(false); + loginToIrcServer(); +} + +void KviIrcConnection::enableStartTlsSupport(bool bEnable) +{ + m_pStateData->setInsideInitialStartTls(false); + + if(bEnable) + { + // Ok, the server supports STARTTLS protocol + // ssl handshake e switch del socket + //qDebug("Starting SSL handshake..."); + link()->socket()->enterSSLMode(); // FIXME: this should be forwarded through KviIrcLink, probably } else { - loginToIrcServer(); + // The server does not support STARTTLS + m_pConsole->output(KVI_OUT_SOCKETERROR,__tr2qs("The server does not support STARTTLS command. Your connection will NOT be encrypted")); } } +#endif // COMPILE_SSL_SUPPORT void KviIrcConnection::handleInitialCapLs() { @@ -388,8 +450,8 @@ void KviIrcConnection::handleInitialCapLs() serverInfo()->supportedCaps().contains("tls",Qt::CaseInsensitive) ) { - trySTARTTLS(); // FIXME: Shouldn't we be able to STARTTLS even without CAP support ? - return; + if(trySTARTTLS(false)) + return; // STARTTLS negotiation in progress } #endif @@ -505,6 +567,8 @@ void KviIrcConnection::endInitialCapNegotiation() void KviIrcConnection::handleFailedInitialCapLs() { + m_pConsole->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Extended Capabilities don't seem to be supported by the server")); + m_pStateData->setInsideInitialCapLs(false); loginToIrcServer(); } @@ -1116,36 +1180,6 @@ void KviIrcConnection::hostNameLookupTerminated(KviDnsResolver *) m_pLocalhostDns = 0; } -#ifdef COMPILE_SSL_SUPPORT -void KviIrcConnection::trySTARTTLS() -{ - // Check if the server supports STARTTLS protocol and we want to - // connect through it - //qDebug("Sending STARTTLS command..."); - if(!sendFmtData("STARTTLS")) - { - // 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) -{ - if(bEnable) - { - // Ok, the server supports STARTTLS protocol - // ssl handshake e switch del socket - //qDebug("Starting SSL handshake..."); - link()->socket()->enterSSLMode(); // FIXME: this should be forwarded through KviIrcLink, probably - } 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")); - } -} -#endif // COMPILE_SSL_SUPPORT - void KviIrcConnection::useRealName(const QString &szRealName) { // Evaluate functions in the real name (so we can have $version() inside) diff --git a/src/kvirc/kernel/KviIrcConnection.h b/src/kvirc/kernel/KviIrcConnection.h index c3f25d507..fbde1fdbf 100644 --- a/src/kvirc/kernel/KviIrcConnection.h +++ b/src/kvirc/kernel/KviIrcConnection.h @@ -723,7 +723,8 @@ protected: void resolveLocalHost(); #ifdef COMPILE_SSL_SUPPORT - void trySTARTTLS(); + void handleFailedInitialStartTls(); + bool trySTARTTLS(bool bAppendPing); void enableStartTlsSupport(bool bEnable); #endif diff --git a/src/kvirc/kernel/KviIrcConnectionStateData.cpp b/src/kvirc/kernel/KviIrcConnectionStateData.cpp index a8315ebbc..c1e0bcbb9 100644 --- a/src/kvirc/kernel/KviIrcConnectionStateData.cpp +++ b/src/kvirc/kernel/KviIrcConnectionStateData.cpp @@ -32,6 +32,7 @@ KviIrcConnectionStateData::KviIrcConnectionStateData() m_bSentQuit = false; m_bInsideInitialCapLs = false; m_bInsideInitialCapReq = false; + m_bInsideInitialStartTls = false; m_bIgnoreOneYouHaveNotRegisteredError = false; m_eLoginNickNameState = UsedConnectionSpecificNickName; m_bSimulateUnexpectedDisconnect = false; diff --git a/src/kvirc/kernel/KviIrcConnectionStateData.h b/src/kvirc/kernel/KviIrcConnectionStateData.h index 3d1452245..284159c72 100644 --- a/src/kvirc/kernel/KviIrcConnectionStateData.h +++ b/src/kvirc/kernel/KviIrcConnectionStateData.h @@ -77,6 +77,15 @@ protected: bool m_bInsideInitialCapLs; // true if there's a CAP LS request pending + /// + /// This is set to true if a forced STARTTLS request has been sent + /// to the server followed by a PING. We use this flag to gracefully + /// handle a ERR_NOTREGISTERED related to the PING if STARTTLS is not supported. + /// + /// Note that in this case the STARTTLS support wasn't detected by a previous CAP LS + /// (which wasn't sent at all). + /// + bool m_bInsideInitialStartTls; bool m_bIgnoreOneYouHaveNotRegisteredError; // true if we have sent a CAP LS request followed by a PING which will generate an error (and we need to ignore it) bool m_bInsideInitialCapReq; // true if there's a CAP REQ request pending bool m_bInsideAuthenticate; // true if there's a AUTHENTICATE request pending @@ -122,6 +131,9 @@ public: bool isInsideInitialCapLs(){ return m_bInsideInitialCapLs; }; void setInsideInitialCapLs(bool bInside){ m_bInsideInitialCapLs = bInside; }; + bool isInsideInitialStartTls(){ return m_bInsideInitialStartTls; }; + void setInsideInitialStartTls(bool bInside){ m_bInsideInitialStartTls = bInside; }; + void setIgnoreOneYouHaveNotRegisteredError(bool bIgnore) { m_bIgnoreOneYouHaveNotRegisteredError = bIgnore; }; bool ignoreOneYouHaveNotRegisteredError() const diff --git a/src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp b/src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp index 59d71a63d..fa99a76cb 100644 --- a/src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp +++ b/src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp @@ -2331,20 +2331,32 @@ void KviIrcServerParser::parseNumericNotRegistered(KviIrcMessage * msg) if(msg->connection()->stateData()->isInsideInitialCapLs()) { + // CAP LS wasn't answered correctly. msg->connection()->handleFailedInitialCapLs(); return; } - - // if not registered yet and a CAP LS request was sent out then - // hide it (WE have triggered the error). + +#ifdef COMPILE_SSL_SUPPORT + if(msg->connection()->stateData()->isInsideInitialStartTls()) + { + // The forced STARTTLS wasn't answered correctly. + msg->connection()->handleFailedInitialStartTls(); + return; + } +#endif //COMPILE_SSL_SUPPORT + + // If not registered yet and a CAP LS or STARTTLS request was sent out then + // hide it (as WE have triggered the error). if(msg->connection()->stateData()->ignoreOneYouHaveNotRegisteredError()) { - // eat it once, silently. + // We DID send a CAP LS or a forced STARTTLS. + // The request was answered properly and this is probably the error related to the following PING. + // Eat it once, silently. msg->connection()->stateData()->setIgnoreOneYouHaveNotRegisteredError(false); return; } - // else we didn't send CAP LS so better show this to the user + // We didn't send CAP LS so better show this to the user if(!msg->haltOutput()) { QString szCmd = msg->connection()->decodeText(msg->safeParam(0)); diff --git a/src/modules/options/OptionsWidget_servers.cpp b/src/modules/options/OptionsWidget_servers.cpp index 6735e5314..45b03c5da 100644 --- a/src/modules/options/OptionsWidget_servers.cpp +++ b/src/modules/options/OptionsWidget_servers.cpp @@ -892,6 +892,20 @@ IrcServerDetailsWidget::IrcServerDetailsWidget(QWidget * par,KviIrcServer * s) iRow = 0; + m_pEnableSTARTTLSCheck = new QCheckBox(__tr2qs_ctx("Switch to SSL/TLS by using the STARTTLS extension","options"),tab); + gl->addWidget(m_pEnableSTARTTLSCheck,iRow,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 Extended Capabilities below then the TLS protocol support will be detected by using " \ + "a CAP LS command. Without Extended Capabilities the STARTTLS command will be forcibly sent at the beginning of the " \ + "connection.</center>","options")); +#ifndef COMPILE_SSL_SUPPORT + m_pEnableSTARTTLSCheck->setEnabled(false); +#endif + m_pEnableSTARTTLSCheck->setChecked(s->enabledSTARTTLS()); + + iRow++; + + QGroupBox * pCapGroup = new QGroupBox(__tr2qs_ctx("Extended Capabilities","options"),tab); gl->addWidget(pCapGroup,iRow,0,1,2); @@ -906,20 +920,6 @@ IrcServerDetailsWidget::IrcServerDetailsWidget(QWidget * par,KviIrcServer * s) m_pEnableCAPCheck->setChecked(s->enabledCAP()); - - m_pEnableSTARTTLSCheck = new QCheckBox(__tr2qs_ctx("Switch to SSL/TLS by using the STARTTLS extension","options"),tab); - pCapLayout->addWidget(m_pEnableSTARTTLSCheck,1,0); - - m_pEnableSTARTTLSCheck->setEnabled(s->enabledCAP()); - QObject::connect(m_pEnableCAPCheck,SIGNAL(toggled(bool)),m_pEnableSTARTTLSCheck,SLOT(setEnabled(bool))); - 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_pEnableSTARTTLSCheck->setEnabled(false); -#endif - m_pEnableSTARTTLSCheck->setChecked(s->enabledCAP() && s->enabledSTARTTLS()); - - QGroupBox * pSASLGroup = new QGroupBox(__tr2qs_ctx("SASL Authentication","options"),tab); pCapLayout->addWidget(pSASLGroup,2,0); |
