Skip to content

Commit

Permalink
Revert "Revert "Merge pull request rdkcentral#107 from rdkcentral/MET…
Browse files Browse the repository at this point in the history
…ROL-103/SecurityAgent""

This reverts commit 3bb2b97.
  • Loading branch information
scthunderbolt committed Sep 17, 2020
1 parent 8194148 commit 390e57a
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 239 deletions.
30 changes: 30 additions & 0 deletions SecurityAgent/AccessControlList.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2020 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "Module.h"
#include "AccessControlList.h"

namespace WPEFramework {

ENUM_CONVERSION_BEGIN(Plugin::AccessControlList::mode)
{ Plugin::AccessControlList::ALLOWED, _TXT("allowed") },
{ Plugin::AccessControlList::BLOCKED, _TXT("blocked") },
ENUM_CONVERSION_END(Plugin::AccessControlList::mode)

}
206 changes: 143 additions & 63 deletions SecurityAgent/AccessControlList.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@
// helper functions
namespace {

void ReplaceString(std::string& subject, const std::string& search,const std::string& replace)
void ReplaceString(string& subject, const string& search,const string& replace)
{
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
while ((pos = subject.find(search, pos)) != string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}

std::string CreateRegex(const std::string& input)
string CreateRegex(const string& input)
{
std::string regex = input;
string regex = input;

// order of replacing is important
ReplaceString(regex,"*","^[a-zA-Z0-9.]+$");
Expand All @@ -46,9 +46,9 @@ namespace {
return regex;
}

std::string CreateUrlRegex(const std::string& input)
string CreateUrlRegex(const string& input)
{
std::string regex = input;
string regex = input;

// order of replacing is important
ReplaceString(regex,"/","\\/");
Expand All @@ -63,7 +63,6 @@ namespace {

return regex;
}

}

namespace WPEFramework {
Expand All @@ -73,51 +72,98 @@ namespace Plugin {
//if Block then check for Block[] and block if present
//else must be explicitly allowed

// "xreapps.net": {
// "thunder": {
// "default": "blocked",
// "DeviceInfo": {
// "default": "allowed",
// "methods": [ "register", "unregister" ]
// }
// }
// },

class EXTERNAL AccessControlList {
public:
enum mode {
BLOCKED,
ALLOWED
};
private:
class EXTERNAL JSONACL : public Core::JSON::Container {
public:
class Config : public Core::JSON::Container {
class Plugins : public Core::JSON::Container {
public:
class Rules : public Core::JSON::Container {
public:
Rules(const Rules&) = delete;
Rules& operator=(const Rules&) = delete;

Rules()
: Core::JSON::Container()
, Default(BLOCKED)
, Methods()
{
Add(_T("default"), &Default);
Add(_T("methods"), &Methods);
}
~Rules() override
{
}

public:
Core::JSON::EnumType<mode> Default;
Core::JSON::ArrayType<Core::JSON::String> Methods;
};

using PluginsMap = std::map<string, Rules>;

public:
Config(const Config&) = delete;
Config& operator=(const Config&) = delete;
using Iterator = Core::IteratorMapType<const PluginsMap, const Rules&, const string&, PluginsMap::const_iterator>;

Plugins(const Plugins&) = delete;
Plugins& operator=(const Plugins&) = delete;

Config()
Plugins()
: Core::JSON::Container()
, Default(BLOCKED)
, _plugins()
{
Add(_T("allow"), &Allow);
Add(_T("block"), &Block);
Add(_T("default"), &Default);
}
virtual ~Config()
~Plugins() override
{
}

public:
Core::JSON::ArrayType<Core::JSON::String> Allow;
Core::JSON::ArrayType<Core::JSON::String> Block;
};
class Role : public Core::JSON::Container {
public:
Role(const Role&) = delete;
Role& operator=(const Role&) = delete;
Core::JSON::EnumType<mode> Default;

Role()
: Configuration()
inline Iterator Elements() const
{
Add(_T("thunder"), &Configuration);
return (Iterator(_plugins));
}
virtual ~Role()

private:
virtual bool Request(const TCHAR label[])
{
if (_plugins.find(label) == _plugins.end()) {
auto element = _plugins.emplace(std::piecewise_construct,
std::forward_as_tuple(label),
std::forward_as_tuple());
Add(element.first->first.c_str(), &(element.first->second));
}
return (true);
}

public:
Config Configuration;
private:
PluginsMap _plugins;
};

class Roles : public Core::JSON::Container {
private:
using RolesMap = std::map<string, Role>;
using RolesMap = std::map<string, Plugins>;

public:
using Iterator = Core::IteratorMapType<const RolesMap, const Role&, const string&, RolesMap::const_iterator>;
using Iterator = Core::IteratorMapType<const RolesMap, const Plugins&, const string&, RolesMap::const_iterator>;

Roles(const Roles&) = delete;
Roles& operator=(const Roles&) = delete;
Expand Down Expand Up @@ -205,58 +251,90 @@ namespace Plugin {

public:
class Filter {
private:
class Plugin {
public:
Plugin() = delete;
Plugin(const Plugin&) = delete;
Plugin& operator= (const Plugin&) = delete;

Plugin (const JSONACL::Plugins::Rules& rules)
: _defaultBlocked(rules.Default.Value() == mode::BLOCKED)
, _methods() {
Core::JSON::ArrayType<Core::JSON::String>::ConstIterator index(rules.Methods.Elements());
while (index.Next() == true) {
string str = index.Current().Value();
_methods.emplace_back(CreateRegex(str));
}
}
~Plugin() {
}

public:
bool Allowed(const string& method) const
{
bool found = false;

std::list<string>::const_iterator index(_methods.begin());

while ((index != _methods.end()) && (found == false)) {
std::regex expression(index->c_str());
std::smatch matchList;
found = std::regex_search(method, matchList, expression);
if (found == false) {
index++;
}
}
return !(_defaultBlocked ^ found);
}

private:
bool _defaultBlocked;
std::list<string> _methods;
};

public:
Filter() = delete;
Filter(const Filter&) = delete;
Filter& operator=(const Filter&) = delete;

Filter(const JSONACL::Config& filter)
Filter(const JSONACL::Plugins& plugins)
: _defaultBlocked(plugins.Default.Value() == mode::BLOCKED)
, _plugins()
{
Core::JSON::ArrayType<Core::JSON::String>::ConstIterator index(filter.Allow.Elements());
std::string str;
while (index.Next() == true) {
str = index.Current().Value();
_allow.emplace_back(CreateRegex(str));
}
index = (filter.Block.Elements());
JSONACL::Plugins::Iterator index(plugins.Elements());

while (index.Next() == true) {
str = index.Current().Value();
_block.emplace_back(CreateRegex(str));
_plugins.emplace(std::piecewise_construct,
std::forward_as_tuple(CreateRegex(index.Key())),
std::forward_as_tuple(index.Current()));
}
}
~Filter()
{
}

public:
bool Allowed(const string& method) const
bool Allowed(const string callsign, const string& method) const
{
bool allowed = false;
if (_allowSet) {
std::list<string>::const_iterator index(_allow.begin());
while ((index != _allow.end()) && (allowed == false)) {
std::regex expression(index->c_str());
std::smatch matchList;
allowed = std::regex_search(method, matchList, expression);
index++;
}
} else {
allowed = true;
std::list<string>::const_iterator index(_block.begin());
while ((index != _block.end()) && (allowed == true)) {
std::regex expression(index->c_str());
std::smatch matchList;
allowed = !std::regex_search(method, matchList, expression);
bool pluginFound = false;

std::map<string, Plugin>::const_iterator index(_plugins.begin());
while ((index != _plugins.end()) && (pluginFound == false)) {
std::regex expression(index->first.c_str());
std::smatch matchList;
pluginFound = std::regex_search(callsign, matchList, expression);
if (pluginFound == false) {
index++;
}
}
return (allowed);

return (pluginFound == false ? !_defaultBlocked : index->second.Allowed(method));
}

private:
bool _allowSet;
std::list<string> _allow;
std::list<string> _block;
bool _defaultBlocked;
std::map<string, Plugin> _plugins;
};

using URLList = std::list<std::pair<string, Filter&>>;
Expand Down Expand Up @@ -308,7 +386,9 @@ namespace Plugin {
if (std::regex_search(URL, matchList, expression) == true) {
result = &(index->second);
}
index++;
else {
index++;
}
}

return (result);
Expand All @@ -333,7 +413,7 @@ namespace Plugin {

_filterMap.emplace(std::piecewise_construct,
std::forward_as_tuple(roleName),
std::forward_as_tuple(rolesIndex.Current().Configuration));
std::forward_as_tuple(rolesIndex.Current()));
}

Core::JSON::ArrayType<JSONACL::Group>::Iterator index = controlList.Groups.Elements();
Expand All @@ -354,7 +434,7 @@ namespace Plugin {
Filter& entry(selectedFilter->second);

// create regex for url
std::string url_regex = CreateUrlRegex(index.Current().URL.Value());
string url_regex = CreateUrlRegex(index.Current().URL.Value());

_urlMap.emplace_back(std::pair<string, Filter&>(
url_regex, entry));
Expand Down
1 change: 1 addition & 0 deletions SecurityAgent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ find_package(${NAMESPACE}Plugins REQUIRED)
find_package(CompileSettingsDebug CONFIG REQUIRED)

add_library(${MODULE_NAME} SHARED
AccessControlList.cpp
SecurityAgent.cpp
SecurityContext.cpp
SecurityAgentJsonRpc.cpp
Expand Down
8 changes: 6 additions & 2 deletions SecurityAgent/SecurityAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ namespace Plugin {

if (index.Next() == true) {
// We might be receiving a plugin download request.
#ifdef SECURITY_TESTING_MODE
if ((request.Verb == Web::Request::HTTP_PUT) && (request.HasBody() == true)) {
if (index.Current() == _T("Token")) {
Core::ProxyType<const Web::TextBody> data(request.Body<Web::TextBody>());
Expand All @@ -224,12 +225,15 @@ namespace Plugin {

result->Body(token);
result->ContentType = Web::MIMETypes::MIME_TEXT;
result->ErrorCode = Core::ERROR_NONE;
result->ErrorCode = Web::STATUS_OK;
result->Message = "Ok";
}
}
}
} else if ( (request.Verb == Web::Request::HTTP_GET) && (index.Current() == _T("Valid")) ) {
} else
#endif

if ( (request.Verb == Web::Request::HTTP_GET) && (index.Current() == _T("Valid")) ) {
result->ErrorCode = Web::STATUS_FORBIDDEN;
result->Message = _T("Missing token");

Expand Down
4 changes: 3 additions & 1 deletion SecurityAgent/SecurityAgent.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ namespace Plugin {
// -------------------------------------------------------------------------------------------------------
void RegisterAll();
void UnregisterAll();
uint32_t endpoint_createtoken(const JsonData::SecurityAgent::CreatetokenParamsData& params, JsonData::SecurityAgent::CreatetokenResultInfo& response);
#ifdef SECURITY_TESTING_MODE
uint32_t endpoint_createtoken(const JsonData::SecurityAgent::CreatetokenParamsData& params, JsonData::SecurityAgent::CreatetokenResultInfo& response);
#endif // DEBUG
uint32_t endpoint_validate(const JsonData::SecurityAgent::CreatetokenResultInfo& params, JsonData::SecurityAgent::ValidateResultData& response);


Expand Down
Loading

0 comments on commit 390e57a

Please sign in to comment.