Exemplo n.º 1
0
void Server::handleAccept() {
    sockaddr_in address;
    socklen_t addrLen = sizeof(address);
    int fd = ::accept(_listenSock,
            reinterpret_cast<sockaddr*>(&address),
            &addrLen);
    if (fd == -1) {
        LS_ERROR(_logger, "Unable to accept: " << getLastError());
        return;
    }
    if (!configureSocket(fd)) {
        ::close(fd);
        return;
    }
    LS_INFO(_logger, formatAddress(address) << " : Accepted on descriptor " << fd);
    Connection* newConnection = new Connection(_logger, *this, fd, address);
    epoll_event event = { EPOLLIN, { newConnection } };
    if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, fd, &event) == -1) {
        LS_ERROR(_logger, "Unable to add socket to epoll: " << getLastError());
        delete newConnection;
        ::close(fd);
        return;
    }
    _connections.insert(std::make_pair(newConnection, time(nullptr)));
}
Exemplo n.º 2
0
//We received a UDP package and answered by connecting to them by TCP. This gets called on a succesful connection.
void LanLinkProvider::connected()
{
    qCDebug(KDECONNECT_CORE) << "Socket connected";

    QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
    if (!socket) return;
    disconnect(socket, &QAbstractSocket::connected, this, &LanLinkProvider::connected);
    disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));

    configureSocket(socket);

    // If socket disconnects due to any reason after connection, link on ssl faliure
    connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);

    NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
    const QString& deviceId = receivedPackage->get<QString>(QStringLiteral("deviceId"));
    //qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();

    // If network is on ssl, do not believe when they are connected, believe when handshake is completed
    NetworkPackage np2(QLatin1String(""));
    NetworkPackage::createIdentityPackage(&np2);
    socket->write(np2.serialize());
    bool success = socket->waitForBytesWritten();

    if (success) {

        qCDebug(KDECONNECT_CORE) << "TCP connection done (i'm the existing device)";

        // if ssl supported
        if (receivedPackage->get<int>(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) {

            bool isDeviceTrusted = KdeConnectConfig::instance()->trustedDevices().contains(deviceId);
            configureSslSocket(socket, deviceId, isDeviceTrusted);

            qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";

            connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted);

            if (isDeviceTrusted) {
                connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
            }

            socket->startServerEncryption();

            return; // Return statement prevents from deleting received package, needed in slot "encrypted"
        } else {
            qWarning() << receivedPackage->get<QString>(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work";
            //addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely);
        }

    } else {
        //I think this will never happen, but if it happens the deviceLink
        //(or the socket that is now inside it) might not be valid. Delete them.
        qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)";
        mUdpSocket.writeDatagram(np2.serialize(), receivedIdentityPackages[socket].sender, PORT);
    }

    delete receivedIdentityPackages.take(socket).np;
    //We don't delete the socket because now it's owned by the LanDeviceLink
}
Exemplo n.º 3
0
//I'm the new device and this is the answer to my UDP identity package (no data received yet). They are connecting to us through TCP, and they should send an identity.
void LanLinkProvider::newConnection()
{
    //qCDebug(KDECONNECT_CORE) << "LanLinkProvider newConnection";

    while (mServer->hasPendingConnections()) {
        QSslSocket* socket = mServer->nextPendingConnection();
        configureSocket(socket);
        //This socket is still managed by us (and child of the QTcpServer), if
        //it disconnects before we manage to pass it to a LanDeviceLink, it's
        //our responsibility to delete it. We do so with this connection.
        connect(socket, &QAbstractSocket::disconnected,
                socket, &QObject::deleteLater);
        connect(socket, &QIODevice::readyRead,
                this, &LanLinkProvider::dataReceived);

    }
}
Exemplo n.º 4
0
bool Server::startListening(uint32_t hostAddr, int port) {
    if (_epollFd == -1 || _eventFd == -1) {
        LS_ERROR(_logger, "Unable to serve, did not initialize properly.");
        return false;
    }

    auto port16 = static_cast<uint16_t>(port);
    if (port != port16) {
        LS_ERROR(_logger, "Invalid port: " << port);
        return false;
    }
    _listenSock = socket(AF_INET, SOCK_STREAM, 0);
    if (_listenSock == -1) {
        LS_ERROR(_logger, "Unable to create listen socket: " << getLastError());
        return false;
    }
    if (!configureSocket(_listenSock)) {
        return false;
    }
    sockaddr_in sock;
    memset(&sock, 0, sizeof(sock));
    sock.sin_port = htons(port16);
    sock.sin_addr.s_addr = htonl(hostAddr);
    sock.sin_family = AF_INET;
    if (bind(_listenSock, reinterpret_cast<const sockaddr*>(&sock), sizeof(sock)) == -1) {
        LS_ERROR(_logger, "Unable to bind socket: " << getLastError());
        return false;
    }
    if (listen(_listenSock, 5) == -1) {
        LS_ERROR(_logger, "Unable to listen on socket: " << getLastError());
        return false;
    }
    epoll_event event = { EPOLLIN, { this } };
    if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, _listenSock, &event) == -1) {
        LS_ERROR(_logger, "Unable to add listen socket to epoll: " << getLastError());
        return false;
    }

    char buf[1024];
    ::gethostname(buf, sizeof(buf));
    LS_INFO(_logger, "Listening on http://" << buf << ":" << port << "/");

    return true;
}
void LanLinkProvider::connected()
{
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    if (!socket) return;
    disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
    disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));

    configureSocket(socket);

    NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
    const QString& deviceId = receivedPackage->get<QString>("deviceId");
    //qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();

    LanDeviceLink* deviceLink = new LanDeviceLink(deviceId, this, socket);

    NetworkPackage np2("");
    NetworkPackage::createIdentityPackage(&np2);
    bool success = deviceLink->sendPackage(np2);

    if (success) {

        //qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the existing device)";

        connect(deviceLink, SIGNAL(destroyed(QObject*)),
                this, SLOT(deviceLinkDestroyed(QObject*)));

        Q_EMIT onConnectionReceived(*receivedPackage, deviceLink);

        //We kill any possible link from this same device
        QMap< QString, DeviceLink* >::iterator oldLinkIterator = mLinks.find(deviceId);
        if (oldLinkIterator != mLinks.end()) {
            DeviceLink* oldLink = oldLinkIterator.value();
            disconnect(oldLink, SIGNAL(destroyed(QObject*)),
                        this, SLOT(deviceLinkDestroyed(QObject*)));
            oldLink->deleteLater();
            mLinks.erase(oldLinkIterator);
        }

        mLinks[deviceId] = deviceLink;

    } else {
Exemplo n.º 6
0
bool Server::startListeningUnix(const char* socketPath) {
    struct sockaddr_un sock;

    _listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (_listenSock == -1) {
        LS_ERROR(_logger, "Unable to create unix listen socket: " << getLastError());
        return false;
    }
    if (!configureSocket(_listenSock)) {
        return false;
    }

    memset(&sock, 0, sizeof(struct sockaddr_un));
    sock.sun_family = AF_UNIX;
    strncpy(sock.sun_path, socketPath, sizeof(sock.sun_path) - 1);

    if (bind(_listenSock, reinterpret_cast<const sockaddr*>(&sock), sizeof(sock)) == -1) {
        LS_ERROR(_logger, "Unable to bind unix socket (" << socketPath << "): " << getLastError());
        return false;
    }

    if (listen(_listenSock, 5) == -1) {
        LS_ERROR(_logger, "Unable to listen on unix socket: " << getLastError());
        return false;
    }

    epoll_event event = { EPOLLIN, { this } };
    if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, _listenSock, &event) == -1) {
        LS_ERROR(_logger, "Unable to add unix listen socket to epoll: " << getLastError());
        return false;
    }

    LS_INFO(_logger, "Listening on unix socket: http://unix:" << socketPath);

    return true;
}
Exemplo n.º 7
0
void LanLinkProvider::connected()
{
    qCDebug(KDECONNECT_CORE) << "Socket connected";

    QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
    if (!socket) return;
    disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
    disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));

    configureSocket(socket);

    // If socket disconnects due to any reason after connection, link on ssl faliure
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));

    NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
    const QString& deviceId = receivedPackage->get<QString>("deviceId");
    //qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();

    // If network is on ssl, do not believe when they are connected, believe when handshake is completed
    NetworkPackage np2("");
    NetworkPackage::createIdentityPackage(&np2);
    socket->write(np2.serialize());
    bool success = socket->waitForBytesWritten();

    if (success) {

        qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the existing device)";

        // if ssl supported
        if (receivedPackage->get<int>("protocolVersion") >= NetworkPackage::ProtocolVersion) {
            // since I support ssl and remote device support ssl

            socket->setPeerVerifyName(deviceId);

            QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "certificate", QString());
            if (!certString.isEmpty()) {
                qCDebug(KDECONNECT_CORE) << "Device trusted";
                socket->addCaCertificate(QSslCertificate(certString.toLatin1()));
                socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
                connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
            } else {
                qCDebug(KDECONNECT_CORE) << "Device untrusted";
                // Do not care about ssl errors here, socket will not be closed due to errors because of query peer
                socket->setPeerVerifyMode(QSslSocket::QueryPeer);
                connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsLogButIgnore(QList<QSslError>)));
            }
            qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";
            connect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));

            socket->startServerEncryption();
            return; // Return statement prevents from deleting received package, needed in slot "encrypted"
        } else {
            qWarning() << "Incompatible protocol version, this won't work";
            //addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely);
        }

    } else {
        //I think this will never happen, but if it happens the deviceLink
        //(or the socket that is now inside it) might not be valid. Delete them.
        qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)";
        mUdpSocket.writeDatagram(np2.serialize(), receivedIdentityPackages[socket].sender, port);
    }

    delete receivedIdentityPackages.take(socket).np;
    //We don't delete the socket because now it's owned by the LanDeviceLink
}