File indexing completed on 2025-02-09 06:35:13
0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0002 // SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org> 0003 0004 #include "helper.h" 0005 0006 #include <array> 0007 #include <QDebug> 0008 #include <QProcess> 0009 #include <QStandardPaths> 0010 0011 #include <KAuth/HelperSupport> 0012 0013 template<typename Output, typename... Input> 0014 auto make_array(Input&&... args) -> std::array<Output, sizeof...(args)> // NB: we need suffix notation here so args is defined 0015 { 0016 return {std::forward<Input>(args)...}; 0017 } 0018 0019 KAuth::ActionReply DMIDecodeHelper::systeminformation(const QVariantMap &args) 0020 { 0021 Q_UNUSED(args); 0022 0023 // PATH is super minimal when invoked through dbus 0024 setenv("PATH", "/usr/sbin:/sbin:/usr/local/sbin", 1); 0025 const QString dmidecode = QStandardPaths::findExecutable("dmidecode"); 0026 if (dmidecode.isEmpty()) { 0027 return KAuth::ActionReply::HelperErrorReply(); 0028 } 0029 0030 // NB: Microsoft also outlines a limited set of DMI values to be required for IOT OEM licensing, as such we 0031 // can rely on the same fields to have sound content . Since this only applies to OEMs we still need to filter 0032 // out dummy values though and because of that we can grab more fields, since we'll filter them anyway. 0033 // https://docs.microsoft.com/en-us/windows-hardware/manufacture/iot/license-requirements?view=windows-11#smbios-support 0034 0035 KAuth::ActionReply reply; 0036 for (const auto &key : {QStringLiteral("system-manufacturer"), 0037 QStringLiteral("system-product-name"), 0038 QStringLiteral("system-version"), 0039 QStringLiteral("system-serial-number")}) { 0040 QProcess proc; 0041 proc.start(dmidecode, {QStringLiteral("--string"), key}); 0042 proc.waitForFinished(); 0043 const QByteArray output = proc.readAllStandardOutput().trimmed(); 0044 0045 if (output.isEmpty() || proc.error() != QProcess::UnknownError || proc.exitStatus() != QProcess::NormalExit) { 0046 continue; 0047 } 0048 0049 // Fairly exhaustive filter list based on a dozen or so samples gathered from reddit and other places. 0050 // These are values that may appear in the DMI system information but aren't really useful. 0051 static const auto dummyData = make_array<QString>(QStringLiteral("system version"), 0052 QStringLiteral("system product name"), 0053 QStringLiteral("system serial number"), 0054 QStringLiteral("system manufacturer"), 0055 QStringLiteral("to be filled by o.e.m."), 0056 QStringLiteral("standard"), /* sometimes the version is useless */ 0057 QStringLiteral("sku"), 0058 QStringLiteral("default string"), 0059 QStringLiteral("not specified"), 0060 QStringLiteral("not applicable") 0061 /* may also be empty, but that is filtered above already */); 0062 if (std::find(dummyData.cbegin(), dummyData.cend(), output.toLower()) != dummyData.cend()) { 0063 continue; 0064 } 0065 0066 reply.addData(key, output); 0067 } 0068 return reply; 0069 } 0070 0071 KAUTH_HELPER_MAIN("org.kde.kinfocenter.dmidecode", DMIDecodeHelper) 0072 0073 #include "moc_helper.cpp"