/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* @file src/service/logic/Logic.cpp
* @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author Zofia Abramowska <z.abramowska@samsung.com>
+ * @author Pawel Wieczorek <p.wieczorek2@samsung.com>
* @version 1.0
* @brief This file implements main class of logic layer in cynara service
*/
#include <exceptions/PluginErrorException.h>
#include <exceptions/PluginNotFoundException.h>
#include <exceptions/UnexpectedErrorException.h>
+#include <exceptions/UnknownPolicyTypeException.h>
#include <request/AdminCheckRequest.h>
#include <request/AgentActionRequest.h>
#include <request/AgentRegisterRequest.h>
#include <request/RequestContext.h>
#include <request/SetPoliciesRequest.h>
#include <request/SignalRequest.h>
+#include <request/SimpleCheckRequest.h>
#include <response/AdminCheckResponse.h>
#include <response/AgentRegisterResponse.h>
#include <response/CancelResponse.h>
#include <response/CodeResponse.h>
#include <response/DescriptionListResponse.h>
#include <response/ListResponse.h>
+#include <response/SimpleCheckResponse.h>
#include <types/Policy.h>
#include <main/Cynara.h>
namespace Cynara {
-Logic::Logic() {
+Logic::Logic() : m_dbCorrupted(false) {
}
Logic::~Logic() {
void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) {
PolicyResult result;
bool bucketValid = true;
- try {
- result = m_storage->checkPolicy(request->key(), request->startBucket(),
- request->recursive());
- } catch (const BucketNotExistsException &ex) {
+
+ if (m_dbCorrupted) {
bucketValid = false;
+ } else {
+ try {
+ result = m_storage->checkPolicy(request->key(), request->startBucket(),
+ request->recursive());
+ } catch (const BucketNotExistsException &ex) {
+ bucketValid = false;
+ }
}
context->returnResponse(context, std::make_shared<AdminCheckResponse>(result, bucketValid,
- request->sequenceNumber()));
+ m_dbCorrupted, request->sequenceNumber()));
}
void Logic::execute(RequestContextPtr context, AgentActionRequestPtr request) {
void Logic::execute(RequestContextPtr context, CheckRequestPtr request) {
PolicyResult result(PredefinedPolicyType::DENY);
if (check(context, request->key(), request->sequenceNumber(), result)) {
+ m_auditLog.log(request->key(), result);
context->returnResponse(context, std::make_shared<CheckResponse>(result,
request->sequenceNumber()));
}
return false;
}
- result = m_storage->checkPolicy(key);
+ result = (m_dbCorrupted ? PredefinedPolicyType::DENY : m_storage->checkPolicy(key));
switch (result.policyType()) {
case PredefinedPolicyType::ALLOW :
ServicePluginInterfacePtr servicePlugin =
std::dynamic_pointer_cast<ServicePluginInterface>(plugin);
- if (!plugin) {
- throw PluginNotFoundException(result);
+ if (!servicePlugin) {
+ result = PolicyResult(PredefinedPolicyType::DENY);
+ return true;
}
AgentType requiredAgent;
}
return false;
default:
- throw PluginErrorException(key); // This 'throw' should be removed or handled properly.
+ result = PolicyResult(PredefinedPolicyType::DENY);
+ return true;
}
}
}
if (answerReady && context->responseQueue()) {
+ m_auditLog.log(key, result);
context->returnResponse(context, std::make_shared<CheckResponse>(result, checkId));
return true;
}
descriptions.insert(descriptions.begin(), predefinedPolicyDescr.begin(),
predefinedPolicyDescr.end());
context->returnResponse(context, std::make_shared<DescriptionListResponse>(descriptions,
- request->sequenceNumber()));
+ m_dbCorrupted, request->sequenceNumber()));
}
void Logic::execute(RequestContextPtr context, EraseRequestPtr request) {
auto code = CodeResponse::Code::OK;
- try {
- m_storage->erasePolicies(request->startBucket(), request->recursive(), request->filter());
- onPoliciesChanged();
- } catch (const DatabaseException &ex) {
- code = CodeResponse::Code::FAILED;
- } catch (const BucketNotExistsException &ex) {
- code = CodeResponse::Code::NO_BUCKET;
+ if (m_dbCorrupted) {
+ code = CodeResponse::Code::DB_CORRUPTED;
+ } else {
+ try {
+ m_storage->erasePolicies(request->startBucket(), request->recursive(), request->filter());
+ onPoliciesChanged();
+ } catch (const DatabaseException &ex) {
+ code = CodeResponse::Code::FAILED;
+ } catch (const BucketNotExistsException &ex) {
+ code = CodeResponse::Code::NO_BUCKET;
+ }
}
context->returnResponse(context, std::make_shared<CodeResponse>(code,
void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) {
auto code = CodeResponse::Code::OK;
- try {
- m_storage->addOrUpdateBucket(request->bucketId(), request->result());
- onPoliciesChanged();
- } catch (const DatabaseException &ex) {
- code = CodeResponse::Code::FAILED;
- } catch (const DefaultBucketSetNoneException &ex) {
- code = CodeResponse::Code::NOT_ALLOWED;
- } catch (const InvalidBucketIdException &ex) {
- code = CodeResponse::Code::NOT_ALLOWED;
+ if (m_dbCorrupted) {
+ code = CodeResponse::Code::DB_CORRUPTED;
+ } else {
+ try {
+ checkSinglePolicyType(request->result().policyType(), true, true);
+ m_storage->addOrUpdateBucket(request->bucketId(), request->result());
+ onPoliciesChanged();
+ } catch (const DatabaseException &ex) {
+ code = CodeResponse::Code::FAILED;
+ } catch (const DefaultBucketSetNoneException &ex) {
+ code = CodeResponse::Code::NOT_ALLOWED;
+ } catch (const InvalidBucketIdException &ex) {
+ code = CodeResponse::Code::NOT_ALLOWED;
+ } catch (const UnknownPolicyTypeException &ex) {
+ code = CodeResponse::Code::NO_POLICY_TYPE;
+ }
}
context->returnResponse(context, std::make_shared<CodeResponse>(code,
void Logic::execute(RequestContextPtr context, ListRequestPtr request) {
bool bucketValid = true;
-
std::vector<Policy> policies;
- try {
- policies = m_storage->listPolicies(request->bucket(), request->filter());
- } catch (const BucketNotExistsException &ex) {
+
+ if (m_dbCorrupted) {
bucketValid = false;
+ } else {
+ try {
+ policies = m_storage->listPolicies(request->bucket(), request->filter());
+ } catch (const BucketNotExistsException &ex) {
+ bucketValid = false;
+ }
}
context->returnResponse(context, std::make_shared<ListResponse>(policies, bucketValid,
- request->sequenceNumber()));
+ m_dbCorrupted, request->sequenceNumber()));
}
void Logic::execute(RequestContextPtr context, RemoveBucketRequestPtr request) {
auto code = CodeResponse::Code::OK;
- try {
- m_storage->deleteBucket(request->bucketId());
- onPoliciesChanged();
- } catch (const DatabaseException &ex) {
- code = CodeResponse::Code::FAILED;
- } catch (const BucketNotExistsException &ex) {
- code = CodeResponse::Code::NO_BUCKET;
- } catch (const DefaultBucketDeletionException &ex) {
- code = CodeResponse::Code::NOT_ALLOWED;
+
+ if (m_dbCorrupted) {
+ code = CodeResponse::Code::DB_CORRUPTED;
+ } else {
+ try {
+ m_storage->deleteBucket(request->bucketId());
+ onPoliciesChanged();
+ } catch (const DatabaseException &ex) {
+ code = CodeResponse::Code::FAILED;
+ } catch (const BucketNotExistsException &ex) {
+ code = CodeResponse::Code::NO_BUCKET;
+ } catch (const DefaultBucketDeletionException &ex) {
+ code = CodeResponse::Code::NOT_ALLOWED;
+ }
}
+
context->returnResponse(context, std::make_shared<CodeResponse>(code,
request->sequenceNumber()));
}
void Logic::execute(RequestContextPtr context, SetPoliciesRequestPtr request) {
auto code = CodeResponse::Code::OK;
- try {
- m_storage->insertPolicies(request->policiesToBeInsertedOrUpdated());
- m_storage->deletePolicies(request->policiesToBeRemoved());
- onPoliciesChanged();
- } catch (const DatabaseException &ex) {
- code = CodeResponse::Code::FAILED;
- } catch (const BucketNotExistsException &ex) {
- code = CodeResponse::Code::NO_BUCKET;
+
+ if (m_dbCorrupted) {
+ code = CodeResponse::Code::DB_CORRUPTED;
+ } else {
+ try {
+ checkPoliciesTypes(request->policiesToBeInsertedOrUpdated(), true, false);
+ m_storage->insertPolicies(request->policiesToBeInsertedOrUpdated());
+ m_storage->deletePolicies(request->policiesToBeRemoved());
+ onPoliciesChanged();
+ } catch (const DatabaseException &ex) {
+ code = CodeResponse::Code::FAILED;
+ } catch (const BucketNotExistsException &ex) {
+ code = CodeResponse::Code::NO_BUCKET;
+ } catch (const UnknownPolicyTypeException &ex) {
+ code = CodeResponse::Code::NO_POLICY_TYPE;
+ }
}
+
context->returnResponse(context, std::make_shared<CodeResponse>(code,
request->sequenceNumber()));
}
+void Logic::execute(RequestContextPtr context, SimpleCheckRequestPtr request) {
+ int retValue = CYNARA_API_SUCCESS;
+ PolicyResult result;
+ PolicyKey key = request->key();
+ result = m_storage->checkPolicy(key);
+
+ switch (result.policyType()) {
+ case PredefinedPolicyType::ALLOW:
+ LOGD("simple check of policy key <%s> returned ALLOW", key.toString().c_str());
+ break;
+ case PredefinedPolicyType::DENY:
+ LOGD("simple check of policy key <%s> returned DENY", key.toString().c_str());
+ break;
+ default: {
+ ExternalPluginPtr plugin = m_pluginManager->getPlugin(result.policyType());
+ if (!plugin) {
+ LOGE("Plugin not found for policy: [0x%x]", result.policyType());
+ result = PolicyResult(PredefinedPolicyType::DENY);
+ retValue = CYNARA_API_SUCCESS;
+ break;
+ }
+
+ ServicePluginInterfacePtr servicePlugin =
+ std::dynamic_pointer_cast<ServicePluginInterface>(plugin);
+ if (!servicePlugin) {
+ LOGE("Couldn't cast plugin pointer to ServicePluginInterface");
+ result = PolicyResult(PredefinedPolicyType::DENY);
+ retValue = CYNARA_API_SUCCESS;
+ break;
+ }
+
+ AgentType requiredAgent;
+ PluginData pluginData;
+ auto ret = servicePlugin->check(key.client().toString(), key.user().toString(),
+ key.privilege().toString(), result, requiredAgent,
+ pluginData);
+ switch (ret) {
+ case ServicePluginInterface::PluginStatus::ANSWER_READY:
+ LOGD("simple check of policy key <%s> in plugin returned [" PRIu16 "]",
+ key.toString().c_str(), result.policyType());
+ break;
+ case ServicePluginInterface::PluginStatus::ANSWER_NOTREADY:
+ retValue = CYNARA_API_ACCESS_NOT_RESOLVED;
+ break;
+ default:
+ result = PolicyResult(PredefinedPolicyType::DENY);
+ retValue = CYNARA_API_SUCCESS;
+ }
+ }
+ }
+ m_auditLog.log(request->key(), result);
+ context->returnResponse(context, std::make_shared<SimpleCheckResponse>(retValue, result,
+ request->sequenceNumber()));
+}
+
+void Logic::checkPoliciesTypes(const std::map<PolicyBucketId, std::vector<Policy>> &policies,
+ bool allowBucket, bool allowNone) {
+ for (const auto &group : policies) {
+ for (const auto &policy : group.second) {
+ checkSinglePolicyType(policy.result().policyType(), allowBucket, allowNone);
+ }
+ }
+}
+
+void Logic::checkSinglePolicyType(const PolicyType &policyType, bool allowBucket, bool allowNone) {
+ if (allowBucket && policyType == PredefinedPolicyType::BUCKET)
+ return;
+ if (allowNone && policyType == PredefinedPolicyType::NONE)
+ return;
+ for (const auto &descr : predefinedPolicyDescr) {
+ if (descr.type == policyType)
+ return;
+ }
+ m_pluginManager->checkPolicyType(policyType);
+}
+
void Logic::contextClosed(RequestContextPtr context) {
LOGD("context closed");
if (!checkContextPtr->cancelled() && checkContextPtr->m_requestContext->responseQueue()) {
PolicyResult result(PredefinedPolicyType::DENY);
+ m_auditLog.log(checkContextPtr->m_key, result);
checkContextPtr->m_requestContext->returnResponse(checkContextPtr->m_requestContext,
std::make_shared<CheckResponse>(result, checkContextPtr->m_checkId));
}