#include "netsplit.h"
#include "quassel.h"
+#ifdef HAVE_QCA2
+# include "keyevent.h"
+#endif
+
CoreSessionEventProcessor::CoreSessionEventProcessor(CoreSession *session)
: BasicHandler("handleCtcp", session),
_coreSession(session)
CoreNetwork *net = coreNetwork(e);
- QString construct = net->saslAccount();
- construct.append(QChar(QChar::Null));
- construct.append(net->saslAccount());
- construct.append(QChar(QChar::Null));
- construct.append(net->saslPassword());
- QByteArray saslData = QByteArray(construct.toAscii().toBase64());
- saslData.prepend("AUTHENTICATE ");
- net->putRawLine(saslData);
+#ifdef HAVE_SSL
+ if (net->identityPtr()->sslCert().isNull()) {
+#endif
+ QString construct = net->saslAccount();
+ construct.append(QChar(QChar::Null));
+ construct.append(net->saslAccount());
+ construct.append(QChar(QChar::Null));
+ construct.append(net->saslPassword());
+ QByteArray saslData = QByteArray(construct.toAscii().toBase64());
+ saslData.prepend("AUTHENTICATE ");
+ net->putRawLine(saslData);
+#ifdef HAVE_SSL
+ } else {
+ net->putRawLine("AUTHENTICATE +");
+ }
+#endif
}
// additional CAP messages (ls, multi-prefix, et cetera).
if (e->params().count() == 3) {
- if (e->params().at(2) == "sasl") {
+ if (e->params().at(2).startsWith("sasl")) { // Freenode (at least) sends "sasl " with a trailing space for some reason!
// FIXME use event
- coreNetwork(e)->putRawLine(coreNetwork(e)->serverEncode("AUTHENTICATE PLAIN")); // Only working with PLAIN atm, blowfish later
+ // if the current identity has a cert set, use SASL EXTERNAL
+#ifdef HAVE_SSL
+ if (!coreNetwork(e)->identityPtr()->sslCert().isNull()) {
+ coreNetwork(e)->putRawLine(coreNetwork(e)->serverEncode("AUTHENTICATE EXTERNAL"));
+ } else {
+#endif
+ // Only working with PLAIN atm, blowfish later
+ coreNetwork(e)->putRawLine(coreNetwork(e)->serverEncode("AUTHENTICATE PLAIN"));
+#ifdef HAVE_SSL
+ }
+#endif
}
}
}
}
+#ifdef HAVE_QCA2
+void CoreSessionEventProcessor::processKeyEvent(KeyEvent *e)
+{
+ if (!Cipher::neededFeaturesAvailable()) {
+ emit newEvent(new MessageEvent(Message::Error, e->network(), tr("Unable to perform key exchange."), e->prefix(), e->target(), Message::None, e->timestamp()));
+ return;
+ }
+ CoreNetwork *net = qobject_cast<CoreNetwork*>(e->network());
+ Cipher *c = net->cipher(e->target());
+ if (!c) // happens when there is no CoreIrcChannel for the target (i.e. never?)
+ return;
+
+ if (e->exchangeType() == KeyEvent::Init) {
+ QByteArray pubKey = c->parseInitKeyX(e->key());
+ if (pubKey.isEmpty()) {
+ emit newEvent(new MessageEvent(Message::Error, e->network(), tr("Unable to parse the DH1080_INIT. Key exchange failed."), e->prefix(), e->target(), Message::None, e->timestamp()));
+ return;
+ } else {
+ net->setCipherKey(e->target(), c->key());
+ emit newEvent(new MessageEvent(Message::Info, e->network(), tr("Your key is set and messages will be encrypted."), e->prefix(), e->target(), Message::None, e->timestamp()));
+ QList<QByteArray> p;
+ p << net->serverEncode(e->target()) << net->serverEncode("DH1080_FINISH ")+pubKey;
+ net->putCmd("NOTICE", p);
+ }
+ } else {
+ if (c->parseFinishKeyX(e->key())) {
+ net->setCipherKey(e->target(), c->key());
+ emit newEvent(new MessageEvent(Message::Info, e->network(), tr("Your key is set and messages will be encrypted."), e->prefix(), e->target(), Message::None, e->timestamp()));
+ } else {
+ emit newEvent(new MessageEvent(Message::Info, e->network(), tr("Failed to parse DH1080_FINISH. Key exchange failed."), e->prefix(), e->target(), Message::None, e->timestamp()));
+ }
+ }
+}
+#endif
+
+
/* RPL_WELCOME */
void CoreSessionEventProcessor::processIrcEvent001(IrcEvent *e)
{
QStringList nicks;
QStringList modes;
- foreach(QString nick, e->params()[2].split(' ')) {
+ foreach(QString nick, e->params()[2].split(' ', QString::SkipEmptyParts)) {
QString mode;
if (e->network()->prefixes().contains(nick[0])) {