/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#include <dpl/log/log.h>
#include <dpl/errno_string.h>
+#include <config.h>
namespace SecurityManager {
{ Bucket::MANIFESTS, std::string("MANIFESTS")},
};
-
CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user,
const std::string &privilege, int operation,
const std::string &bucket)
void CynaraAdmin::UpdateAppPolicy(
const std::string &label,
const std::string &user,
- const std::vector<std::string> &privileges)
-{
- std::unordered_set<std::string> privilegesSet(privileges.begin(), privileges.end());
-
- std::vector<CynaraAdminPolicy> policies;
- CynaraAdmin::getInstance().ListPolicies(
- CynaraAdmin::Buckets.at(Bucket::MANIFESTS),
- label, user, CYNARA_ADMIN_ANY, policies);
+ const std::vector<std::string> &privileges,
+ std::function <bool(const std::string &)> isPrivacy)
+{
+ auto calcPolicies = [&label](
+ const std::string &user,
+ const std::vector<std::string> &privileges,
+ const std::string &bucket,
+ int policyToSet,
+ std::vector<CynaraAdminPolicy> &policies)
+ {
+ std::vector<CynaraAdminPolicy> oldPolicies;
+ std::unordered_set<std::string> privilegesSet(privileges.begin(),
+ privileges.end());
+ CynaraAdmin::getInstance().ListPolicies(bucket, label, user,
+ CYNARA_ADMIN_ANY, oldPolicies);
+
+ // Compare previous policies with set of new requested privileges
+ for (auto &policy : oldPolicies) {
+ if (privilegesSet.erase(policy.privilege)) {
+ // privilege was found and removed from the set, keeping policy
+ LogDebug("(user = " << user << " label = " << label << ") " <<
+ "keeping privilege " << policy.privilege);
+ } else {
+ // privilege was not found in the set, deleting policy
+ policy.result = static_cast<int>(CynaraAdminPolicy::Operation::Delete);
+ LogDebug("(user = " << user << " label = " << label << ") " <<
+ "removing privilege " << policy.privilege);
+ }
+ policies.push_back(std::move(policy));
+ }
- // Compare previous policies with set of new requested privileges
- for (auto &policy : policies) {
- if (privilegesSet.erase(policy.privilege)) {
- // privilege was found and removed from the set, keeping policy
- LogDebug("(user = " << user << " label = " << label << ") " <<
- "keeping privilege " << policy.privilege);
- } else {
- // privilege was not found in the set, deleting policy
- policy.result = static_cast<int>(CynaraAdminPolicy::Operation::Delete);
+ // Add policies for privileges that weren't previously enabled
+ // Those that were previously enabled are now removed from privilegesSet
+ for (const auto &privilege : privilegesSet) {
LogDebug("(user = " << user << " label = " << label << ") " <<
- "removing privilege " << policy.privilege);
+ "adding privilege " << privilege);
+ policies.push_back(CynaraAdminPolicy(label, user, privilege, policyToSet, bucket));
}
- }
+ };
- // Add policies for privileges that weren't previously enabled
- // Those that were previously enabled are now removed from privilegesSet
- for (const auto &privilege : privilegesSet) {
- LogDebug("(user = " << user << " label = " << label << ") " <<
- "adding privilege " << privilege);
- policies.push_back(CynaraAdminPolicy(label, user, privilege,
- static_cast<int>(CynaraAdminPolicy::Operation::Allow),
- Buckets.at(Bucket::MANIFESTS)));
+ std::vector<CynaraAdminPolicy> policies;
+
+ // 1st, performing operation on MANIFESTS bucket
+ calcPolicies(user, privileges, Buckets.at(Bucket::MANIFESTS),
+ static_cast<int>(CynaraAdminPolicy::Operation::Allow),
+ policies);
+
+ int askUserPolicy = convertToPolicyType(Config::PRIVACY_POLICY_DESC);
+
+ std::vector<std::string> privacyPrivileges;
+ for (auto &p : privileges)
+ if (isPrivacy(p))
+ privacyPrivileges.push_back(p);
+
+ // 2nd, performing operation on PRIVACY_MANAGER bucket for all affected users
+ if (user == CYNARA_ADMIN_WILDCARD) {
+ // perform bucket setting for all users in the system, app is installed for everyone
+ std::vector<uid_t> users;
+ ListUsers(users);
+ for (uid_t id : users) {
+ calcPolicies(std::to_string(id), privacyPrivileges,
+ Buckets.at(Bucket::PRIVACY_MANAGER),
+ askUserPolicy, policies);
+ }
+ } else {
+ // local single user installation, do it only for that particular user
+ calcPolicies(user, privacyPrivileges, Buckets.at(Bucket::PRIVACY_MANAGER),
+ askUserPolicy, policies);
}
SetPolicies(policies);
}
}
-void CynaraAdmin::UserInit(uid_t uid, security_manager_user_type userType)
+void CynaraAdmin::UserInit(uid_t uid, security_manager_user_type userType,
+ std::function <bool(const std::string &)> isPrivacy)
{
Bucket bucket;
std::vector<CynaraAdminPolicy> policies;
+ std::string userStr = std::to_string(uid);
switch (userType) {
case SM_USER_TYPE_SYSTEM:
}
policies.push_back(CynaraAdminPolicy(CYNARA_ADMIN_WILDCARD,
- std::to_string(static_cast<unsigned int>(uid)),
+ userStr,
CYNARA_ADMIN_WILDCARD,
Buckets.at(bucket),
Buckets.at(Bucket::MAIN)));
+ // for each global app: retrieve its privacy-related privileges and set
+ // their policy in PRIVACY_MANAGER bucket to "Ask user"
+ int askUserPolicy = convertToPolicyType(Config::PRIVACY_POLICY_DESC);
+
+ std::vector<CynaraAdminPolicy> appPolicies;
+ CynaraAdmin::getInstance().ListPolicies(CynaraAdmin::Buckets.at(Bucket::MANIFESTS),
+ CYNARA_ADMIN_ANY, CYNARA_ADMIN_WILDCARD,
+ CYNARA_ADMIN_ANY, appPolicies);
+
+ for (CynaraAdminPolicy &policy : appPolicies)
+ if (isPrivacy(policy.privilege))
+ policies.push_back(CynaraAdminPolicy(policy.client,
+ userStr,
+ policy.privilege,
+ askUserPolicy,
+ Buckets.at(Bucket::PRIVACY_MANAGER)));
+
CynaraAdmin::getInstance().SetPolicies(policies);
}
#include <dpl/log/log.h>
#include <dpl/errno_string.h>
+#include <privilege_info.h>
+
#include <config.h>
#include "protocols.h"
#include "privilege_db.h"
}
}
+bool ServiceImpl::isPrivilegePrivacy(const std::string &privilege)
+{
+ int ret = privilege_info_is_privacy(privilege.c_str());
+ if (ret == 1)
+ return true;
+ if (ret != 0)
+ LogError("privilege_info_is_privacy called with " << privilege << " returned error: " << ret);
+ // FIXME: we should probably disallow such installation where privilege is not known
+ // However, currently privielge-checker seems to return -1 with so many real privileges
+ // that it would make ask-user testing impossible.
+ return false;
+}
+
int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
{
std::vector<std::string> addedPermissions;
/* Get all application ids in the package to generate rules withing the package */
PrivilegeDb::getInstance().GetPkgApps(req.pkgName, pkgContents);
PrivilegeDb::getInstance().GetPkgAuthorId(req.pkgName, authorId);
- CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, cynaraUserStr, req.privileges);
-
+ CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, cynaraUserStr, req.privileges, isPrivilegePrivacy);
// if app is targetted to Tizen 2.X, give other 2.X apps RO rules to it's shared dir
if (isTizen2XVersion(req.tizenVersion))
getTizen2XApps(tizen2XpkgsApps);
if (isTizen2XVersion(req.tizenVersion))
getTizen2XApps(tizen2XpkgsApps);
- CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, cynaraUserStr, std::vector<std::string>());
+ CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, cynaraUserStr, std::vector<std::string>(), isPrivilegePrivacy);
+
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application uninstallation commited to database");
PermissibleSet::updatePermissibleFile(req.uid, req.installationType);
}
try {
- CynaraAdmin::getInstance().UserInit(uidAdded, static_cast<security_manager_user_type>(userType));
+ CynaraAdmin::getInstance().UserInit(uidAdded, static_cast<security_manager_user_type>(userType), isPrivilegePrivacy);
+
} catch (CynaraException::InvalidParam &e) {
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
}