Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-40622

Segfault in QNetworkAccessManager when using bad credentials

    XMLWordPrintable

Details

    • 3e804976687ce3dbe424ae5dfa47bba0a6280ce1

    Description

      the issue QTBUG-11824 seems to have been partially solved, because I still face it in case two requests are made with bad credentials (identical or not). At the second trial, I get

      QNetworkAccessCache::removeEntry: trying to remove key 'ftp-connection:ftp://host:21' that is not in cache

      Then I get a segfault when deleting the network access manager.
      The Url used is the following ftp://user:password@host:21/data, and the signal QNetworkAccessManager::authenticationRequired is not connected.

      After digging into QNetworkAccessFtpBackend, I noticed the following:
      It seems like during the first request, empty credentials are cached (because of newUrl.setUserInfo(QString()); in QNetworkAccessFtpBackend::ftpDone)
      At the second request, inside QNetworkAccessFtpBackend::ftpDone, it enters inside the following condition :

                  QAuthenticator auth;
                  authenticationRequired(&auth);
      
                  if (!auth.isNull()) {
                      // try again:
                      newUrl.setUserName(auth.user());
                      ftp->login(auth.user(), auth.password());
                      return;
                  }

      where it tries to login with empty cached credential, thus the QNetwokAccessCache finally tries to remove the cache entry without credentials whereas it was cached with credentials.

      As a workaround, I suggest avoiding caching empty credentials in QNetworkAccessManagerPrivate::authenticationRequired by changing

          if (allowAuthenticationReuse)
              authenticationManager->cacheCredentials(url, authenticator);

      to

          if (allowAuthenticationReuse && !authenticator->isNull())
              authenticationManager->cacheCredentials(url, authenticator);

      Another solution could be to add the check for is null in QNetworkAccessAuthenticationManager::cacheCredentials :

      void QNetworkAccessAuthenticationManager::cacheCredentials(const QUrl &url,
                                                        const QAuthenticator *authenticator)
      {
          Q_ASSERT(authenticator);
          if(authenticator->isNull()){
              return;
          }

      These are untested pseudo-code

      Attachments

        Activity

          People

            richmoore Richard Moore (qtnetwork)
            ericlemanissier Eric Lemanissier
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: