checkPermission() implementation - possible to limit certificates by regular expressi...
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 10 Oct 2013 12:44:14 +0000 (14:44 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 10 Oct 2013 12:44:14 +0000 (14:44 +0200)
src/Vfs.cpp
src/Vfs.h
src/VfsNs.cpp
src/VfsNs.h

index a31a8c9..1a7dc09 100644 (file)
@@ -61,6 +61,12 @@ void VfsFactory::configure(const std::string& key, const std::string& value) thr
   else if (key == "TokenLife") {
     this->tokenLife_ = (unsigned)atoi(value.c_str());
   }
+  else if (key == "Allow") {
+    this->allow_ = value;
+  }
+  else if (key == "Deny") {
+    this->deny_ = value;
+  }
   else
     throw DmException(DMLITE_CFGERR(DMLITE_UNKNOWN_KEY),
                       "Unrecognised option " + key);
@@ -70,7 +76,7 @@ void VfsFactory::configure(const std::string& key, const std::string& value) thr
 
 Catalog* VfsFactory::createCatalog(PluginManager*) throw (DmException)
 {
-  return new VfsCatalog(this->hostName_);
+  return new VfsCatalog(this->hostName_, this->allow_, this->deny_);
 }
 
 
index 6c6e1f2..022fb04 100644 (file)
--- a/src/Vfs.h
+++ b/src/Vfs.h
@@ -52,6 +52,7 @@ namespace dmlite {
     std::string tokenPasswd_;
     bool        tokenUseIp_;
     unsigned    tokenLife_;
+    std::string allow_, deny_;
 
   private:
     std::string getImplId(void) const throw ();
index 85ee002..08bc0a8 100644 (file)
@@ -10,6 +10,7 @@
 #include <dmlite/cpp/dmlite.h>
 #include <dmlite/cpp/utils/urls.h>
 #include <errno.h>
+#include <regex.h>
 #include <unistd.h>
 #include <algorithm>
 #include "Vfs.h"
@@ -30,17 +31,43 @@ static gid_t getGid(const SecurityContext* ctx) {
 }
 
 
-VfsCatalog::VfsCatalog(const std::string& host) throw (DmException): Catalog(),
+VfsCatalog::VfsCatalog(const std::string& host, const std::string &allow, const std::string &deny) throw (DmException): Catalog(),
         hostName_(host)
 {
-  // Nothing
+  regex_t regex;
+  int ret;
+  char buf[256];
+
+  this->allowRegex = 0;
+  if (!allow.empty()) {
+//fprintf(stderr, "allow regex: '%s'\n", allow.c_str());
+    if ((ret = regcomp(&regex, allow.c_str(), REG_EXTENDED | REG_NOSUB)) != 0) {
+      regerror(ret, &regex, buf, sizeof buf);
+      vfsThrow(EINVAL, "invalid regular expresion for 'Allow': %s", buf);
+    }
+    this->allowRegex = new regex_t(regex);
+  }
+  this->denyRegex = 0;
+  if (!deny.empty()) {
+//fprintf(stderr, "deny regex: '%s'\n", deny.c_str());
+    if ((ret = regcomp(&regex, deny.c_str(), REG_EXTENDED | REG_NOSUB)) != 0)
+      vfsThrow(EINVAL, "invalid regular expresion for 'Deny': %s", buf);
+    this->denyRegex = new regex_t(regex);
+  }
 }
 
 
 
 VfsCatalog::~VfsCatalog()
 {
-  // Nothing
+  if (this->allowRegex) {
+    regfree(this->allowRegex);
+    delete this->allowRegex;
+  }
+  if (this->denyRegex) {
+    regfree(this->denyRegex);
+    delete this->denyRegex;
+  }
 }
 
 
@@ -61,7 +88,21 @@ void VfsCatalog::setStackInstance(StackInstance* si) throw (DmException)
 
 void VfsCatalog::setSecurityContext(const SecurityContext* ctx) throw (DmException)
 {
+  std::string subj = ctx->credentials.clientName;
   secCtx_ = ctx;
+  int ret;
+
+  this->allowCurrent = false;
+  if (this->allowRegex) {
+    if ((ret = regexec(this->allowRegex, subj.c_str(), 0, NULL, 0)) == 0)
+      this->allowCurrent = true;
+//fprintf(stderr, "'%s' %s allow regexp\n", subj.c_str(), ((ret == 0) ? "matches" : "not matches"));
+  }
+  if (this->allowCurrent && this->denyRegex) {
+    if ((ret = regexec(this->denyRegex, subj.c_str(), 0, NULL, 0)) == 0)
+      this->allowCurrent = false;
+//fprintf(stderr, "'%s' %s deny regexp\n", subj.c_str(), ret == 0 ? "matches" : "not matches");
+  }
 }
 
 
@@ -700,6 +741,6 @@ ExtendedStat VfsCatalog::getParent(const std::string& path,
 
 
 int VfsCatalog::checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode) {
-  fprintf(stderr, "VfsCatalog::checkPermissions(inode %lu, %04o)\n", stat.st_ino, mode);
-  return 0;
+//fprintf(stderr, "VfsCatalog::checkPermissions(inode %lu, %04o)\n", stat.st_ino, mode);
+  return this->allowCurrent ? 0 : 1;
 }
index 2e5904a..2ab57d4 100644 (file)
@@ -4,7 +4,9 @@
 #ifndef VFSNS_H
 #define        VFSNS_H
 
+#include <sys/types.h>
 #include <dirent.h>
+#include <regex.h>
 #include <dmlite/cpp/catalog.h>
 
 
@@ -25,7 +27,7 @@ namespace dmlite {
    public:
     /// Constructor
     /// @param retryLimit Limit of retrials.
-    VfsCatalog(const std::string& host) throw (DmException);
+    VfsCatalog(const std::string& host, const std::string& allow, const std::string& deny) throw (DmException);
 
     /// Destructor
     ~VfsCatalog();
@@ -107,6 +109,9 @@ namespace dmlite {
 
    private:
     int checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode);
+
+    regex_t *allowRegex, *denyRegex;
+    bool allowCurrent;
   };
 
 };