[Release] wrt-installer_0.1.58
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_smack.cpp
index 7c36c65..9769276 100644 (file)
 #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.");
         }
     }
-    DPL::OptionalString pkgName = m_context.widgetConfig.Pkgname;
-    Assert(!pkgName.IsNull() && "widget doesn't have a pkg name");
-    int result = handle_access_control_conf_forWAC(
-                     DPL::ToUTF8String(*pkgName).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