void SslTlsSocket::close()
{
    QSslSocket *sock = qobject_cast<QSslSocket*>(d);
    Q_ASSERT(sock);
    sock->abort();
    emit disconnected(tr("Connection closed"));
}
Esempio n. 2
0
void SslCertificateMonitor::socketReady(QObject *sockobj)
{
    QSslSocket *sock = qobject_cast<QSslSocket *>(sockobj);
    if (!sock)
        return;

    QString peerName = sock->peerName();
    QSslCertificate certificate = sock->peerCertificate();

    if (*(d->acceptedCache.object(peerName)) == certificate)
        return; // Fast path for most recently accepted certificates

    // Have we been here before?
    QSslCertificate previousCertificate = cachedCertificate(peerName);

    if (!previousCertificate.isNull()) {
        if (certificate == previousCertificate) {
            // We need to add the certificate to the cache here as well as when we add to
            // the on-disk cache so that we don't hit the disk again for this site.
            d->acceptedCache.insert(peerName,new QSslCertificate(certificate));
            return; // All is well
        }

        // Cert has changed
        QString message = evaluateCertificateChange( peerName, previousCertificate,
                                                     certificate, sock->sslErrors().isEmpty() );

        d->acceptCurrent = false;
        emit certificateWarning(sock, message);
    }
    else {
        // The certificate is new. We don't show anything to user because then
        // we're simply training them to click through our warning message without
        // thinking.
        d->acceptCurrent = true;
    }

    // If the user has chosen to accept the certificate or the certficate is new
    // then we store the updated entry.
    if (d->acceptCurrent) {
        d->acceptedCache.insert(peerName,new QSslCertificate(certificate));
        addCertificate(peerName, certificate);
    }
    else {
        // Certficate has been considered dangerous by the user
        sock->abort();
    }
}
Esempio n. 3
0
void SslServer::readyReadPrivate()
{
    QSslSocket *socket = qobject_cast<QSslSocket*>(sender());

    if (!socket)
        return;

    QByteArray *m_buffer = &m_buffer_hash[socket];
    qint32 &m_size = m_size_hash[socket];

    while (socket->bytesAvailable() > 0)
    {
        m_buffer->append(socket->readAll());

        while ((m_size == 0 && m_buffer->size() >= 4) || (m_size > 0 && m_buffer->size() >= m_size))
        {
            if (m_size == 0 && m_buffer->size() >= 4)
            {
                m_size = getValue<qint32>(m_buffer->mid(0, 4));
                m_buffer->remove(0, 4);

                if (m_size < 0 || m_size > MAX_NETWORK_CHUNK_SIZE)
                {
                    socket->abort();
                    return;
                }
            }
            if (m_size > 0 && m_buffer->size() >= m_size)
            {
                QByteArray data = m_buffer->mid(0, m_size);
                m_buffer->remove(0, m_size);
                m_size = 0;

                QHostAddress host = socket->peerAddress();
                qintptr descriptor = socket->socketDescriptor();

                PeerData pd;
                pd.data = data;
                pd.host = host;
                pd.descriptor = descriptor;

                QMetaObject::invokeMethod(this, "process", Qt::QueuedConnection, Q_ARG(PeerData, pd));
            }
        }
    }
}
Esempio n. 4
0
void SslServer::newConnectionPrivate(qintptr descriptor)
{
    QSslSocket *socket = new QSslSocket(this);
    socket->setSocketDescriptor(descriptor);

    if (m_max_connections == 0)
    {
        socket->abort();
        return;
    }

    socket->setProtocol(QSsl::TlsV1_2OrLater);

    socket->addCaCertificate(m_cert);
    socket->setLocalCertificate(m_cert);
    socket->setPrivateKey(m_key);

    //New connection done, set one less available connection
    m_max_connections--;

    QByteArray m_buffer;
    qint32 size = 0;

    m_socket_list.append(socket);
    m_descriptor_hash.insert(socket, descriptor);
    m_socket_hash.insert(descriptor, socket);
    m_buffer_hash.insert(socket, m_buffer);
    m_size_hash.insert(socket, size);

    connect(socket, &QSslSocket::encrypted, this, &SslServer::encrypted);
    connect(socket, &QSslSocket::disconnected, this, &SslServer::disconnectedPrivate);
    connect(socket, static_cast<void(QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors), this, &SslServer::sslErrors);

    m_alive_hash[socket].start();

    socket->startServerEncryption();
}