summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslsocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qsslsocket.cpp')
-rw-r--r--src/network/ssl/qsslsocket.cpp92
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;