summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAron Rosenberg <aronrosenberg@gmail.com>2012-04-04 16:41:27 -0700
committerQt by Nokia <qt-info@nokia.com>2012-04-11 01:42:12 +0200
commit90520cd834d84f2b091fea94f1d44bc6cb863420 (patch)
tree721e2ef556f19faee93d3aa2e2ca0966c07761d2 /src
parentc524bbbb8aa4ba10bac68292a3078534f1b51df5 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/network/access/access.pri2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp70
2 files changed, 72 insertions, 0 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index e0a0253b6c..590a37bf15 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -65,3 +65,5 @@ SOURCES += \
access/qhttpmultipart.cpp
include($$PWD/../../3rdparty/zlib_dependency.pri)
+
+mac:LIBS_PRIVATE += -framework Security
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 397bb0535e..3a69ec4056 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -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