void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy) { Q_ASSERT(auth); // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up. if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm) return; if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm) return; // select another channel QAuthenticator* otherAuth = 0; for (int i = 0; i < channelCount; ++i) { if (i == fromChannel) continue; if (isProxy) otherAuth = &channels[i].proxyAuthenticator; else otherAuth = &channels[i].authenticator; // if the credentials are different, copy them if (otherAuth->user().compare(auth->user())) otherAuth->setUser(auth->user()); if (otherAuth->password().compare(auth->password())) otherAuth->setPassword(auth->password()); } }
void QWebEnginePagePrivate::authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) { Q_Q(QWebEnginePage); QAuthenticator networkAuth; networkAuth.setRealm(realm); if (isProxy) Q_EMIT q->proxyAuthenticationRequired(requestUrl, &networkAuth, challengingHost); else Q_EMIT q->authenticationRequired(requestUrl, &networkAuth); *outUser = networkAuth.user(); *outPassword = networkAuth.password(); }
void MetadataJob::doStart() { if (!m_core) { emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine.")); return; // We can't do anything here without core, so avoid tons of !m_core checks. } const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance(); if (!m_addCompressedPackages) { reset(); emit infoMessage(this, tr("Preparing meta information download...")); const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly(); if (onlineInstaller || m_core->isMaintainer()) { QList<FileTaskItem> items; foreach (const Repository &repo, m_core->settings().repositories()) { if (repo.isEnabled() && productKeyCheck->isValidRepository(repo)) { QAuthenticator authenticator; authenticator.setUser(repo.username()); authenticator.setPassword(repo.password()); if (!repo.isCompressed()) { QString url = repo.url().toString() + QLatin1String("/Updates.xml?"); if (!m_core->value(scUrlQueryString).isEmpty()) url += m_core->value(scUrlQueryString) + QLatin1Char('&'); // also append a random string to avoid proxy caches FileTaskItem item(url.append(QString::number(qrand() * qrand()))); item.insert(TaskRole::UserRole, QVariant::fromValue(repo)); item.insert(TaskRole::Authenticator, QVariant::fromValue(authenticator)); items.append(item); } else { qDebug() << "Trying to parse compressed repo as normal repository."\ "Check repository syntax."; } } } if (items.count() > 0) { startXMLTask(items); } else { emitFinished(); } } else {
KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &suffix, const QString &queryString) { KDUpdater::FileDownloader *downloader = 0; const QFileInfo fi = QFileInfo(m_archivesToDownload.first().first); const Component *const component = m_core->componentByName(QFileInfo(fi.path()).fileName()); if (component) { QString fullQueryString; if (!queryString.isEmpty()) fullQueryString = QLatin1String("?") + queryString; const QUrl url(m_archivesToDownload.first().second + suffix + fullQueryString); const QString &scheme = url.scheme(); downloader = FileDownloaderFactory::instance().create(scheme, this); if (downloader) { downloader->setUrl(url); downloader->setAutoRemoveDownloadedFile(false); QAuthenticator auth; auth.setUser(component->value(QLatin1String("username"))); auth.setPassword(component->value(QLatin1String("password"))); downloader->setAuthenticator(auth); connect(downloader, &FileDownloader::downloadCanceled, this, &DownloadArchivesJob::downloadCanceled); connect(downloader, &FileDownloader::downloadAborted, this, &DownloadArchivesJob::downloadFailed, Qt::QueuedConnection); connect(downloader, &FileDownloader::downloadStatus, this, &DownloadArchivesJob::downloadStatusChanged); if (FileDownloaderFactory::isSupportedScheme(scheme)) { downloader->setDownloadedFileName(component->localTempPath() + QLatin1Char('/') + component->name() + QLatin1Char('/') + fi.fileName() + suffix); } emit outputTextChanged(tr("Downloading archive \"%1\" for component %2.") .arg(fi.fileName() + suffix, component->displayName())); } else { emit outputTextChanged(tr("Scheme %1 not supported (URL: %2).").arg(scheme, url.toString())); } } else { emit outputTextChanged(tr("Cannot find component for %1.").arg(QFileInfo(fi.path()).fileName())); } return downloader; }
// handles the authentication for one channel and eventually re-starts the other channels bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend) { Q_ASSERT(socket); Q_ASSERT(reply); resend = false; //create the response header to be used with QAuthenticatorPrivate. QList<QPair<QByteArray, QByteArray> > fields = reply->header(); //find out the type of authentication protocol requested. QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy); if (authMethod != QAuthenticatorPrivate::None) { int i = indexOf(socket); //Use a single authenticator for all domains. ### change later to use domain/realm QAuthenticator* auth = 0; if (isProxy) { auth = &channels[i].proxyAuthenticator; channels[i].proxyAuthMethod = authMethod; } else { auth = &channels[i].authenticator; channels[i].authMethod = authMethod; } //proceed with the authentication. if (auth->isNull()) auth->detach(); QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth); priv->parseHttpResponse(fields, isProxy); if (priv->phase == QAuthenticatorPrivate::Done) { pauseConnection(); if (!isProxy) { if (channels[i].authenticationCredentialsSent) { auth->detach(); priv = QAuthenticatorPrivate::getPrivate(*auth); priv->hasFailed = true; priv->phase = QAuthenticatorPrivate::Done; channels[i].authenticationCredentialsSent = false; } emit reply->authenticationRequired(reply->request(), auth); #ifndef QT_NO_NETWORKPROXY } else { if (channels[i].proxyCredentialsSent) { auth->detach(); priv = QAuthenticatorPrivate::getPrivate(*auth); priv->hasFailed = true; priv->phase = QAuthenticatorPrivate::Done; channels[i].proxyCredentialsSent = false; } emit reply->proxyAuthenticationRequired(networkProxy, auth); #endif } resumeConnection(); if (priv->phase != QAuthenticatorPrivate::Done) { // send any pending requests copyCredentials(i, auth, isProxy); } } else if (priv->phase == QAuthenticatorPrivate::Start) { // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request, // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them. emit reply->cacheCredentials(reply->request(), auth); } // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done" // then nothing was filled in by the user or the cache // - If withCredentials has been set to false (e.g. by QtWebKit for a cross-origin XMLHttpRequest) then // we need to bail out if authentication is required. if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) { // Reset authenticator so the next request on that channel does not get messed up auth = 0; if (isProxy) channels[i].proxyAuthenticator = QAuthenticator(); else channels[i].authenticator = QAuthenticator(); // authentication is cancelled, send the current contents to the user. emit channels[i].reply->headerChanged(); emit channels[i].reply->readyRead(); QNetworkReply::NetworkError errorCode = isProxy ? QNetworkReply::ProxyAuthenticationRequiredError : QNetworkReply::AuthenticationRequiredError; reply->d_func()->errorString = errorDetail(errorCode, socket); emit reply->finishedWithError(errorCode, reply->d_func()->errorString); // ### at this point the reply could be deleted return true; } //resend the request resend = true; return true; } return false; }
// This is invoked as QueuedConnection from QNetworkAccessHttpBackend in the user thread void QHttpThreadDelegate::startRequest() { #ifdef QHTTPTHREADDELEGATE_DEBUG qDebug() << "QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId(); #endif // Check QThreadStorage for the QNetworkAccessCache // If not there, create this connection cache if (!connections.hasLocalData()) { connections.setLocalData(new QNetworkAccessCache()); } // check if we have an open connection to this host QUrl urlCopy = httpRequest.url(); urlCopy.setPort(urlCopy.port(ssl ? 443 : 80)); QHttpNetworkConnection::ConnectionType connectionType = QHttpNetworkConnection::ConnectionTypeHTTP; #ifndef QT_NO_SSL if (httpRequest.isSPDYAllowed() && ssl) { connectionType = QHttpNetworkConnection::ConnectionTypeSPDY; urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests QList<QByteArray> nextProtocols; nextProtocols << QSslConfiguration::NextProtocolSpdy3_0 << QSslConfiguration::NextProtocolHttp1_1; incomingSslConfiguration.setAllowedNextProtocols(nextProtocols); } #endif // QT_NO_SSL #ifndef QT_NO_NETWORKPROXY if (transparentProxy.type() != QNetworkProxy::NoProxy) cacheKey = makeCacheKey(urlCopy, &transparentProxy); else if (cacheProxy.type() != QNetworkProxy::NoProxy) cacheKey = makeCacheKey(urlCopy, &cacheProxy); else #endif cacheKey = makeCacheKey(urlCopy, 0); // the http object is actually a QHttpNetworkConnection httpConnection = static_cast<QNetworkAccessCachedHttpConnection *>(connections.localData()->requestEntryNow(cacheKey)); if (httpConnection == 0) { // no entry in cache; create an object // the http object is actually a QHttpNetworkConnection #ifdef QT_NO_BEARERMANAGEMENT httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl, connectionType); #else httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl, connectionType, networkSession); #endif #ifndef QT_NO_SSL // Set the QSslConfiguration from this QNetworkRequest. if (ssl && incomingSslConfiguration != QSslConfiguration::defaultConfiguration()) { httpConnection->setSslConfiguration(incomingSslConfiguration); } #endif #ifndef QT_NO_NETWORKPROXY httpConnection->setTransparentProxy(transparentProxy); httpConnection->setCacheProxy(cacheProxy); #endif // cache the QHttpNetworkConnection corresponding to this cache key connections.localData()->addEntry(cacheKey, httpConnection); } else { if (httpRequest.withCredentials()) { QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), 0); if (!credential.user.isEmpty() && !credential.password.isEmpty()) { QAuthenticator auth; auth.setUser(credential.user); auth.setPassword(credential.password); httpConnection->d_func()->copyCredentials(-1, &auth, false); } } } // Send the request to the connection httpReply = httpConnection->sendRequest(httpRequest); httpReply->setParent(this); // Connect the reply signals that we need to handle and then forward if (synchronous) { connect(httpReply,SIGNAL(headerChanged()), this, SLOT(synchronousHeaderChangedSlot())); connect(httpReply,SIGNAL(finished()), this, SLOT(synchronousFinishedSlot())); connect(httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)), this, SLOT(synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError,QString))); connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*))); #ifndef QT_NO_NETWORKPROXY connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*))); #endif // Don't care about ignored SSL errors for now in the synchronous HTTP case. } else if (!synchronous) {