From 7768b765b21279eadef1400c6c614c63a3db8ed8 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Sat, 28 Dec 2013 20:35:51 +0100 Subject: [PATCH] Add handler for DCC-SEND This adds a basic handler for incoming DCC-SEND requests. Note that not all features are supported yet, there are no settings and no way to disable it. Also, the EventStringifier hasn't been adapted yet, so there will be a warning about an unknown event in the status buffer... --- src/core/coresessioneventprocessor.cpp | 57 ++++++++++++++++++++++++++ src/core/coresessioneventprocessor.h | 1 + 2 files changed, 58 insertions(+) diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index f8fd4d70..844155b0 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -23,12 +23,14 @@ #include "coreirclisthelper.h" #include "corenetwork.h" #include "coresession.h" +#include "coretransfermanager.h" #include "ctcpevent.h" #include "ircevent.h" #include "ircuser.h" #include "messageevent.h" #include "netsplit.h" #include "quassel.h" +#include "transfer.h" #ifdef HAVE_QCA2 # include "keyevent.h" @@ -1014,6 +1016,61 @@ void CoreSessionEventProcessor::handleCtcpClientinfo(CtcpEvent *e) } +// http://www.irchelp.org/irchelp/rfc/ctcpspec.html +// http://en.wikipedia.org/wiki/Direct_Client-to-Client +void CoreSessionEventProcessor::handleCtcpDcc(CtcpEvent *e) +{ + // normal: SEND [] + // reverse: SEND 0 + QStringList params = e->param().split(' '); + if (params.count()) { + QString cmd = params[0].toUpper(); + if (cmd == "SEND") { + if (params.count() < 4) { + qWarning() << "Invalid DCC SEND request:" << e; // TODO emit proper error to client + return; + } + QString filename = params[1]; + QHostAddress address; + quint16 port = params[3].toUShort(); + quint64 size = 0; + QString numIp = params[2]; // this is either IPv4 as a 32 bit value, or IPv6 (which always contains a colon) + if (numIp.contains(':')) { // IPv6 + if (!address.setAddress(numIp)) { + qWarning() << "Invalid IPv6:" << numIp; + return; + } + } + else { + address.setAddress(numIp.toUInt()); + } + + if (port == 0) { // Reverse DCC is indicated by a 0 port + emit newEvent(new MessageEvent(Message::Error, e->network(), tr("Reverse DCC SEND not supported"), e->prefix(), e->target(), Message::None, e->timestamp())); + return; + } + if (port < 1024) { + qWarning() << "Privileged port requested:" << port; // FIXME ask user if this is ok + } + + + if (params.count() > 4) { // filesize is optional + size = params[4].toULong(); + } + + // TODO: check if target is the right thing to use for the partner + Transfer *transfer = new Transfer(Transfer::Receive, e->target(), filename, address, port, size, this); + coreSession()->signalProxy()->synchronize(transfer); + coreSession()->transferManager()->addTransfer(transfer); + } + else { + emit newEvent(new MessageEvent(Message::Error, e->network(), tr("DCC %1 not supported").arg(cmd), e->prefix(), e->target(), Message::None, e->timestamp())); + return; + } + } +} + + void CoreSessionEventProcessor::handleCtcpPing(CtcpEvent *e) { e->setReply(e->param().isNull() ? "" : e->param()); diff --git a/src/core/coresessioneventprocessor.h b/src/core/coresessioneventprocessor.h index 6a163c6c..b13f6e24 100644 --- a/src/core/coresessioneventprocessor.h +++ b/src/core/coresessioneventprocessor.h @@ -97,6 +97,7 @@ public: Q_INVOKABLE void handleCtcpAction(CtcpEvent *event); Q_INVOKABLE void handleCtcpClientinfo(CtcpEvent *event); + Q_INVOKABLE void handleCtcpDcc(CtcpEvent *event); Q_INVOKABLE void handleCtcpPing(CtcpEvent *event); Q_INVOKABLE void handleCtcpTime(CtcpEvent *event); Q_INVOKABLE void handleCtcpVersion(CtcpEvent *event); -- 2.20.1