All pastes #1822992 Raw Edit

Anonymous

public cpp v1 · immutable
#1822992 ·published 2010-03-04 19:17 UTC
rendered paste body
/* * Copyright (C) 2010 Bollor telecom * See AUTHORS file for a full list of contributors. *  * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program.  If not, see <http://www.gnu.org/licenses/>. */#include <QCryptographicHash>#include <QDebug>#include <QDomElement>#include "qxmpp/QXmppByteStreamIq.h"#include "qxmpp/QXmppConfiguration.h"#include "qxmpp/QXmppConstants.h"#include "qxmpp/QXmppDiscoveryIq.h"#include "qxmpp/QXmppSocks.h"#include "proxy.h"static QString streamHash(const QString &sid, const QString &initiatorJid, const QString &targetJid){    QCryptographicHash hash(QCryptographicHash::Sha1);    QString str = sid + initiatorJid + targetJid;    hash.addData(str.toAscii());    return hash.result().toHex();}Proxy::Proxy(const QHostAddress &host, quint16 port)    : m_host(host), m_port(port), m_server(0){    m_server = new QXmppSocksServer(this);    m_server->listen(m_host, m_port);    connect(m_server, SIGNAL(newConnection(QTcpSocket*, const QString&, quint16)), this, SLOT(slotNewConnection(QTcpSocket*, const QString &, quint16)));}/** Open the connection to the chat server. * * @param jid * @param password */bool Proxy::open(const QString &jid, const QString &password, bool ignoreSslErrors){    QXmppConfiguration config;    config.setResource("xmas-stocking");    /* get user and domain */    QStringList bits = jid.split("@");    config.setPasswd(password);    config.setUser(bits[0]);    config.setDomain(bits[1]);    /* get the server */    config.setHost(config.getDomain());    /* set security parameters */    config.setAutoAcceptSubscriptions(false);    config.setStreamSecurityMode(QXmppConfiguration::TLSRequired);    config.setIgnoreSslErrors(ignoreSslErrors);    /* connect to server */    connectToServer(config);    return true;}bool Proxy::handleStreamElement(const QDomElement &element){    if (element.tagName() != "iq")        return false;    if (QXmppDiscoveryIq::isDiscoveryIq(element))    {        QXmppDiscoveryIq discoIq;        discoIq.parse(element);        if (discoIq.type() == QXmppIq::Get && discoIq.queryType() == QXmppDiscoveryIq::InfoQuery)        {            qDebug() << "GOT" << element.tagName();            QXmppDiscoveryIq responseIq;            responseIq.setTo(discoIq.from());            responseIq.setId(discoIq.id());            responseIq.setType(QXmppIq::Result);            responseIq.setQueryType(discoIq.queryType());            QList<QXmppElement> items;            QXmppElement identity;            identity.setTagName("identity");            identity.setAttribute("category", "proxy");            identity.setAttribute("type", "bytestreams");            identity.setAttribute("name", "SOCKS5 Bytestreams");            items.append(identity);            QStringList features = QStringList() << ns_disco_info << ns_disco_items << ns_bytestreams;            foreach (const QString &feature, features)            {                QXmppElement item;                item.setTagName("feature");                item.setAttribute("var", feature);                items.append(item);            }            responseIq.setQueryItems(items);            sendPacket(responseIq);            return true;        }    }    else if (QXmppByteStreamIq::isByteStreamIq(element))    {        QXmppByteStreamIq bsIq;        bsIq.parse(element);        if (bsIq.type() == QXmppIq::Get)        {            QXmppByteStreamIq responseIq;            responseIq.setType(QXmppIq::Result);            responseIq.setTo(bsIq.from());            responseIq.setId(bsIq.id());            QList<QXmppByteStreamIq::StreamHost> streamHosts;            QXmppByteStreamIq::StreamHost streamHost;            streamHost.setJid(getConfiguration().getJid());            streamHost.setHost(m_host);            streamHost.setPort(m_port);            streamHosts.append(streamHost);            responseIq.setStreamHosts(streamHosts);            sendPacket(responseIq);            return true;        }        else if (bsIq.type() == QXmppIq::Set)        {            QString hash = streamHash(bsIq.sid(), bsIq.from(), bsIq.activate());            if (m_pairs.contains(hash))            {                qDebug() << "ACTIVATING" << hash;                QTcpSocketPair pair = m_pairs.value(hash);                connect(pair.first, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));                connect(pair.second, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));                QXmppIq responseIq;                responseIq.setType(QXmppIq::Result);                responseIq.setTo(bsIq.from());                responseIq.setId(bsIq.id());                sendPacket(responseIq);                return true;                }        }    }    return false;}void Proxy::slotNewConnection(QTcpSocket *socket, const QString &hostName, quint16 port){    qDebug() << "new connection" << hostName;    if (m_pairs.contains(hostName))    {        m_pairs[hostName].second = socket;    } else {        m_pairs[hostName] = QTcpSocketPair(socket, 0);    }}void Proxy::slotReadyRead(){    QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());    if (!socket)        return;    foreach (const QTcpSocketPair &pair, m_pairs)    {        if (pair.first == socket)        {            pair.second->write(socket->readAll());            break;        } else if (pair.second == socket) {            pair.first->write(socket->readAll());            break;        }    }}