File indexing completed on 2024-12-08 04:18:38
0001 /* 0002 * SPDX-FileCopyrightText: 2010 Kare Sars <kare dot sars at iki dot fi> 0003 * SPDX-FileCopyrightText: 2014 Gregor Mitsch : port to KDE5 frameworks 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #include "authentication.h" 0009 0010 // Qt includes 0011 #include <QMutex> 0012 #include <QMutexLocker> 0013 #include <QList> 0014 0015 #include <ksanecore_debug.h> 0016 0017 namespace KSaneCore 0018 { 0019 0020 static Authentication *s_instance = nullptr; 0021 Q_GLOBAL_STATIC(QMutex, s_mutex) 0022 0023 struct Authentication::Private { 0024 struct AuthStruct { 0025 QString resource; 0026 QString username; 0027 QString password; 0028 }; 0029 0030 QList<AuthStruct> authList; 0031 }; 0032 0033 Authentication *Authentication::getInstance() 0034 { 0035 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0036 QMutexLocker<QMutex> locker(s_mutex); 0037 #else 0038 QMutexLocker locker(s_mutex); 0039 #endif 0040 0041 if (s_instance == nullptr) { 0042 s_instance = new Authentication(); 0043 } 0044 return s_instance; 0045 } 0046 0047 Authentication::Authentication() : d(new Private) {} 0048 0049 Authentication::~Authentication() 0050 { 0051 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0052 QMutexLocker<QMutex> locker(s_mutex); 0053 #else 0054 QMutexLocker locker(s_mutex); 0055 #endif 0056 d->authList.clear(); 0057 delete d; 0058 } 0059 0060 void Authentication::setDeviceAuth(const QString &resource, const QString &username, const QString &password) 0061 { 0062 // This is a short list so we do not need a QMap... 0063 int i; 0064 for (i = 0; i < d->authList.size(); i++) { 0065 if (resource == d->authList.at(i).resource) { 0066 // update the existing node 0067 d->authList[i].username = username; 0068 d->authList[i].password = password; 0069 break; 0070 } 0071 } 0072 if (i == d->authList.size()) { 0073 // Add a new list node 0074 Private::AuthStruct tmp; 0075 tmp.resource = resource; 0076 tmp.username = username; 0077 tmp.password = password; 0078 d->authList << tmp; 0079 } 0080 } 0081 0082 void Authentication::clearDeviceAuth(const QString &resource) 0083 { 0084 // This is a short list so we do not need a QMap... 0085 for (int i = 0; i < d->authList.size(); i++) { 0086 if (resource == d->authList.at(i).resource) { 0087 d->authList.removeAt(i); 0088 return; 0089 } 0090 } 0091 } 0092 0093 /** static function called by sane_open to get authorization from user */ 0094 void Authentication::authorization(SANE_String_Const resource, SANE_Char *username, SANE_Char *password) 0095 { 0096 qCDebug(KSANECORE_LOG) << resource; 0097 // This is vague in the standard... what can I find in the resource string? 0098 // I have found that "resource contains the backend name + "$MD5$....." 0099 // it does not contain unique identifiers like ":libusb:001:004" 0100 // -> remove $MD5 and later before comparison... 0101 QString res = QString::fromUtf8(resource); 0102 int end = res.indexOf(QStringLiteral("$MD5$")); 0103 res = res.left(end); 0104 qCDebug(KSANECORE_LOG) << res; 0105 0106 const QList<Private::AuthStruct> list = getInstance()->d->authList; 0107 for (const auto &authItem : list) { 0108 qCDebug(KSANECORE_LOG) << res << authItem.resource; 0109 if (authItem.resource.contains(res)) { 0110 qstrncpy(username, authItem.username.toLocal8Bit().constData(), SANE_MAX_USERNAME_LEN); 0111 qstrncpy(password, authItem.password.toLocal8Bit().constData(), SANE_MAX_PASSWORD_LEN); 0112 break; 0113 } 0114 } 0115 } 0116 0117 } // namespace KSaneCore