void SslTlsSocket::close() { QSslSocket *sock = qobject_cast<QSslSocket*>(d); Q_ASSERT(sock); sock->abort(); emit disconnected(tr("Connection closed")); }
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(); } }
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)); } } } }
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(); }