From d8921adbf53acc7af049b1b459d6ae43cd011e06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Thu, 10 Oct 2013 14:44:14 +0200 Subject: [PATCH] checkPermission() implementation - possible to limit certificates by regular expressions (Allow and Deny in plugin configuration). --- src/Vfs.cpp | 8 +++++++- src/Vfs.h | 1 + src/VfsNs.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- src/VfsNs.h | 7 ++++++- 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/Vfs.cpp b/src/Vfs.cpp index a31a8c9..1a7dc09 100644 --- a/src/Vfs.cpp +++ b/src/Vfs.cpp @@ -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_); } diff --git a/src/Vfs.h b/src/Vfs.h index 6c6e1f2..022fb04 100644 --- 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 (); diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index 85ee002..08bc0a8 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #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(®ex, allow.c_str(), REG_EXTENDED | REG_NOSUB)) != 0) { + regerror(ret, ®ex, 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(®ex, 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; } diff --git a/src/VfsNs.h b/src/VfsNs.h index 2e5904a..2ab57d4 100644 --- a/src/VfsNs.h +++ b/src/VfsNs.h @@ -4,7 +4,9 @@ #ifndef VFSNS_H #define VFSNS_H +#include #include +#include #include @@ -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; }; }; -- 1.8.2.3