• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

kauthorized.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
00003     Copyright (C) 1998, 1999, 2000 Waldo Bastian <bastian@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kauthorized.h"
00022 
00023 #include <QtCore/QDir>
00024 #include <QtCore/QRegExp>
00025 #include <QList>
00026 
00027 
00028 #include <QCoreApplication>
00029 #include <kglobal.h>
00030 #include <ksharedconfig.h>
00031 #include <kprotocolinfo.h>
00032 #include <kstandarddirs.h>
00033 #include <stdlib.h> // srand(), rand()
00034 #include <unistd.h>
00035 #include <netdb.h>
00036 #include <kurl.h>
00037 #include <kconfiggroup.h>
00038 
00039 #include <QMutex>
00040 #include <QMutexLocker>
00041 #include <QtCore/QBool>
00042 
00043 #ifdef __GNUC__
00044 #warning used non public api for now
00045 #endif
00046 extern bool kde_kiosk_exception;
00047 
00048 
00049 class URLActionRule
00050 {
00051   public:
00052 #define checkExactMatch(s, b) \
00053         if (s.isEmpty()) b = true; \
00054         else if (s[s.length()-1] == '!') \
00055         { b = false; s.truncate(s.length()-1); } \
00056         else b = true;
00057 #define checkStartWildCard(s, b) \
00058         if (s.isEmpty()) b = true; \
00059         else if (s[0] == '*') \
00060         { b = true; s = s.mid(1); } \
00061         else b = false;
00062 #define checkEqual(s, b) \
00063         b = (s == "=");
00064 
00065      URLActionRule(const QString &act,
00066                    const QString &bProt, const QString &bHost, const QString &bPath,
00067                    const QString &dProt, const QString &dHost, const QString &dPath,
00068                    bool perm)
00069                    : action(act),
00070                      baseProt(bProt), baseHost(bHost), basePath(bPath),
00071                      destProt(dProt), destHost(dHost), destPath(dPath),
00072                      permission(perm)
00073                    {
00074                       checkExactMatch(baseProt, baseProtWildCard);
00075                       checkStartWildCard(baseHost, baseHostWildCard);
00076                       checkExactMatch(basePath, basePathWildCard);
00077                       checkExactMatch(destProt, destProtWildCard);
00078                       checkStartWildCard(destHost, destHostWildCard);
00079                       checkExactMatch(destPath, destPathWildCard);
00080                       checkEqual(destProt, destProtEqual);
00081                       checkEqual(destHost, destHostEqual);
00082                    }
00083 
00084      bool baseMatch(const KUrl &url, const QString &protClass) const
00085      {
00086         if (baseProtWildCard)
00087         {
00088            if ( !baseProt.isEmpty() && !url.protocol().startsWith(baseProt) &&
00089                 (protClass.isEmpty() || (protClass != baseProt)) )
00090               return false;
00091         }
00092         else
00093         {
00094            if ( (url.protocol() != baseProt) &&
00095                 (protClass.isEmpty() || (protClass != baseProt)) )
00096               return false;
00097         }
00098         if (baseHostWildCard)
00099         {
00100            if (!baseHost.isEmpty() && !url.host().endsWith(baseHost))
00101               return false;
00102         }
00103         else
00104         {
00105            if (url.host() != baseHost)
00106               return false;
00107         }
00108         if (basePathWildCard)
00109         {
00110            if (!basePath.isEmpty() && !url.path().startsWith(basePath))
00111               return false;
00112         }
00113         else
00114         {
00115            if (url.path() != basePath)
00116               return false;
00117         }
00118         return true;
00119      }
00120 
00121      bool destMatch(const KUrl &url, const QString &protClass, const KUrl &base, const QString &baseClass) const
00122      {
00123         if (destProtEqual)
00124         {
00125            if ( (url.protocol() != base.protocol()) &&
00126                 (protClass.isEmpty() || baseClass.isEmpty() || protClass != baseClass) )
00127               return false;
00128         }
00129         else if (destProtWildCard)
00130         {
00131            if ( !destProt.isEmpty() && !url.protocol().startsWith(destProt) &&
00132                 (protClass.isEmpty() || (protClass != destProt)) )
00133               return false;
00134         }
00135         else
00136         {
00137            if ( (url.protocol() != destProt) &&
00138                 (protClass.isEmpty() || (protClass != destProt)) )
00139               return false;
00140         }
00141         if (destHostWildCard)
00142         {
00143            if (!destHost.isEmpty() && !url.host().endsWith(destHost))
00144               return false;
00145         }
00146         else if (destHostEqual)
00147         {
00148            if (url.host() != base.host())
00149               return false;
00150         }
00151         else
00152         {
00153            if (url.host() != destHost)
00154               return false;
00155         }
00156         if (destPathWildCard)
00157         {
00158            if (!destPath.isEmpty() && !url.path().startsWith(destPath))
00159               return false;
00160         }
00161         else
00162         {
00163            if (url.path() != destPath)
00164               return false;
00165         }
00166         return true;
00167      }
00168 
00169      QString action;
00170      QString baseProt;
00171      QString baseHost;
00172      QString basePath;
00173      QString destProt;
00174      QString destHost;
00175      QString destPath;
00176      bool baseProtWildCard : 1;
00177      bool baseHostWildCard : 1;
00178      bool basePathWildCard : 1;
00179      bool destProtWildCard : 1;
00180      bool destHostWildCard : 1;
00181      bool destPathWildCard : 1;
00182      bool destProtEqual    : 1;
00183      bool destHostEqual    : 1;
00184      bool permission;
00185 };
00186 
00187 class KAuthorizedPrivate {
00188 public:
00189   KAuthorizedPrivate()
00190     :   actionRestrictions( false ), blockEverything(false),mutex(QMutex::Recursive)
00191   {
00192     Q_ASSERT_X(QCoreApplication::instance(),"KAuthorizedPrivate()","There has to be an existing QCoreApplication::instance() pointer");
00193 
00194     KSharedConfig::Ptr config = KGlobal::config();
00195 
00196     Q_ASSERT_X(config,"KAuthorizedPrivate()","There has to be an existing KGlobal::config() pointer");
00197     if (!config) {
00198       blockEverything=true;
00199       return;
00200     }
00201     actionRestrictions = config->hasGroup("KDE Action Restrictions" ) && !kde_kiosk_exception;
00202   }
00203 
00204   ~KAuthorizedPrivate()
00205   {
00206   }
00207 
00208   bool actionRestrictions : 1;
00209   bool blockEverything : 1;
00210   QList<URLActionRule> urlActionRestrictions;
00211   QMutex mutex;
00212 };
00213 
00214 Q_GLOBAL_STATIC(KAuthorizedPrivate,authPrivate)
00215 #define MY_D KAuthorizedPrivate *d=authPrivate();
00216 
00217 
00218 bool KAuthorized::authorize(const QString &genericAction)
00219 {
00220    MY_D
00221    if (d->blockEverything) return false;
00222 
00223    if (!d->actionRestrictions)
00224       return true;
00225 
00226    KConfigGroup cg(KGlobal::config(), "KDE Action Restrictions");
00227    return cg.readEntry(genericAction, true);
00228 }
00229 
00230 bool KAuthorized::authorizeKAction(const QString& action)
00231 {
00232    MY_D
00233    if (d->blockEverything) return false;
00234    if (!d->actionRestrictions || action.isEmpty())
00235       return true;
00236 
00237    return authorize(QLatin1String("action/") + action);
00238 }
00239 
00240 bool KAuthorized::authorizeControlModule(const QString &menuId)
00241 {
00242    if (menuId.isEmpty() || kde_kiosk_exception)
00243       return true;
00244    KConfigGroup cg(KGlobal::config(), "KDE Control Module Restrictions");
00245    return cg.readEntry(menuId, true);
00246 }
00247 
00248 QStringList KAuthorized::authorizeControlModules(const QStringList &menuIds)
00249 {
00250    KConfigGroup cg(KGlobal::config(), "KDE Control Module Restrictions");
00251    QStringList result;
00252    for(QStringList::ConstIterator it = menuIds.begin();
00253        it != menuIds.end(); ++it)
00254    {
00255       if (cg.readEntry(*it, true))
00256          result.append(*it);
00257    }
00258    return result;
00259 }
00260 
00261 static void initUrlActionRestrictions()
00262 {
00263   MY_D
00264   const QString Any;
00265 
00266   d->urlActionRestrictions.clear();
00267   d->urlActionRestrictions.append(
00268     URLActionRule("open", Any, Any, Any, Any, Any, Any, true));
00269   d->urlActionRestrictions.append(
00270     URLActionRule("list", Any, Any, Any, Any, Any, Any, true));
00271 // TEST:
00272 //  d->urlActionRestrictions.append(
00273 //  URLActionRule("list", Any, Any, Any, Any, Any, Any, false));
00274 //  d->urlActionRestrictions.append(
00275 //  URLActionRule("list", Any, Any, Any, "file", Any, QDir::homePath(), true));
00276   d->urlActionRestrictions.append(
00277     URLActionRule("link", Any, Any, Any, ":internet", Any, Any, true));
00278   d->urlActionRestrictions.append(
00279     URLActionRule("redirect", Any, Any, Any, ":internet", Any, Any, true));
00280 
00281   // We allow redirections to file: but not from internet protocols, redirecting to file:
00282   // is very popular among io-slaves and we don't want to break them
00283   d->urlActionRestrictions.append(
00284     URLActionRule("redirect", Any, Any, Any, "file", Any, Any, true));
00285   d->urlActionRestrictions.append(
00286     URLActionRule("redirect", ":internet", Any, Any, "file", Any, Any, false));
00287 
00288   // local protocols may redirect everywhere
00289   d->urlActionRestrictions.append(
00290     URLActionRule("redirect", ":local", Any, Any, Any, Any, Any, true));
00291 
00292   // Anyone may redirect to about:
00293   d->urlActionRestrictions.append(
00294     URLActionRule("redirect", Any, Any, Any, "about", Any, Any, true));
00295 
00296   // Anyone may redirect to itself, cq. within it's own group
00297   d->urlActionRestrictions.append(
00298     URLActionRule("redirect", Any, Any, Any, "=", Any, Any, true));
00299 
00300   d->urlActionRestrictions.append(
00301     URLActionRule("redirect", "about", Any, Any, Any, Any, Any, true));
00302 
00303 
00304   KConfigGroup cg(KGlobal::config(), "KDE URL Restrictions");
00305   int count = cg.readEntry("rule_count", 0);
00306   QString keyFormat = QString("rule_%1");
00307   for(int i = 1; i <= count; i++)
00308   {
00309     QString key = keyFormat.arg(i);
00310     const QStringList rule = cg.readEntry(key, QStringList());
00311     if (rule.count() != 8)
00312       continue;
00313     QString action = rule[0];
00314     QString refProt = rule[1];
00315     QString refHost = rule[2];
00316     QString refPath = rule[3];
00317     QString urlProt = rule[4];
00318     QString urlHost = rule[5];
00319     QString urlPath = rule[6];
00320     bool bEnabled   = (rule[7].toLower() == "true");
00321 
00322     if (refPath.startsWith("$HOME"))
00323        refPath.replace(0, 5, QDir::homePath());
00324     else if (refPath.startsWith('~'))
00325        refPath.replace(0, 1, QDir::homePath());
00326     if (urlPath.startsWith("$HOME"))
00327        urlPath.replace(0, 5, QDir::homePath());
00328     else if (urlPath.startsWith('~'))
00329        urlPath.replace(0, 1, QDir::homePath());
00330 
00331     if (refPath.startsWith("$TMP"))
00332        refPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
00333     if (urlPath.startsWith("$TMP"))
00334        urlPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
00335 
00336     d->urlActionRestrictions.append(
00337     URLActionRule( action, refProt, refHost, refPath, urlProt, urlHost, urlPath, bEnabled));
00338   }
00339 }
00340 
00341 void KAuthorized::allowUrlAction(const QString &action, const KUrl &_baseURL, const KUrl &_destURL)
00342 {
00343   MY_D
00344   QMutexLocker locker((&d->mutex));
00345   if (authorizeUrlAction(action, _baseURL, _destURL))
00346      return;
00347 
00348   d->urlActionRestrictions.append( URLActionRule
00349       ( action, _baseURL.protocol(), _baseURL.host(), _baseURL.path(KUrl::RemoveTrailingSlash),
00350         _destURL.protocol(), _destURL.host(), _destURL.path(KUrl::RemoveTrailingSlash), true));
00351 }
00352 
00353 bool KAuthorized::authorizeUrlAction(const QString &action, const KUrl &_baseURL, const KUrl &_destURL)
00354 {
00355   MY_D
00356   QMutexLocker locker(&(d->mutex));
00357   if (d->blockEverything) return false;
00358 
00359   if (_destURL.isEmpty())
00360      return true;
00361 
00362   bool result = false;
00363   if (d->urlActionRestrictions.isEmpty())
00364      initUrlActionRestrictions();
00365 
00366   KUrl baseURL(_baseURL);
00367   baseURL.setPath(QDir::cleanPath(baseURL.path()));
00368   QString baseClass = KProtocolInfo::protocolClass(baseURL.protocol());
00369   KUrl destURL(_destURL);
00370   destURL.setPath(QDir::cleanPath(destURL.path()));
00371   QString destClass = KProtocolInfo::protocolClass(destURL.protocol());
00372 
00373   foreach(const URLActionRule &rule, d->urlActionRestrictions) {
00374      if ((result != rule.permission) && // No need to check if it doesn't make a difference
00375          (action == rule.action) &&
00376          rule.baseMatch(baseURL, baseClass) &&
00377          rule.destMatch(destURL, destClass, baseURL, baseClass))
00378      {
00379         result = rule.permission;
00380      }
00381   }
00382   return result;
00383 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal