Beispiel #1
0
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());
    }
}
Beispiel #2
0
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();
}
Beispiel #3
0
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;
}
Beispiel #5
0
// 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) {