KAuth

policy-gen.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com>
3 SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8#include "policy-gen.h"
9
10#include <QCoreApplication>
11#include <QDebug>
12#include <QFile>
13#include <QRegularExpression>
14#include <QSettings>
15#include <QStringList>
16
17#include <cerrno>
18#include <cstdio>
19
20using namespace std;
21
23QMap<QString, QString> parseDomain(const QSettings &ini);
24
25int main(int argc, char **argv)
26{
27 QCoreApplication app(argc, argv);
28
29 if (argc < 2) {
30 qCritical("Too few arguments");
31 return 1;
32 }
33
35 if (ini.status()) {
36 qCritical("Error loading file: %s", argv[1]);
37 return 1;
38 }
39
40 if (argc == 3) {
41 // Support an optional 2nd argument pointing to the output file
42 //
43 // This is safer to use in build systems than
44 // "kauth-policy-gen foo.actions > foo.policy" because when using a
45 // redirection "foo.policy" is created even if kauth-policy-gen fails.
46 // This means the first call to make fails, but a second call succeeds
47 // because an empty "foo.policy" exists.
48 if (!freopen(argv[2], "w", stdout)) {
49 qCritical("Failed to open %s for writing: %s", argv[2], strerror(errno));
50 return 1;
51 }
52 }
53
54 output(parse(ini), parseDomain(ini));
55}
56
58{
59 QList<Action> actions;
60
61 // example: [org.kde.kcontrol.kcmfoo.save]
62 const QRegularExpression actionExp(QRegularExpression::anchoredPattern(QStringLiteral("[0-9a-z]+(\\.[0-9a-z]+)*")));
63
64 // example: Description[ca]=Mòdul de control del Foo.
65 const QRegularExpression descriptionExp(QRegularExpression::anchoredPattern(QStringLiteral("description(?:\\[(\\w+)\\])?")),
67
68 // example: Name[ca]=Mòdul de control del Foo
69 const QRegularExpression nameExp(QRegularExpression::anchoredPattern(QStringLiteral("name(?:\\[(\\w+)\\])?")), QRegularExpression::CaseInsensitiveOption);
70
71 // example: Policy=auth_admin
72 const QRegularExpression policyExp(QRegularExpression::anchoredPattern(QStringLiteral("(?:yes|no|auth_self|auth_admin)")));
73
74 const auto listChilds = ini.childGroups();
75 for (const QString &name : listChilds) {
76 Action action;
77
78 if (name == QLatin1String("Domain")) {
79 continue;
80 }
81
82 if (!actionExp.match(name).hasMatch()) {
83 qCritical("Wrong action syntax: %s\n", name.toLatin1().data());
84 exit(1);
85 }
86
87 action.name = name;
88 ini.beginGroup(name);
89
90 const auto listChildKeys = ini.childKeys();
91 for (const QString &key : listChildKeys) {
93 if ((match = descriptionExp.match(key)).hasMatch()) {
94 QString lang = match.captured(1);
95
96 if (lang.isEmpty()) {
97 lang = QString::fromLatin1("en");
98 }
99
100 action.descriptions.insert(lang, ini.value(key).toString());
101
102 } else if ((match = nameExp.match(key)).hasMatch()) {
103 QString lang = match.captured(1);
104
105 if (lang.isEmpty()) {
106 lang = QString::fromLatin1("en");
107 }
108
109 action.messages.insert(lang, ini.value(key).toString());
110
111 } else if (key.toLower() == QLatin1String("policy")) {
112 QString policy = ini.value(key).toString();
113 if (!policyExp.match(policy).hasMatch()) {
114 qCritical("Wrong policy: %s", policy.toLatin1().data());
115 exit(1);
116 }
117 action.policy = policy;
118
119 } else if (key.toLower() == QLatin1String("policyinactive")) {
120 QString policyInactive = ini.value(key).toString();
121 if (!policyExp.match(policyInactive).hasMatch()) {
122 qCritical("Wrong policy: %s", policyInactive.toLatin1().data());
123 exit(1);
124 }
125 action.policyInactive = policyInactive;
126
127 } else if (key.toLower() == QLatin1String("persistence")) {
128 QString persistence = ini.value(key).toString();
129 if (persistence != QLatin1String("session") && persistence != QLatin1String("always")) {
130 qCritical("Wrong persistence: %s", persistence.toLatin1().data());
131 exit(1);
132 }
133 action.persistence = persistence;
134 }
135 }
136
137 if (action.policy.isEmpty() || action.messages.isEmpty() || action.descriptions.isEmpty()) {
138 qCritical("Missing option in action: %s", name.toLatin1().data());
139 exit(1);
140 }
141 ini.endGroup();
142
143 actions.append(action);
144 }
145
146 return actions;
147}
148
149QMap<QString, QString> parseDomain(const QSettings &ini)
150{
152
153 if (ini.childGroups().contains(QString::fromLatin1("Domain"))) {
154 if (ini.contains(QString::fromLatin1("Domain/Name"))) {
155 rethash[QString::fromLatin1("vendor")] = ini.value(QString::fromLatin1("Domain/Name")).toString();
156 }
157 if (ini.contains(QString::fromLatin1("Domain/URL"))) {
158 rethash[QString::fromLatin1("vendorurl")] = ini.value(QString::fromLatin1("Domain/URL")).toString();
159 }
160 if (ini.contains(QString::fromLatin1("Domain/Icon"))) {
161 rethash[QString::fromLatin1("icon")] = ini.value(QString::fromLatin1("Domain/Icon")).toString();
162 }
163 }
164
165 return rethash;
166}
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
KHEALTHCERTIFICATE_EXPORT QVariant parse(const QByteArray &data)
QString name(StandardShortcut id)
char * data()
QString decodeName(const QByteArray &localFileName)
void append(QList< T > &&value)
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
QString anchoredPattern(QStringView expression)
void beginGroup(QAnyStringView prefix)
QStringList childGroups() const const
QStringList childKeys() const const
bool contains(QAnyStringView key) const const
void endGroup()
QVariant value(QAnyStringView key) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QByteArray toLatin1() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:10 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.