KAuth

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

KDE's Doxygen guidelines are available online.