diff options
Diffstat (limited to 'src/network/ssl/qsslsocket.cpp')
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 805adc734f..3e7a30aa9f 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1,32 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -506,6 +512,8 @@ bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state setPeerPort(d->plainSocket->peerPort()); setPeerAddress(d->plainSocket->peerAddress()); setPeerName(d->plainSocket->peerName()); + d->readChannelCount = d->plainSocket->readChannelCount(); + d->writeChannelCount = d->plainSocket->writeChannelCount(); return retVal; } @@ -1507,6 +1515,10 @@ QList<QSslCertificate> QSslSocket::defaultCaCertificates() returned by defaultCaCertificates(). You can replace that database with your own with setDefaultCaCertificates(). + \note: On OS X, only certificates that are either trusted for all + purposes or trusted for the purpose of SSL in the keychain will be + returned. + \sa caCertificates(), defaultCaCertificates(), setDefaultCaCertificates() */ QList<QSslCertificate> QSslSocket::systemCaCertificates() @@ -1915,6 +1927,7 @@ void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode o d->plainSocket->setProxy(proxy()); #endif QIODevice::open(openMode); + d->readChannelCount = d->writeChannelCount = 0; d->plainSocket->connectToHost(hostName, port, openMode, d->preferredNetworkLayerProtocol); d->cachedSocketDescriptor = d->plainSocket->socketDescriptor(); } @@ -1994,8 +2007,7 @@ qint64 QSslSocket::writeData(const char *data, qint64 len) if (d->mode == UnencryptedMode && !d->autoStartHandshake) return d->plainSocket->write(data, len); - char *writePtr = d->writeBuffer.reserve(len); - ::memcpy(writePtr, data, len); + d->writeBuffer.append(data, len); // make sure we flush to the plain socket's buffer QMetaObject::invokeMethod(this, "_q_flushWriteBuffer", Qt::QueuedConnection); @@ -2262,9 +2274,15 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode) q->connect(plainSocket, SIGNAL(readyRead()), q, SLOT(_q_readyReadSlot()), Qt::DirectConnection); + q->connect(plainSocket, SIGNAL(channelReadyRead(int)), + q, SLOT(_q_channelReadyReadSlot(int)), + Qt::DirectConnection); q->connect(plainSocket, SIGNAL(bytesWritten(qint64)), q, SLOT(_q_bytesWrittenSlot(qint64)), Qt::DirectConnection); + q->connect(plainSocket, SIGNAL(channelBytesWritten(int, qint64)), + q, SLOT(_q_channelBytesWrittenSlot(int, qint64)), + Qt::DirectConnection); #ifndef QT_NO_NETWORKPROXY q->connect(plainSocket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -2318,6 +2336,7 @@ bool QSslSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstrac localPort = plainSocket->localPort(); localAddress = plainSocket->localAddress(); cachedSocketDescriptor = plainSocket->socketDescriptor(); + readChannelCount = writeChannelCount = 0; return ret; } @@ -2333,6 +2352,8 @@ void QSslSocketPrivate::_q_connectedSlot() q->setPeerAddress(plainSocket->peerAddress()); q->setPeerName(plainSocket->peerName()); cachedSocketDescriptor = plainSocket->socketDescriptor(); + readChannelCount = plainSocket->readChannelCount(); + writeChannelCount = plainSocket->writeChannelCount(); #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << "QSslSocket::_q_connectedSlot()"; @@ -2438,6 +2459,16 @@ void QSslSocketPrivate::_q_readyReadSlot() /*! \internal */ +void QSslSocketPrivate::_q_channelReadyReadSlot(int channel) +{ + Q_Q(QSslSocket); + if (mode == QSslSocket::UnencryptedMode) + emit q->channelReadyRead(channel); +} + +/*! + \internal +*/ void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written) { Q_Q(QSslSocket); @@ -2456,6 +2487,16 @@ void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written) /*! \internal */ +void QSslSocketPrivate::_q_channelBytesWrittenSlot(int channel, qint64 written) +{ + Q_Q(QSslSocket); + if (mode == QSslSocket::UnencryptedMode) + emit q->channelBytesWritten(channel, written); +} + +/*! + \internal +*/ void QSslSocketPrivate::_q_flushWriteBuffer() { Q_Q(QSslSocket); @@ -2527,7 +2568,7 @@ qint64 QSslSocketPrivate::peek(char *data, qint64 maxSize) if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake) { //unencrypted mode - do not use QIODevice::peek, as it reads ahead data from the plain socket //peek at data already in the QIODevice buffer (from a previous read) - qint64 r = buffer.peek(data, maxSize); + qint64 r = buffer.peek(data, maxSize, transactionPos); if (r == maxSize) return r; data += r; @@ -2556,7 +2597,7 @@ QByteArray QSslSocketPrivate::peek(qint64 maxSize) //peek at data already in the QIODevice buffer (from a previous read) QByteArray ret; ret.reserve(maxSize); - ret.resize(buffer.peek(ret.data(), maxSize)); + ret.resize(buffer.peek(ret.data(), maxSize, transactionPos)); if (ret.length() == maxSize) return ret; //peek at data in the plain socket @@ -2612,18 +2653,19 @@ QSharedPointer<QSslContext> QSslSocketPrivate::sslContext(QSslSocket *socket) bool QSslSocketPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName) { - QStringList commonNameList = cert.subjectInfo(QSslCertificate::CommonName); + const QString lowerPeerName = peerName.toLower(); + const QStringList commonNames = cert.subjectInfo(QSslCertificate::CommonName); - foreach (const QString &commonName, commonNameList) { - if (isMatchingHostname(commonName.toLower(), peerName.toLower())) { + for (const QString &commonName : commonNames) { + if (isMatchingHostname(commonName.toLower(), lowerPeerName)) return true; - } } - foreach (const QString &altName, cert.subjectAlternativeNames().values(QSsl::DnsEntry)) { - if (isMatchingHostname(altName.toLower(), peerName.toLower())) { + const auto subjectAlternativeNames = cert.subjectAlternativeNames(); + const auto altNames = subjectAlternativeNames.equal_range(QSsl::DnsEntry); + for (auto it = altNames.first; it != altNames.second; ++it) { + if (isMatchingHostname(it->toLower(), lowerPeerName)) return true; - } } return false; |