Automatically query for Mac Proxy Server credentials
Add support for automatically searching the Mac System Preferences for proxy server username/password. If a user has put credentials in the SystemPreferences->Network->Interface->Proxies area, we will now look in the KeyChain for those files. This will automatically pop up a Permissions dialog from the OS if valid credentials were found which match the server we are trying to access. Task-Number: QTBUG-22033 Change-Id: Ic7952afab4d16a65a87bb2f97a928c1c91167fe7 Reviewed-by: Shane Kearns <shane.kearns@accenture.com>bb10
parent
c524bbbb8a
commit
90520cd834
|
|
@ -65,3 +65,5 @@ SOURCES += \
|
|||
access/qhttpmultipart.cpp
|
||||
|
||||
include($$PWD/../../3rdparty/zlib_dependency.pri)
|
||||
|
||||
mac:LIBS_PRIVATE += -framework Security
|
||||
|
|
|
|||
|
|
@ -82,6 +82,64 @@ Q_GLOBAL_STATIC(QNetworkAccessFtpBackendFactory, ftpBackend)
|
|||
Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <SystemConfiguration/SystemConfiguration.h>
|
||||
#include <Security/SecKeychain.h>
|
||||
|
||||
bool getProxyAuth(const QString& proxyHostname, const QString &scheme, 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) {
|
||||
protocolType = kSecProtocolTypeHTTP;
|
||||
} else if (scheme.compare(QLatin1String("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;
|
||||
}
|
||||
CFRelease(itemRef);
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void ensureInitialized()
|
||||
{
|
||||
#ifndef QT_NO_FTP
|
||||
|
|
@ -1117,6 +1175,18 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen
|
|||
return;
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
//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)) {
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue