--- qtbase/src/network/access/qnetworkaccessmanager.cpp 2013-12-08 19:09:47.000000000 +0200 +++ ../5.2.1/qtbase/src/network/access/qnetworkaccessmanager.cpp 2014-02-13 11:26:10.000000000 +0200 @@ -92,53 +92,65 @@ #include #include -bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString& username, QString& password) +bool getCredentialsFromKeychain(const QString& hostname, const QStringList &schemes, QString& username, QString& password) { - OSStatus err; - SecKeychainItemRef itemRef; bool retValue = false; - SecProtocolType protocolType = kSecProtocolTypeAny; - if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) { - protocolType = kSecProtocolTypeFTP; - } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0 - || scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) { - protocolType = kSecProtocolTypeHTTP; - } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0 - || scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) { - protocolType = kSecProtocolTypeHTTPS; - } - QByteArray proxyHostnameUtf8(proxyHostname.toUtf8()); - err = SecKeychainFindInternetPassword(NULL, - proxyHostnameUtf8.length(), proxyHostnameUtf8.constData(), - 0,NULL, - 0, NULL, - 0, NULL, - 0, - protocolType, - kSecAuthenticationTypeAny, - 0, NULL, - &itemRef); - if (err == noErr) { - - SecKeychainAttribute attr; - SecKeychainAttributeList attrList; - UInt32 length; - void *outData; - - attr.tag = kSecAccountItemAttr; - attr.length = 0; - attr.data = NULL; - - attrList.count = 1; - attrList.attr = &attr; - - if (SecKeychainItemCopyContent(itemRef, NULL, &attrList, &length, &outData) == noErr) { - username = QString::fromUtf8((const char*)attr.data, attr.length); - password = QString::fromUtf8((const char*)outData, length); - SecKeychainItemFreeContent(&attrList,outData); - retValue = true; + if (!hostname.isEmpty()) + { + OSStatus err; + SecKeychainItemRef itemRef; + foreach (QString scheme, schemes) { + SecProtocolType protocolType = kSecProtocolTypeAny; + if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeFTP; + } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0 + || scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTP; + } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0 + || scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTPS; + } else if (scheme.compare(QLatin1String("http-proxy"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTPProxy; + } else if (scheme.compare(QLatin1String("https-proxy"),Qt::CaseInsensitive)==0) { + protocolType = kSecProtocolTypeHTTPSProxy; + } + QByteArray hostnameUtf8(hostname.toUtf8()); + err = SecKeychainFindInternetPassword(NULL, + hostnameUtf8.length(), hostnameUtf8.constData(), + 0, NULL, + 0, NULL, + 0, NULL, + 0, + protocolType, + kSecAuthenticationTypeAny, + 0, NULL, + &itemRef); + if (err == noErr) { + + SecKeychainAttribute attr; + SecKeychainAttributeList attrList; + UInt32 length; + void *outData; + + attr.tag = kSecAccountItemAttr; + attr.length = 0; + attr.data = NULL; + + attrList.count = 1; + attrList.attr = &attr; + + if (SecKeychainItemCopyContent(itemRef, NULL, &attrList, &length, &outData) == noErr) { + username = QString::fromUtf8((const char*)attr.data, attr.length); + password = QString::fromUtf8((const char*)outData, length); + SecKeychainItemFreeContent(&attrList,outData); + retValue = true; + } + CFRelease(itemRef); + + if (retValue) + break; + } } - CFRelease(itemRef); } return retValue; } @@ -1384,20 +1396,20 @@ } } -#ifndef QT_NO_NETWORKPROXY #if defined(Q_OS_MACX) //now we try to get the username and password from keychain //if not successful signal will be emitted QString username; QString password; - if (getProxyAuth(proxy.hostName(),reply->request().url().scheme(),username,password)) { + QStringList schemes = QStringList() << reply->request().url().scheme(); + if (getCredentialsFromKeychain(reply->request().url().host(), schemes, username,password)) { authenticator->setUser(username); authenticator->setPassword(password); + *urlForLastAuthentication = url; authenticationManager->cacheProxyCredentials(proxy, authenticator); return; } #endif -#endif //QT_NO_NETWORKPROXY // if we emit a signal here in synchronous mode, the user might spin // an event loop, which might recurse and lead to problems @@ -1418,8 +1430,8 @@ { Q_Q(QNetworkAccessManager); QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator); + QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy); if (proxy != *lastProxyAuthentication && (!priv || !priv->hasFailed)) { - QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy); if (!cred.isNull()) { authenticator->setUser(cred.user); authenticator->setPassword(cred.password); @@ -1427,6 +1439,23 @@ } } +#if defined(Q_OS_MACX) + //now we try to get the username and password from keychain + //if not successful signal will be emitted + QString username; + QString password; + QStringList proxySchemes = QStringList() << "http-proxy" << "https-proxy"; + if (getCredentialsFromKeychain(proxy.hostName(), proxySchemes, username, password)) { + if (cred.isNull() || (!cred.isNull() && (cred.user != username || cred.password != password))) { + authenticator->setUser(username); + authenticator->setPassword(password); + authenticationManager->cacheProxyCredentials(proxy, authenticator); + return; + } + } +#endif + + // if we emit a signal here in synchronous mode, the user might spin // an event loop, which might recurse and lead to problems if (synchronous)