/*
- * Copyright (c) 2018 Samsung Electronics Co.
+ * Copyright (c) 2018-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
m_uid = uid;
}
+int app_func(pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ char *appid = NULL;
+ int ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (ret != PMINFO_R_OK) {
+ ALOGE("pkgmgrinfo_appinfo_get_appid failed with " << ret);
+ return -1;
+ }
+ std::vector<std::string> *output = static_cast<std::vector<std::string>*>(user_data);
+ output->push_back(std::string(appid));
+ return 0;
+}
+
+std::vector<std::string> PkgMgrPkgInfo::listOfAppIds(const std::string &pkgId, uid_t uid)
+{
+ pkgmgrinfo_pkginfo_h handle = nullptr;
+ int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
+ std::vector<std::string> output;
+ if (ret != PMINFO_R_OK) {
+ ALOGE("pkgmgrinfo_pkginfo_get_usr_pkginfo failed for " << pkgId << " with " << ret);
+ return output;
+ }
+ ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP, app_func, &output);
+ if (ret != PMINFO_R_OK) {
+ ALOGE("pkgmgrinfo_appinfo_get_list failed for " << pkgId << " with " << ret);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return std::vector<std::string>();
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return output;
+}
+
void PkgMgrPkgInfo::fetch(const std::string &pkgId, uid_t uid) {
pkgmgrinfo_pkginfo_h handle = nullptr;
int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
/*
- * Copyright (c) 2017-2018 Samsung Electronics Co.
+ * Copyright (c) 2017-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <string>
#include <sys/types.h>
+#include <vector>
namespace AskUser {
};
class PkgMgrPkgInfo : public PkgInfo {
+public:
+ static std::vector<std::string> listOfAppIds(const std::string &pkgId, uid_t uid);
protected:
virtual void fetch(const std::string &pkgId, uid_t uid);
};
/*
- * Copyright (c) 2016-2018 Samsung Electronics Co.
+ * Copyright (c) 2016-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return fetch.fetchPolicy();
}
-void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId)
+void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId, bool &isHybrid)
{
char *pkgName = nullptr;
char *appName = nullptr;
std::unique_ptr<char, decltype(free)*> app_name_p(appName, free);
throwOnSMError("security_manager_identify_app_from_cynara_client", ret);
+ // if the appId was in Smack label of client, it means that the app comes from hybrid package
+ isHybrid = (appName == nullptr ? false : true);
+
if (!pkgName) {
ALOGE("Couldn't identify clients package id");
return;
/*
- * Copyright (c) 2016-2018 Samsung Electronics Co.
+ * Copyright (c) 2016-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
class PolicyEntryCopy;
std::string getOwnAppId(PkgInfo &pkgInfo);
-void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId);
+void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId, bool &isHybrid);
std::set<Privilege> getManifestPrivs(const std::string &appId);
/*
- * Copyright (c) 2017-2018 Samsung Electronics Co.
+ * Copyright (c) 2017-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
std::string appId, pkgId;
PkgMgrPkgInfo pkgInfo;
- identifyApp(pkgInfo, creds.label, appId, pkgId);
+ bool isHybrid;
+ identifyApp(pkgInfo, creds.label, appId, pkgId, isHybrid);
ALOGD("Proper client connected");
stopTimer();
- ConnectionInfo connInfo{appId, pkgId, creds.uid};
+ ConnectionInfo connInfo{appId, pkgId, creds.uid, isHybrid};
m_connToInfo.insert(it, std::make_pair(fd, connInfo));
} catch (const std::exception &e) {
ALOGE("Failed to add channel fd " << fd);
levels[i] = clientResponseToPolicy(currentEvent.privacyResponses[privacy]);
}
- if (!PolicyUpdater::update(conn.appId, currentEvent.uniquePrivacies, levels)) {
+ if (!PolicyUpdater::update(conn.pkgId, conn.appId, conn.isHybrid, currentEvent.uniquePrivacies, levels)) {
ALOGE("Couldn't set policy for " << conn.appId);
return false;
}
/*
- * Copyright (c) 2017-2018 Samsung Electronics Co.
+ * Copyright (c) 2017-2019 Samsung Electronics Co.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
std::string appId;
std::string pkgId;
std::string user;
+ bool isHybrid;
};
struct PrivilegeStruct {
/*
- * Copyright (c) 2016-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2019 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.
#include "PolicyUpdater.h"
#include <policy/Policy.h>
#include <policy/PrivilegeInfo.h>
+#include <policy/PkgInfo.h>
namespace AskUser {
namespace Notification {
-bool PolicyUpdater::update(const std::string &appId, const std::vector<std::string> &privacies,
+bool PolicyUpdater::update(const std::string &pkgId, const std::string &appId, bool isHybrid,
+ const std::vector<std::string> &privacies,
const std::vector<std::string> &levels)
{
try {
- ALOGD("Generating policy update for: app: " << appId << ", user:" << geteuid()
+ uid_t myUid = geteuid();
+ ALOGD("Generating policy update for: app: " << appId << ", hybrid: " << isHybrid << ", user:" << myUid
<< ", privacies num: " << privacies.size());
if (privacies.size() != levels.size() || levels.size() == 0) {
static const std::string user = std::to_string(geteuid());
PolicyRequest req;
- for (size_t i = 0; i < privacies.size(); ++i) {
- const auto &privacy = privacies[i];
- const auto &level = levels[i];
+ std::vector<std::string> appIds = {appId};
- ALOGD("Generating policy update for: app: " << appId << ", user:" << geteuid()
- << ", privacy " << privacy << ", level: " << level);
+ if (isHybrid) {
+ // apps in a hybrid package have distinct Smack labels;
+ // since entire platform manages privileges per package,
+ // here we need to get all apps in the pkg for the policy
+ // to be effective for entire pkg
+ appIds = PkgMgrPkgInfo::listOfAppIds(pkgId, myUid);
+ }
- auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacy);
- if (privacyPrivs.empty()) {
- ALOGE("Unable to get privacy privileges for privacy " << privacy);
- throw Exception("Unable to get privacy privileges for privacy " + privacy);
- }
+ for (auto &app : appIds) {
+ for (size_t i = 0; i < privacies.size(); ++i) {
+ const auto &privacy = privacies[i];
+ const auto &level = levels[i];
+
+ ALOGD("Generating policy update for: app: " << app << ", user:" << geteuid()
+ << ", privacy " << privacy << ", level: " << level);
+
+ auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacy);
+ if (privacyPrivs.empty()) {
+ ALOGE("Unable to get privacy privileges for privacy " << privacy);
+ throw Exception("Unable to get privacy privileges for privacy " + privacy);
+ }
- for (auto &priv : privacyPrivs) {
- std::string currentPolicy = getPrivilegePolicy(appId, priv);
- if (currentPolicy.empty()) {
- ALOGD("Application didn't request privilege " << priv << ", skipping");
- continue;
+ for (auto &priv : privacyPrivs) {
+ std::string currentPolicy = getPrivilegePolicy(app, priv);
+ if (currentPolicy.empty()) {
+ ALOGD("Application didn't request privilege " << priv << ", skipping");
+ continue;
+ }
+ ALOGD("Adding policy entries for : app: " << app << ", priv: "
+ << priv << ", user:" << user << ", level: "
+ << level);
+ PolicyEntry entry;
+ entry.setApp(app);
+ entry.setUser(user);
+ entry.setPrivilege(priv);
+ entry.setLevel(level);
+ req.addEntry(std::move(entry));
}
- ALOGD("Adding policy entries for : app: " << appId << ", priv: "
- << priv << ", user:" << user << ", level: "
- << level);
- PolicyEntry entry;
- entry.setApp(appId);
- entry.setUser(user);
- entry.setPrivilege(priv);
- entry.setLevel(level);
- req.addEntry(std::move(entry));
}
}
/*
- * Copyright (c) 2016 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2019 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.
namespace Notification {
namespace PolicyUpdater {
- bool update(const std::string &appId, const std::vector<std::string> &privacies,
+ bool update(const std::string &pkgId, const std::string &appId, bool isHybrid,
+ const std::vector<std::string> &privacies,
const std::vector<std::string> &levels);
};