diff options
Diffstat (limited to 'src/network')
33 files changed, 388 insertions, 120 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 360f9722c7..7ff6bffed3 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1203,7 +1203,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt, connectionType)), parent) { Q_D(QHttpNetworkConnection); - d->networkSession = networkSession; + d->networkSession = qMove(networkSession); d->init(); } @@ -1215,7 +1215,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS connectionType)), parent) { Q_D(QHttpNetworkConnection); - d->networkSession = networkSession; + d->networkSession = qMove(networkSession); d->init(); } #else @@ -1339,7 +1339,7 @@ QSharedPointer<QSslContext> QHttpNetworkConnection::sslContext() void QHttpNetworkConnection::setSslContext(QSharedPointer<QSslContext> context) { Q_D(QHttpNetworkConnection); - d->sslContext = context; + d->sslContext = qMove(context); } void QHttpNetworkConnection::ignoreSslErrors(int channel) diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 76107d3110..8743989dec 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -188,7 +188,7 @@ public: QHttpNetworkConnection::ConnectionType connectionType, QSharedPointer<QNetworkSession> networkSession) : QHttpNetworkConnection(hostName, port, encrypt, connectionType, /*parent=*/0, - networkSession) + qMove(networkSession)) #endif { setExpires(true); diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index b4aaca0851..acaba33dee 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -130,9 +130,9 @@ QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice() { if (reply->outgoingDataBuffer) - uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer)); + uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingDataBuffer); else if (reply->outgoingData) { - uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingData)); + uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingData); } else { return 0; } diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 9528330aae..bd5a6faeef 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -92,7 +92,7 @@ public: initializeSession(true), #endif cookieJarCreated(false), - authenticationManager(new QNetworkAccessAuthenticationManager) + authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create()) { } ~QNetworkAccessManagerPrivate(); diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 56105a544b..3ac8b8f56f 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -194,7 +194,7 @@ QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manage if (d->synchronous && outgoingData) { // The synchronous HTTP is a corner case, we will put all upload data in one big QByteArray in the outgoingDataBuffer. // Yes, this is not the most efficient thing to do, but on the other hand synchronous XHR needs to die anyway. - d->outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer()); + d->outgoingDataBuffer = QSharedPointer<QRingBuffer>::create(); qint64 previousDataSize = 0; do { previousDataSize = d->outgoingDataBuffer->size(); @@ -277,6 +277,10 @@ void QNetworkReplyHttpImpl::abort() // call finished which will emit signals // FIXME shouldn't this be emitted Queued? d->error(OperationCanceledError, tr("Operation canceled")); + + // If state is WaitingForSession, calling finished has no effect + if (d->state == QNetworkReplyHttpImplPrivate::WaitingForSession) + d->state = QNetworkReplyHttpImplPrivate::Working; d->finished(); } @@ -440,8 +444,8 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , downloadBufferReadPosition(0) , downloadBufferCurrentSize(0) , downloadZerocopyBuffer(0) - , pendingDownloadDataEmissions(new QAtomicInt()) - , pendingDownloadProgressEmissions(new QAtomicInt()) + , pendingDownloadDataEmissions(QSharedPointer<QAtomicInt>::create()) + , pendingDownloadProgressEmissions(QSharedPointer<QAtomicInt>::create()) #ifndef QT_NO_SSL , pendingIgnoreAllSslErrors(false) #endif @@ -1724,7 +1728,7 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData() if (!outgoingDataBuffer) { // first call, create our buffer - outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer()); + outgoingDataBuffer = QSharedPointer<QRingBuffer>::create(); QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData())); QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished())); @@ -1853,9 +1857,9 @@ QNonContiguousByteDevice* QNetworkReplyHttpImplPrivate::createUploadByteDevice() Q_Q(QNetworkReplyHttpImpl); if (outgoingDataBuffer) - uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(outgoingDataBuffer)); + uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingDataBuffer); else if (outgoingData) { - uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(outgoingData)); + uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingData); } else { return 0; } diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index f51b85cba0..616019ea41 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -248,7 +248,7 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData() if (!outgoingDataBuffer) { // first call, create our buffer - outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer()); + outgoingDataBuffer = QSharedPointer<QRingBuffer>::create(); QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData())); QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished())); @@ -367,7 +367,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // The synchronous HTTP is a corner case, we will put all upload data in one big QByteArray in the outgoingDataBuffer. // Yes, this is not the most efficient thing to do, but on the other hand synchronous XHR needs to die anyway. if (synchronousHttpAttribute.toBool() && outgoingData) { - outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer()); + outgoingDataBuffer = QSharedPointer<QRingBuffer>::create(); qint64 previousDataSize = 0; do { previousDataSize = outgoingDataBuffer->size(); diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp index 32a804e9f4..ab703981ee 100644 --- a/src/network/access/qspdyprotocolhandler.cpp +++ b/src/network/access/qspdyprotocolhandler.cpp @@ -506,25 +506,7 @@ QByteArray QSpdyProtocolHandler::composeHeader(const QHttpNetworkRequest &reques #endif uncompressedHeader.append(headerField(":version", "HTTP/1.1")); - QHostAddress add; // ### unify with the host parsing from QHttpNetworkConnection - QByteArray host; - QString hostName = m_connection->hostName(); - if (add.setAddress(hostName)) { - if (add.protocol() == QAbstractSocket::IPv6Protocol) - host = "[" + hostName.toLatin1() + "]"; //format the ipv6 in the standard way - else - host = hostName.toLatin1(); - - } else { - host = QUrl::toAce(hostName); - } - - int port = request.url().port(); - if (port != -1) { - host += ':'; - host += QByteArray::number(port); - } - uncompressedHeader.append(headerField(":host", host)); + uncompressedHeader.append(headerField(":host", request.url().authority(QUrl::FullyEncoded | QUrl::RemoveUserInfo).toLatin1())); uncompressedHeader.append(headerField(":scheme", request.url().scheme().toLatin1())); diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 33d6c24461..522d71fd27 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -2,7 +2,6 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtNetwork description = Qt Network Reference Documentation -url = http://qt-project.org/doc/qt-$QT_VER version = $QT_VERSION examplesinstallpath = network diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index f7b956651f..ea935869fb 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -282,6 +282,15 @@ QString QAuthenticator::realm() const } /*! + \internal +*/ +void QAuthenticator::setRealm(const QString &realm) +{ + detach(); + d->realm = realm; +} + +/*! \since 4.7 Returns the value related to option \a opt if it was set by the server. See \l{QAuthenticator#Options} for more information on incoming options. diff --git a/src/network/kernel/qauthenticator.h b/src/network/kernel/qauthenticator.h index 4d96104bc0..2f440d660d 100644 --- a/src/network/kernel/qauthenticator.h +++ b/src/network/kernel/qauthenticator.h @@ -70,6 +70,7 @@ public: void setPassword(const QString &password); QString realm() const; + void setRealm(const QString &realm); QVariant option(const QString &opt) const; QVariantHash options() const; diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp index e111a190cb..b7e6bad0a7 100644 --- a/src/network/kernel/qdnslookup.cpp +++ b/src/network/kernel/qdnslookup.cpp @@ -283,9 +283,21 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent) /*! \fn QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) - \internal + \since 5.4 + Constructs a QDnsLookup object for the given \a type, \a name and + \a nameserver and sets \a parent as the parent object. */ +QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) + : QObject(*new QDnsLookupPrivate, parent) +{ + Q_D(QDnsLookup); + qRegisterMetaType<QDnsLookupReply>(); + d->name = name; + d->type = type; + d->nameserver = nameserver; +} + /*! Destroys the QDnsLookup object. diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp index e2a5ba2f37..52a8c3a530 100644 --- a/src/network/kernel/qdnslookup_winrt.cpp +++ b/src/network/kernel/qdnslookup_winrt.cpp @@ -81,31 +81,28 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN return; } - IHostNameFactory *hostnameFactory; - - HStringReference classId(RuntimeClass_Windows_Networking_HostName); - if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) { + ComPtr<IHostNameFactory> hostnameFactory; + HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + IID_PPV_ARGS(&hostnameFactory)); + if (FAILED(hr)) { reply->error = QDnsLookup::ResolverError; reply->errorString = QLatin1String("Could not obtain hostname factory"); return; } - IHostName *host; + ComPtr<IHostName> host; HStringReference hostNameRef((const wchar_t*)aceHostname.utf16()); hostnameFactory->CreateHostName(hostNameRef.Get(), &host); - hostnameFactory->Release(); - IDatagramSocketStatics *datagramSocketStatics; + ComPtr<IDatagramSocketStatics> datagramSocketStatics; GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); - IAsyncOperation<IVectorView<EndpointPair*> *> *op; - datagramSocketStatics->GetEndpointPairsAsync(host, + ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op; + datagramSocketStatics->GetEndpointPairsAsync(host.Get(), HString::MakeReference(L"0").Get(), &op); - datagramSocketStatics->Release(); - host->Release(); - IVectorView<EndpointPair*> *endpointPairs = 0; - HRESULT hr = op->GetResults(&endpointPairs); + ComPtr<IVectorView<EndpointPair *>> endpointPairs; + hr = op->GetResults(&endpointPairs); int waitCount = 0; while (hr == E_ILLEGAL_METHOD_CALL) { WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE); @@ -113,7 +110,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN if (++waitCount > 1200) // Wait for 1 minute max return; } - op->Release(); if (!endpointPairs) return; @@ -123,11 +119,10 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN // endpoint pairs might contain duplicates so we temporarily store addresses in a QSet QSet<QHostAddress> addresses; for (unsigned int i = 0; i < size; ++i) { - IEndpointPair *endpointpair; + ComPtr<IEndpointPair> endpointpair; endpointPairs->GetAt(i, &endpointpair); - IHostName *remoteHost; + ComPtr<IHostName> remoteHost; endpointpair->get_RemoteHostName(&remoteHost); - endpointpair->Release(); HostNameType type; remoteHost->get_Type(&type); if (type == HostNameType_Bluetooth || type == HostNameType_DomainName @@ -138,7 +133,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN HString name; remoteHost->get_CanonicalName(name.GetAddressOf()); - remoteHost->Release(); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); addresses.insert(QHostAddress(QString::fromWCharArray(rawString, length))); diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp index e02cd98e08..26f6585c32 100644 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ b/src/network/kernel/qhostinfo_winrt.cpp @@ -80,29 +80,25 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) return results; } - IHostNameFactory *hostnameFactory; + ComPtr<IHostNameFactory> hostnameFactory; + HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + IID_PPV_ARGS(&hostnameFactory)); + Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); - HStringReference classId(RuntimeClass_Windows_Networking_HostName); - if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) - Q_ASSERT_X(false, "QHostInfoAgent", "Could not obtain hostname factory."); - - IHostName *host; + ComPtr<IHostName> host; HStringReference hostNameRef((const wchar_t*)hostName.utf16()); hostnameFactory->CreateHostName(hostNameRef.Get(), &host); - hostnameFactory->Release(); - IDatagramSocketStatics *datagramSocketStatics; + ComPtr<IDatagramSocketStatics> datagramSocketStatics; GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); - IAsyncOperation<IVectorView<EndpointPair*> *> *op; - datagramSocketStatics->GetEndpointPairsAsync(host, + ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op; + datagramSocketStatics->GetEndpointPairsAsync(host.Get(), HString::MakeReference(L"0").Get(), &op); - datagramSocketStatics->Release(); - host->Release(); - IVectorView<EndpointPair*> *endpointPairs = 0; - HRESULT hr = op->GetResults(&endpointPairs); + ComPtr<IVectorView<EndpointPair *>> endpointPairs; + hr = op->GetResults(&endpointPairs); int waitCount = 0; while (hr == E_ILLEGAL_METHOD_CALL) { WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE); @@ -110,7 +106,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) if (++waitCount > 1200) // Wait for 1 minute max return results; } - op->Release(); if (!endpointPairs) return results; @@ -119,11 +114,10 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) endpointPairs->get_Size(&size); QList<QHostAddress> addresses; for (unsigned int i = 0; i < size; ++i) { - IEndpointPair *endpointpair; + ComPtr<IEndpointPair> endpointpair; endpointPairs->GetAt(i, &endpointpair); - IHostName *remoteHost; + ComPtr<IHostName> remoteHost; endpointpair->get_RemoteHostName(&remoteHost); - endpointpair->Release(); if (!remoteHost) continue; HostNameType type; @@ -133,7 +127,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) HString name; remoteHost->get_CanonicalName(name.GetAddressOf()); - remoteHost->Release(); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); QHostAddress addr; @@ -148,12 +141,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) QString QHostInfo::localHostName() { - INetworkInformationStatics *statics; + ComPtr<INetworkInformationStatics> statics; GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics); - IVectorView<HostName*> *hostNames = 0; + ComPtr<IVectorView<HostName *>> hostNames; statics->GetHostNames(&hostNames); - statics->Release(); if (!hostNames) return QString(); @@ -163,7 +155,7 @@ QString QHostInfo::localHostName() return QString(); for (unsigned int i = 0; i < size; ++i) { - IHostName *hostName; + ComPtr<IHostName> hostName; hostNames->GetAt(i, &hostName); HostNameType type; hostName->get_Type(&type); @@ -172,18 +164,15 @@ QString QHostInfo::localHostName() HString name; hostName->get_CanonicalName(name.GetAddressOf()); - hostName->Release(); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); return QString::fromWCharArray(rawString, length); } - IHostName *firstHost; + ComPtr<IHostName> firstHost; hostNames->GetAt(0, &firstHost); - hostNames->Release(); HString name; firstHost->get_CanonicalName(name.GetAddressOf()); - firstHost->Release(); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); return QString::fromWCharArray(rawString, length); diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp index 48a96928a8..c8547411eb 100644 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ b/src/network/kernel/qnetworkinterface_winrt.cpp @@ -73,12 +73,11 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() QList<HostNameInfo> hostList; - INetworkInformationStatics *hostNameStatics; + ComPtr<INetworkInformationStatics> hostNameStatics; GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics); - IVectorView<HostName*> *hostNames = 0; + ComPtr<IVectorView<HostName *>> hostNames; hostNameStatics->GetHostNames(&hostNames); - hostNameStatics->Release(); if (!hostNames) return interfaces; @@ -86,7 +85,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() hostNames->get_Size(&hostNameCount); for (unsigned i = 0; i < hostNameCount; ++i) { HostNameInfo hostInfo; - IHostName *hostName; + ComPtr<IHostName> hostName; hostNames->GetAt(i, &hostName); HostNameType type; @@ -94,20 +93,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() if (type == HostNameType_DomainName) continue; - IIPInformation *ipInformation; + ComPtr<IIPInformation> ipInformation; hostName->get_IPInformation(&ipInformation); - INetworkAdapter *currentAdapter; + ComPtr<INetworkAdapter> currentAdapter; ipInformation->get_NetworkAdapter(¤tAdapter); currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId); - currentAdapter->Release(); - IReference<unsigned char> *prefixLengthReference; + ComPtr<IReference<unsigned char>> prefixLengthReference; ipInformation->get_PrefixLength(&prefixLengthReference); - ipInformation->Release(); prefixLengthReference->get_Value(&hostInfo.prefixLength); - prefixLengthReference->Release(); // invalid prefixes if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32) @@ -116,20 +112,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() HString name; hostName->get_CanonicalName(name.GetAddressOf()); - hostName->Release(); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); hostInfo.address = QString::fromWCharArray(rawString, length); hostList << hostInfo; } - hostNames->Release(); INetworkInformationStatics *networkInfoStatics; GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics); - IVectorView<ConnectionProfile *> *connectionProfiles = 0; + ComPtr<IVectorView<ConnectionProfile *>> connectionProfiles; networkInfoStatics->GetConnectionProfiles(&connectionProfiles); - networkInfoStatics->Release(); if (!connectionProfiles) return interfaces; @@ -139,7 +132,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; - IConnectionProfile *profile; + ComPtr<IConnectionProfile> profile; connectionProfiles->GetAt(i, &profile); NetworkConnectivityLevel connectivityLevel; @@ -147,16 +140,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() if (connectivityLevel != NetworkConnectivityLevel_None) iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning; - INetworkAdapter *adapter; + ComPtr<INetworkAdapter> adapter; profile->get_NetworkAdapter(&adapter); - profile->Release(); UINT32 type; adapter->get_IanaInterfaceType(&type); if (type == 23) iface->flags |= QNetworkInterface::IsPointToPoint; GUID id; adapter->get_NetworkAdapterId(&id); - adapter->Release(); OLECHAR adapterName[39]={0}; StringFromGUID2(id, adapterName, 39); iface->name = QString::fromWCharArray(adapterName); @@ -179,7 +170,6 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() --i; } } - connectionProfiles->Release(); return interfaces; } diff --git a/src/network/network.pro b/src/network/network.pro index 79e357e0cb..4cced923f7 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -25,3 +25,14 @@ include(socket/socket.pri) include(ssl/ssl.pri) QMAKE_LIBS += $$QMAKE_LIBS_NETWORK + +ANDROID_BUNDLED_JAR_DEPENDENCIES = \ + jar/QtAndroidBearer-bundled.jar +ANDROID_JAR_DEPENDENCIES = \ + jar/QtAndroidBearer.jar +ANDROID_LIB_DEPENDENCIES = \ + plugins/bearer/libqandroidbearer.so +MODULE_PLUGIN_TYPES = \ + bearer +ANDROID_PERMISSIONS += \ + android.permission.ACCESS_NETWORK_STATE diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 65244ce9cf..472e0cb98c 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -365,7 +365,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port) { #ifdef QNATIVESOCKETENGINE_DEBUG - qDebug("QNativeSocketEnginePrivate::nativeConnect() : %lli", socketDescriptor); + qDebug() << "QNativeSocketEnginePrivate::nativeConnect() " << socketDescriptor; #endif struct sockaddr_in sockAddrIPv4; @@ -405,6 +405,9 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 } int connectResult = qt_safe_connect(socketDescriptor, sockAddrPtr, sockAddrSize); +#if defined (QNATIVESOCKETENGINE_DEBUG) + int ecopy = errno; +#endif if (connectResult == -1) { switch (errno) { case EISCONN: @@ -456,7 +459,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)", addr.toString().toLatin1().constData(), port, socketState == QAbstractSocket::ConnectingState - ? "Connection in progress" : socketErrorString.toLatin1().constData()); + ? "Connection in progress" : strerror(ecopy)); #endif return false; } @@ -524,6 +527,9 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 } if (bindResult < 0) { +#if defined (QNATIVESOCKETENGINE_DEBUG) + int ecopy = errno; +#endif switch(errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString); @@ -543,7 +549,7 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)", - address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData()); + address.toString().toLatin1().constData(), port, strerror(ecopy)); #endif return false; @@ -563,6 +569,9 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 bool QNativeSocketEnginePrivate::nativeListen(int backlog) { if (qt_safe_listen(socketDescriptor, backlog) < 0) { +#if defined (QNATIVESOCKETENGINE_DEBUG) + int ecopy = errno; +#endif switch (errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, @@ -574,7 +583,7 @@ bool QNativeSocketEnginePrivate::nativeListen(int backlog) #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)", - backlog, socketErrorString.toLatin1().constData()); + backlog, strerror(ecopy)); #endif return false; } diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 1646940cb8..ab6c2a6590 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -477,16 +477,15 @@ void QNativeSocketEngine::close() { Q_D(QNativeSocketEngine); if (d->socketDescriptor != -1) { - IClosable *socket = 0; + ComPtr<IClosable> socket; if (d->socketType == QAbstractSocket::TcpSocket && d->tcp) - d->tcp->QueryInterface(IID_PPV_ARGS(&socket)); + d->tcp.As(&socket); else if (d->socketType == QAbstractSocket::UdpSocket && d->udp) - d->udp->QueryInterface(IID_PPV_ARGS(&socket)); + d->udp.As(&socket); if (socket) { d->closingDown = true; socket->Close(); - socket->Release(); d->socketDescriptor = -1; } d->socketDescriptor = -1; @@ -624,11 +623,10 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr = returnAddress; *port = returnPort; arg = d->pendingDatagrams.takeFirst(); + arg->Release(); // TODO: fill data Q_UNUSED(data); - arg->Release(); - delete arg; --i; return maxlen; } @@ -833,8 +831,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc SocketHandler *handler = gSocketHandler(); switch (socketType) { case QAbstractSocket::TcpSocket: { - if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), - reinterpret_cast<IInspectable **>(&tcp)))) { + HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &tcp); + if (FAILED(hr)) { qWarning("Failed to create StreamSocket instance"); return false; } @@ -842,8 +840,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc return true; } case QAbstractSocket::UdpSocket: { - if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), - reinterpret_cast<IInspectable **>(&udp)))) { + HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &udp); + if (FAILED(hr)) { qWarning("Failed to create stream socket"); return false; } @@ -1256,7 +1254,7 @@ HRESULT QNativeSocketEnginePrivate::handleWriteCompleted(IAsyncOperationWithProg HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); - Q_UNUSED(socket) + Q_UNUSED(socket); pendingDatagrams.append(args); emit q->readReady(); diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index ec2e1b3ad4..bf23faeb45 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -193,10 +193,8 @@ public: bool checkProxy(const QHostAddress &address); bool fetchConnectionParameters(); private: - union { - ABI::Windows::Networking::Sockets::IStreamSocket *tcp; - ABI::Windows::Networking::Sockets::IDatagramSocket *udp; - }; + Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocket> tcp; + Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IDatagramSocket> udp; Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener; Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> readBuffer; QBuffer readBytes; diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index a113ec156b..4b71f34b3a 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -265,6 +265,22 @@ bool QSslCertificate::isBlacklisted() const } /*! + \since 5.4 + Returns \c true if this certificate is self signed; otherwise + returns \c false. + + A certificate is considered self-signed its issuer and subject + are identical. +*/ +bool QSslCertificate::isSelfSigned() const +{ + if (!d->x509) + return false; + + return (q_X509_check_issued(d->x509, d->x509) == X509_V_OK); +} + +/*! Clears the contents of this certificate, making it a null certificate. @@ -963,6 +979,26 @@ QList<QSslError> QSslCertificate::verify(QList<QSslCertificate> certificateChain return QSslSocketBackendPrivate::verify(certificateChain, hostName); } +/*! + \since 5.4 + + Imports a PKCS#12 (pfx) file from the specified \a device. A PKCS#12 + file is a bundle that can contain a number of certificates and keys. + This method reads a single \a key, its \a certificate and any + associated \a caCertificates from the bundle. If a \a passPhrase is + specified then this will be used to decrypt the bundle. Returns + \c true if the PKCS#12 file was successfully loaded. + + \note The \a device must be open and ready to be read from. + */ +bool QSslCertificate::importPKCS12(QIODevice *device, + QSslKey *key, QSslCertificate *certificate, + QList<QSslCertificate> *caCertificates, + const QByteArray &passPhrase) +{ + return QSslSocketBackendPrivate::importPKCS12(device, key, certificate, caCertificates, passPhrase); +} + void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format) { if (!data.isEmpty()) { diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index 988071eb9d..2217eb7fb9 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -105,6 +105,7 @@ public: } #endif bool isBlacklisted() const; + bool isSelfSigned() const; void clear(); // Certificate info @@ -141,6 +142,11 @@ public: static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName = QString()); + static bool importPKCS12(QIODevice *device, + QSslKey *key, QSslCertificate *cert, + QList<QSslCertificate> *caCertificates=0, + const QByteArray &passPhrase=QByteArray()); + Qt::HANDLE handle() const; private: diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 14881931af..64b75f98ec 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -208,6 +208,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const d->localCertificateChain == other.d->localCertificateChain && d->privateKey == other.d->privateKey && d->sessionCipher == other.d->sessionCipher && + d->sessionProtocol == other.d->sessionProtocol && d->ciphers == other.d->ciphers && d->caCertificates == other.d->caCertificates && d->protocol == other.d->protocol && @@ -512,6 +513,18 @@ QSslCipher QSslConfiguration::sessionCipher() const } /*! + Returns the socket's SSL/TLS protocol or UnknownProtocol if the + connection isn't encrypted. The socket's protocol for the session + is set during the handshake phase. + + \sa protocol(), setProtocol() +*/ +QSsl::SslProtocol QSslConfiguration::sessionProtocol() const +{ + return d->sessionProtocol; +} + +/*! Returns the \l {QSslKey} {SSL key} assigned to this connection or a null key if none has been assigned yet. diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index 587187ca06..4c5799bf28 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -109,6 +109,7 @@ public: QSslCertificate peerCertificate() const; QList<QSslCertificate> peerCertificateChain() const; QSslCipher sessionCipher() const; + QSsl::SslProtocol sessionProtocol() const; // Private keys, for server sockets QSslKey privateKey() const; diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index d183c3335c..29bd4053ad 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -81,7 +81,8 @@ class QSslConfigurationPrivate: public QSharedData { public: QSslConfigurationPrivate() - : protocol(QSsl::SecureProtocols), + : sessionProtocol(QSsl::UnknownProtocol), + protocol(QSsl::SecureProtocols), peerVerifyMode(QSslSocket::AutoVerifyPeer), peerVerifyDepth(0), allowRootCertOnDemandLoading(true), @@ -98,6 +99,7 @@ public: QSslKey privateKey; QSslCipher sessionCipher; + QSsl::SslProtocol sessionProtocol; QList<QSslCipher> ciphers; QList<QSslCertificate> caCertificates; diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp index 95eed6e4b3..b43e28589f 100644 --- a/src/network/ssl/qsslkey.cpp +++ b/src/network/ssl/qsslkey.cpp @@ -96,6 +96,38 @@ void QSslKeyPrivate::clear(bool deep) } } +bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) +{ + if (pkey->type == EVP_PKEY_RSA) { + isNull = false; + algorithm = QSsl::Rsa; + type = QSsl::PrivateKey; + + rsa = q_RSA_new(); + memcpy(rsa, q_EVP_PKEY_get1_RSA(pkey), sizeof(RSA)); + + return true; + } + else if (pkey->type == EVP_PKEY_DSA) { + isNull = false; + algorithm = QSsl::Dsa; + type = QSsl::PrivateKey; + + dsa = q_DSA_new(); + memcpy(rsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA)); + + return true; + } + else { + // Unknown key type. This could be handled as opaque, but then + // we'd eventually leak memory since we wouldn't be able to free + // the underlying EVP_PKEY structure. For now, we won't support + // this. + } + + return false; +} + /*! \internal diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h index 145d4a28f1..59063e2e57 100644 --- a/src/network/ssl/qsslkey.h +++ b/src/network/ssl/qsslkey.h @@ -95,6 +95,7 @@ public: private: QExplicitlySharedDataPointer<QSslKeyPrivate> d; friend class QSslCertificate; + friend class QSslSocketBackendPrivate; }; Q_DECLARE_SHARED(QSslKey) diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 54d12d76fb..658be85621 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -79,6 +79,7 @@ public: void clear(bool deep = true); + bool fromEVP_PKEY(EVP_PKEY *pkey); void decodePem(const QByteArray &pem, const QByteArray &passPhrase, bool deepClear = true); QByteArray pemHeader() const; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 90f6e25b97..8fd9114b2e 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -880,6 +880,7 @@ QSslConfiguration QSslSocket::sslConfiguration() const QSslConfigurationPrivate *copy = new QSslConfigurationPrivate(d->configuration); copy->ref.store(0); // the QSslConfiguration constructor refs up copy->sessionCipher = d->sessionCipher(); + copy->sessionProtocol = d->sessionProtocol(); return QSslConfiguration(copy); } @@ -1075,6 +1076,20 @@ QSslCipher QSslSocket::sessionCipher() const } /*! + Returns the socket's SSL/TLS protocol or UnknownProtocol if the + connection isn't encrypted. The socket's protocol for the session + is set during the handshake phase. + + \sa protocol(), setProtocol() +*/ +QSsl::SslProtocol QSslSocket::sessionProtocol() const +{ + Q_D(const QSslSocket); + return d->sessionProtocol(); +} + + +/*! Sets the socket's private \l {QSslKey} {key} to \a key. The private key and the local \l {QSslCertificate} {certificate} are used by clients and servers that must prove their identity to @@ -1667,6 +1682,32 @@ QString QSslSocket::sslLibraryVersionString() } /*! + \since 5.4 + Returns the version number of the SSL library in use at compile + time. If no SSL support is available then this will return an + undefined value. + + \sa sslLibraryVersionNumber() +*/ +long QSslSocket::sslLibraryBuildVersionNumber() +{ + return QSslSocketPrivate::sslLibraryBuildVersionNumber(); +} + +/*! + \since 5.4 + Returns the version string of the SSL library in use at compile + time. If no SSL support is available then this will return an + empty value. + + \sa sslLibraryVersionString() +*/ +QString QSslSocket::sslLibraryBuildVersionString() +{ + return QSslSocketPrivate::sslLibraryBuildVersionString(); +} + +/*! Starts a delayed SSL handshake for a client connection. This function can be called when the socket is in the \l ConnectedState but still in the \l UnencryptedMode. If it is not yet connected, @@ -2098,6 +2139,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri ptr->localCertificateChain = global->localCertificateChain; ptr->privateKey = global->privateKey; ptr->sessionCipher = global->sessionCipher; + ptr->sessionProtocol = global->sessionProtocol; ptr->ciphers = global->ciphers; ptr->caCertificates = global->caCertificates; ptr->protocol = global->protocol; diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index d89933efda..9cc5e02de3 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -140,6 +140,7 @@ public: QSslCertificate peerCertificate() const; QList<QSslCertificate> peerCertificateChain() const; QSslCipher sessionCipher() const; + QSsl::SslProtocol sessionProtocol() const; // Private keys, for server sockets. void setPrivateKey(const QSslKey &key); @@ -182,6 +183,8 @@ public: static bool supportsSsl(); static long sslLibraryVersionNumber(); static QString sslLibraryVersionString(); + static long sslLibraryBuildVersionNumber(); + static QString sslLibraryBuildVersionString(); void ignoreSslErrors(const QList<QSslError> &errors); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 0315749cb3..f869039687 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -62,6 +62,7 @@ #include "qsslsocket.h" #include "qsslcertificate_p.h" #include "qsslcipher_p.h" +#include "qsslkey_p.h" #include <QtCore/qdatetime.h> #include <QtCore/qdebug.h> @@ -585,6 +586,16 @@ QString QSslSocketPrivate::sslLibraryVersionString() return QString::fromLatin1(versionString); } +long QSslSocketPrivate::sslLibraryBuildVersionNumber() +{ + return OPENSSL_VERSION_NUMBER; +} + +QString QSslSocketPrivate::sslLibraryBuildVersionString() +{ + return QLatin1String(OPENSSL_VERSION_TEXT); +} + /*! \internal @@ -1429,6 +1440,28 @@ QSslCipher QSslSocketBackendPrivate::sessionCipher() const return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher(); } +QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const +{ + if (!ssl) + return QSsl::UnknownProtocol; + int ver = q_SSL_version(ssl); + + switch (ver) { + case 0x2: + return QSsl::SslV2; + case 0x300: + return QSsl::SslV3; + case 0x301: + return QSsl::TlsV1_0; + case 0x302: + return QSsl::TlsV1_1; + case 0x303: + return QSsl::TlsV1_2; + } + + return QSsl::UnknownProtocol; +} + void QSslSocketBackendPrivate::continueHandshake() { Q_Q(QSslSocket); @@ -1703,4 +1736,72 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi return errors; } +bool QSslSocketBackendPrivate::importPKCS12(QIODevice *device, + QSslKey *key, QSslCertificate *cert, + QList<QSslCertificate> *caCertificates, + const QByteArray &passPhrase) +{ + if (!supportsSsl()) + return false; + + // These are required + Q_ASSERT(device); + Q_ASSERT(key); + Q_ASSERT(cert); + + // Read the file into a BIO + QByteArray pkcs12data = device->readAll(); + if (pkcs12data.size() == 0) + return false; + + BIO *bio = q_BIO_new_mem_buf(const_cast<char *>(pkcs12data.constData()), pkcs12data.size()); + + // Create the PKCS#12 object + PKCS12 *p12 = q_d2i_PKCS12_bio(bio, 0); + if (!p12) { + qWarning("Unable to read PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); + q_BIO_free(bio); + return false; + } + + // Extract the data + EVP_PKEY *pkey; + X509 *x509; + STACK_OF(X509) *ca = 0; + + if (!q_PKCS12_parse(p12, passPhrase.constData(), &pkey, &x509, &ca)) { + qWarning("Unable to parse PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); + q_PKCS12_free(p12); + q_BIO_free(bio); + return false; + } + + // Convert to Qt types + if (!key->d->fromEVP_PKEY(pkey)) { + qWarning("Unable to convert private key"); + q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free)); + q_X509_free(x509); + q_EVP_PKEY_free(pkey); + q_PKCS12_free(p12); + q_BIO_free(bio); + + return false; + } + + *cert = QSslCertificatePrivate::QSslCertificate_from_X509(x509); + + if (caCertificates) + *caCertificates = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ca); + + // Clean up + q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free)); + q_X509_free(x509); + q_EVP_PKEY_free(pkey); + q_PKCS12_free(p12); + q_BIO_free(bio); + + return true; +} + + QT_END_NAMESPACE diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index c8b23e6cad..f4f2fe842c 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -131,6 +131,7 @@ public: void disconnectFromHost(); void disconnected(); QSslCipher sessionCipher() const; + QSsl::SslProtocol sessionProtocol() const; void continueHandshake(); bool checkSslErrors(); #ifdef Q_OS_WIN @@ -145,6 +146,10 @@ public: Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname); static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName); static QString getErrorsFromOpenSsl(); + static bool importPKCS12(QIODevice *device, + QSslKey *key, QSslCertificate *cert, + QList<QSslCertificate> *caCertificates, + const QByteArray &passPhrase); }; #ifdef Q_OS_WIN diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index d4a4117b8b..ca692510c1 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -146,6 +146,7 @@ DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG) DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG) DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG) +DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG) #if OPENSSL_VERSION_NUMBER < 0x00908000L DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, unsigned char **b, b, long c, c, return 0, return) @@ -186,6 +187,7 @@ DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, retur DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return) DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG) DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return) +DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG) DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return) DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG) @@ -239,6 +241,7 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, retu #else DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return) #endif +DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return) DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return) DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return) DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return) @@ -316,6 +319,7 @@ DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0 #else DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return) #endif +DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return) DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return) DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return) DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return) @@ -368,6 +372,11 @@ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return) DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG) +DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKEY **pkey, pkey, \ + X509 **cert, cert, STACK_OF(X509) **ca, ca, return 1, return); +DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return 0, return); +DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG) + #define RESOLVEFUNC(func) \ if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \ @@ -686,6 +695,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(CRYPTO_num_locks) RESOLVEFUNC(CRYPTO_set_id_callback) RESOLVEFUNC(CRYPTO_set_locking_callback) + RESOLVEFUNC(DSA_new) RESOLVEFUNC(DSA_free) RESOLVEFUNC(ERR_error_string) RESOLVEFUNC(ERR_get_error) @@ -718,6 +728,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY) RESOLVEFUNC(RAND_seed) RESOLVEFUNC(RAND_status) + RESOLVEFUNC(RSA_new) RESOLVEFUNC(RSA_free) RESOLVEFUNC(sk_new_null) RESOLVEFUNC(sk_push) @@ -746,6 +757,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_free) RESOLVEFUNC(SSL_get_ciphers) RESOLVEFUNC(SSL_get_current_cipher) + RESOLVEFUNC(SSL_version) RESOLVEFUNC(SSL_get_error) RESOLVEFUNC(SSL_get_peer_cert_chain) RESOLVEFUNC(SSL_get_peer_certificate) @@ -819,6 +831,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(BASIC_CONSTRAINTS_free) RESOLVEFUNC(AUTHORITY_KEYID_free) RESOLVEFUNC(ASN1_STRING_print) + RESOLVEFUNC(X509_check_issued) RESOLVEFUNC(X509_get_issuer_name) RESOLVEFUNC(X509_get_subject_name) RESOLVEFUNC(X509_verify_cert) @@ -847,6 +860,9 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(BN_bin2bn) RESOLVEFUNC(EC_KEY_new_by_curve_name) RESOLVEFUNC(EC_KEY_free) + RESOLVEFUNC(PKCS12_parse) + RESOLVEFUNC(d2i_PKCS12_bio) + RESOLVEFUNC(PKCS12_free) symbolsResolved = true; delete libs.first; diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 0f3d2673c2..34c0040e56 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -233,6 +233,7 @@ int q_CRYPTO_num_locks(); void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int)); void q_CRYPTO_set_id_callback(unsigned long (*a)()); void q_CRYPTO_free(void *a); +DSA *q_DSA_new(); void q_DSA_free(DSA *a); #if OPENSSL_VERSION_NUMBER >= 0x00908000L // 0.9.8 broke SC and BC by changing this function's signature. @@ -277,6 +278,7 @@ int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b); int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b); void q_RAND_seed(const void *a, int b); int q_RAND_status(); +RSA *q_RSA_new(); void q_RSA_free(RSA *a); int q_sk_num(STACK *a); void q_sk_pop_free(STACK *a, void (*b)(void *)); @@ -330,6 +332,7 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); #else SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); #endif +int q_SSL_version(const SSL *a); int q_SSL_get_error(SSL *a, int b); STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); X509 *q_SSL_get_peer_certificate(SSL *a); @@ -407,6 +410,7 @@ int q_ASN1_STRING_print(BIO *a, const ASN1_STRING *b); #else int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b); #endif +int q_X509_check_issued(X509 *a, X509 *b); X509_NAME *q_X509_get_issuer_name(X509 *a); X509_NAME *q_X509_get_subject_name(X509 *a); int q_X509_verify_cert(X509_STORE_CTX *ctx); @@ -439,6 +443,12 @@ EC_KEY *q_EC_KEY_new_by_curve_name(int nid); void q_EC_KEY_free(EC_KEY *ecdh); #define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh) +// PKCS#12 support +int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); +PKCS12 *q_d2i_PKCS12_bio(BIO *bio, PKCS12 **pkcs12); +void q_PKCS12_free(PKCS12 *pkcs12); + + #define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) #define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) #ifdef SSLEAY_MACROS diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 6281753225..0033a46d98 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -129,6 +129,8 @@ public: static bool supportsSsl(); static long sslLibraryVersionNumber(); static QString sslLibraryVersionString(); + static long sslLibraryBuildVersionNumber(); + static QString sslLibraryBuildVersionString(); static void ensureInitialized(); static void deinitialize(); static QList<QSslCipher> defaultCiphers(); @@ -190,6 +192,7 @@ public: virtual void disconnectFromHost() = 0; virtual void disconnected() = 0; virtual QSslCipher sessionCipher() const = 0; + virtual QSsl::SslProtocol sessionProtocol() const = 0; virtual void continueHandshake() = 0; Q_AUTOTEST_EXPORT static bool rootCertOnDemandLoadingSupported(); |