#include <widget_install/widget_install_context.h>
#include <widget_install/widget_install_errors.h>
#include <widget_install/job_widget_install.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/utils/bash_utils.h>
+#include <vcore/Certificate.h>
+#include <vcore/CryptoHash.h>
#ifdef WRT_SMACK_ENABLED
#include <privilege-control.h>
+#include <sys/smack.h>
#endif
-
#include <sstream>
+using namespace WrtDB;
+using namespace ValidationCore;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+void freeList(const char** list) {
+ for (int i = 0; list[i] != NULL; i++)
+ {
+ delete(list[i]);
+ }
+ delete[] list;
+}
+}
+
namespace Jobs {
namespace WidgetInstall {
TaskSmack::TaskSmack(InstallerContext& context) :
DPL::TaskDecl<TaskSmack>(this),
m_context(context)
{
- AddStep(&TaskSmack::Step);
+ AddStep(&TaskSmack::SmackFolderLabelingStep);
+ AddStep(&TaskSmack::SmackPrivilegeStep);
+ AddStep(&TaskSmack::SetEndofInstallation);
+
+ AddAbortStep(&TaskSmack::StepAbortSmack);
}
-void TaskSmack::Step()
+void TaskSmack::SmackFolderLabelingStep()
{
- LogInfo("----------------> SMACK: Jobs::WidgetInstall::TaskSmack::Step()");
+ LogInfo("----------------> SMACK:\
+ Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
#ifdef WRT_SMACK_ENABLED
- std::stringstream devcaps;
- FOREACH(it, m_context.staticPermittedDevCaps) {
- if (it->second) {
- std::string utf8 = DPL::ToUTF8String(it->first);
- if (it != m_context.staticPermittedDevCaps.begin())
- devcaps << ",";
- devcaps << utf8;
+ std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+ char* pkgId = NULL;
+ pkgId = (char*)calloc(1, pkg.length() + 1);
+ snprintf(pkgId, pkg.length() + 1, "%s", pkg.c_str());
+
+ if (m_context.widgetConfig.packagingType !=
+ WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
+ {
+ if (PC_OPERATION_SUCCESS != app_install(pkgId)) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "failure in creating smack rules file.");
}
}
- TizenAppId tzAppid = m_context.widgetConfig.tzAppid;
- int result = handle_access_control_conf_forWAC(
- DPL::ToUTF8String(tzAppid).c_str(),
- devcaps.str().c_str(),
- OPERATION_INSTALL);
- Assert(result==PC_OPERATION_SUCCESS && "access control setup failed");
+
+ /* /opt/usr/apps/[pkgid] directory's label is "_" */
+ if (PC_OPERATION_SUCCESS != app_label_dir("_",
+ m_context.locations->getPackageInstallationDir().c_str())) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+
+ /* res directory */
+ std::string resDir = m_context.locations->getPackageInstallationDir() +
+ "/res";
+ if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
+ resDir.c_str())) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+
+ /* for prealod */
+ if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)
+ {
+ if (PC_OPERATION_SUCCESS != app_label_dir("_",
+ m_context.locations->getUserDataRootDir().c_str())) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+ }
+
+ /* data directory */
+ if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
+ m_context.locations->getPrivateStorageDir().c_str())) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+
+ /* bin directory */
+ if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
+ m_context.locations->getBinaryDir().c_str())) {
+ free(pkgId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+
+ if(!setLabelForSharedDir(pkgId)) {
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+
+ free(pkgId);
+
+ /* TODO : set label at wrt-client
+
+ std::string app = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+ char* appId = NULL;
+ appId = (char*)calloc(1, app.length() + 1);
+ snprintf(appId, app.length() + 1, "%s", app.c_str());
+
+ if (0 != smack_lsetlabel(m_context.locations->getExecFile().c_str(),
+ appId, SMACK_LABEL_ACCESS)) {
+ free(pkgId);
+ free(appId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add ACESS Label for binary failure");
+ }
+
+ if (0 != smack_lsetlabel(m_context.locations->getExecFile().c_str(),
+ appId, SMACK_LABEL_EXEC)) {
+ free(pkgId);
+ free(appId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add EXEC Label for binary failure");
+ }
+
+ if (PC_OPERATION_SUCCESS != app_add_friend(pkgId, appId)) {
+ free(pkgId);
+ free(appId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add friend failure");
+ }
+
+ if (PC_OPERATION_SUCCESS != app_label_shared_dir(appId, pkgId,
+ m_context.locations->getBinaryDir().c_str())) {
+ free(pkgId);
+ free(appId);
+ ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+ "Add Label failure");
+ }
+ */
+#endif
+}
+
+void TaskSmack::SmackPrivilegeStep()
+{
+ LogInfo("----------------> SMACK:\
+ Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
+#ifdef WRT_SMACK_ENABLED
+ /* TODO :
+ std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+ */
+ std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+ char* appId = NULL;
+ appId = (char*)calloc(1, id.length() + 1);
+ snprintf(appId, id.length() + 1, "%s", id.c_str());
+
+ WrtDB::ConfigParserData::PrivilegeList privileges =
+ m_context.widgetConfig.configInfo.privilegeList;
+
+ const char** perm_list = new const char*[privileges.size() + 1];
+ int index = 0;
+ FOREACH(it, privileges) {
+ LogInfo("Permission : " << it->name);
+ int length = DPL::ToUTF8String(it->name).length();
+ char *priv = (char*) calloc(1, (sizeof(char) * length) + 1);
+ snprintf(priv, length + 1, "%s",
+ DPL::ToUTF8String(it->name).c_str());
+ perm_list[index++] = priv;
+ }
+ perm_list[index] = NULL;
+
+ if (PC_OPERATION_SUCCESS != app_enable_permissions(appId, APP_TYPE_WGT,
+ perm_list, true)) {
+ LogError("failure in contructing smack rules based on perm_list");
+ }
+
+ free(appId);
+
m_context.job->UpdateProgress(
- UninstallerContext::INSTALL_SMACK_ENABLE,
+ InstallerContext::INSTALL_SMACK_ENABLE,
"Widget SMACK Enabled");
#endif
}
+void TaskSmack::StepAbortSmack()
+{
+ LogInfo("----------------> SMACK:\
+ Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
+#ifdef WRT_SMACK_ENABLED
+ /* TODO :
+ std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+ std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+ char* appId = NULL;
+ appId = (char*)calloc(1, id.length() + 1);
+ snprintf(appId, id.length() + 1, "%s", id.c_str());
+ */
+
+ std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+ char* pkgId = NULL;
+ pkgId = (char*)calloc(1, pkg.length() + 1);
+ snprintf(pkgId, pkg.length() + 1, "%s", pkg.c_str());
+
+ if (PC_OPERATION_SUCCESS != app_revoke_permissions(pkgId)) {
+ LogError("failure in revoking smack permissions");
+ }
+
+ if (PC_OPERATION_SUCCESS != app_uninstall(pkgId)) {
+ LogError("failure in removing smack rules file");
+ }
+ free(pkgId);
+#endif
+}
+
+void TaskSmack::SetEndofInstallation()
+{
+ m_context.job->UpdateProgress(
+ InstallerContext::INSTALL_END,
+ "End installation");
+}
+
+bool TaskSmack::setLabelForSharedDir(const char* pkgId)
+{
+ /* shared directory */
+ if (PC_OPERATION_SUCCESS != app_label_dir("*",
+ m_context.locations->getSharedRootDir().c_str())) {
+ return false;
+ }
+
+ /* shared/res directory */
+ if (PC_OPERATION_SUCCESS != app_label_dir("_",
+ m_context.locations->getSharedResourceDir().c_str())) {
+ return false;
+ }
+
+ /* shared/trusted directory */
+ CertificatePtr rootCert = m_context.wacSecurity.getAuthorCertificatePtr();
+ if (rootCert.Get() != NULL) {
+ ValidationCore::Crypto::Hash::SHA1 sha1;
+ sha1.Append(rootCert->getDER());
+ sha1.Finish();
+ std::string sha1String = sha1.ToBase64String();
+ size_t iPos = sha1String.find("/");
+ while(iPos < std::string::npos) {
+ sha1String.replace(iPos, 1, "#");
+ iPos = sha1String.find("/");
+ }
+
+ LogDebug("sha1 label string : " << sha1String);
+
+ if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
+ sha1String.c_str(),
+ m_context.locations->getSharedTrustedDir().c_str())) {
+ return false;
+ }
+ }
+
+ /* shared/data directory */
+ std::string dataLabel = std::string(pkgId) + "_shareddata";
+ TizenPkgIdList pkgList = WidgetDAOReadOnly::getTizenPkgidList();
+ const char** pList = new (std::nothrow) const char*[pkgList.size() + 1];
+
+ int index = 0;
+ FOREACH(app, pkgList) {
+ std::string id = DPL::ToUTF8String(*app);
+ char *pId = new char[id.size() + 1];
+ snprintf(pId, id.length() + 1, "%s", id.c_str());
+ pList[index++] = pId;
+ }
+
+ pList[index] = NULL;
+ if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
+ dataLabel.c_str(),
+ m_context.locations->getSharedDataDir().c_str())) {
+ freeList(pList);
+ return false;
+ }
+ if (PC_OPERATION_SUCCESS != add_shared_dir_readers(dataLabel.c_str(), pList)) {
+ freeList(pList);
+ return false;
+ }
+ if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
+ "*",
+ m_context.locations->getSharedDataDir().c_str())) {
+ freeList(pList);
+ return false;
+ }
+ freeList(pList);
+ return true;
+}
} //namespace WidgetInstall
} //namespace Jobs