aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2011-12-21 04:30:08 +0000
committerGravatar Szymon Tomasz Stefanek2011-12-21 04:30:08 +0000
commit72e767c54de4dd534d7ceed50f8845dc03870a66 (patch)
treefc5e99921e639de0b63d9f0c62ae4e9fb564066c
parentStartTls and Sasl are now per-server options. These are no longer needed. (diff)
downloadKVIrc-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.cpp102
-rw-r--r--src/kvirc/kernel/KviIrcConnection.h3
-rw-r--r--src/kvirc/kernel/KviIrcConnectionStateData.cpp1
-rw-r--r--src/kvirc/kernel/KviIrcConnectionStateData.h12
-rw-r--r--src/kvirc/sparser/KviIrcServerParser_numericHandlers.cpp22
-rw-r--r--src/modules/options/OptionsWidget_servers.cpp28
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);