[Release] wrt-installer_0.1.114
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_smack.cpp
index 9857bf7..f338fc3 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/foreach.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;
-#ifdef WRT_SMACK_ENABLED
-const char* SMACK_RULE_STR = "/usr/bin/smackload-app.sh";
-#endif
+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)
+    m_context(context),
+    m_pkgId(NULL)
 {
-    AddStep(&TaskSmack::SmackFolderLabelingStep);
-    AddStep(&TaskSmack::SmackPrivilegeStep);
-    AddStep(&TaskSmack::SmackTemporaryStep);
-    AddStep(&TaskSmack::SetEndofInstallation);
+    AddStep(&TaskSmack::StartStep);
+    AddStep(&TaskSmack::StepSetInstall);
+    AddStep(&TaskSmack::StepSmackFolderLabeling);
+    AddStep(&TaskSmack::StepSmackPrivilege);
+    AddStep(&TaskSmack::EndStep);
+
+    AddAbortStep(&TaskSmack::StepAbortSmack);
 }
 
-void TaskSmack::SmackFolderLabelingStep()
+void TaskSmack::StepSetInstall()
 {
-    LogInfo(
-        "----------------> SMACK: \
-            Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
+    LogDebug("----------------> SMACK: StepStartSetSmack()");
+#ifdef WRT_SMACK_ENABLED
+    std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+    m_pkgId = (char*)calloc(1, pkg.length() + 1);
+    snprintf(m_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(m_pkgId)) {
+            free(m_pkgId);
+            ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+                    "failure in creating smack rules file.");
+        }
+    }
+#endif
+}
+
+void TaskSmack::StepSmackFolderLabeling()
+{
+    LogDebug("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
 #ifdef WRT_SMACK_ENABLED
     /* /opt/usr/apps/[pkgid] directory's label is "_" */
-    std::string tzPkgid = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
-    if (PC_OPERATION_SUCCESS != app_label_dir("_",
-                                              m_context.locations->
-                                                  getPackageInstallationDir().
-                                                  c_str()))
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getPackageInstallationDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        LogWarning("Add label to " <<
+                m_context.locations->getPackageInstallationDir());
+    }
+
+    /* for prealod */
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD &&
+            m_context.mode.extension != InstallMode::ExtensionType::DIR)
     {
-        LogError("Set smack failure. Failed to add label for app root directory");
-        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                                         "Add Label failure");
+        if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                    m_context.locations->getUserDataRootDir().c_str(),
+                    APP_PATH_ANY_LABEL, "_")) {
+        }
     }
 
     /* res directory */
     std::string resDir = m_context.locations->getPackageInstallationDir() +
         "/res";
-    if (PC_OPERATION_SUCCESS != app_label_dir(tzPkgid.c_str(),
-                                              resDir.c_str()))
+
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId, resDir.c_str(),
+                APP_PATH_PRIVATE)) {
+        LogWarning("Add label to " << resDir);
+    }
+
+    /* data directory */
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getPrivateStorageDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        LogWarning("Add label to " << m_context.locations->getPrivateStorageDir());
+    }
+
+    /* tmp directory */
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getPrivateTempStorageDir().c_str(),
+                APP_PATH_PRIVATE))
     {
-        LogError("Set smack failure. Failed to add label for resource directory");
-        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                                         "Add Label failure");
+        LogWarning("Add label to " << m_context.locations->getPrivateTempStorageDir());
     }
 
     /* bin directory */
-    if (PC_OPERATION_SUCCESS != app_label_dir(tzPkgid.c_str(),
-                                              m_context.locations->getBinaryDir()
-                                                  .c_str()))
-    {
-        LogError("Set smack failure. Failed to add label for binary directory");
-        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                                         "Add Label failure");
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getBinaryDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        LogWarning("Add label to " << m_context.locations->getBinaryDir());
     }
 
-    /* data directory */
-    if (PC_OPERATION_SUCCESS != app_label_dir(tzPkgid.c_str(),
-                                              m_context.locations->
-                                                  getPrivateStorageDir().c_str()))
-    {
-        LogError("Set smack failure. Failed to add label for private storage directory");
-        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                                         "Add Label failure");
+    if(!setLabelForSharedDir(m_pkgId)) {
+        LogWarning("Add label to shared directory");
     }
 
+    free(m_pkgId);
+
+    /* TODO : set label at wrt-client */
 #endif
 }
 
-void TaskSmack::SmackPrivilegeStep()
+void TaskSmack::StepSmackPrivilege()
 {
-    LogInfo(
-        "----------------> SMACK: \
+    LogDebug("----------------> SMACK:\
             Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
 #ifdef WRT_SMACK_ENABLED
-    WrtDB::TizenPkgId tzPkgid = m_context.widgetConfig.tzPkgid;
-#if 0
-    char** perm_list = new char*[m_context.staticPermittedDevCaps.size()];
+    /* 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;
 
+    char** perm_list = new char*[privileges.size() + 1];
     int index = 0;
-    FOREACH(it, m_context.staticPermittedDevCaps) {
-        if (it->second) {
-            LogInfo("Permission : " << it->first);
-            perm_list[index++] =
-                const_cast<char*>(DPL::ToUTF8String(it->first).c_str());
-        }
+    FOREACH(it, privileges) {
+        LogDebug("Permission : " << it->name);
+        int length = DPL::ToUTF8String(it->name).length();
+        char *priv = new char[length + 1];
+        snprintf(priv, length + 1, "%s",
+                 DPL::ToUTF8String(it->name).c_str());
+        perm_list[index++] = priv;
     }
     perm_list[index] = NULL;
 
-    int result = app_add_permissions(
-            DPL::ToUTF8String(tzPkgid).c_str(),
-            const_cast<const char**>(perm_list));
+    if (PC_OPERATION_SUCCESS != app_enable_permissions(appId, APP_TYPE_WGT,
+                const_cast<const char **>(perm_list), true)) {
+        LogWarning("failure in contructing smack rules based on perm_list");
+    }
 
-#else
-    const char* perm_list[0];
-    perm_list[0] = NULL;
-#endif
-    if (m_context.mode.installTime != InstallMode::InstallTime::PRELOAD) {
-        int result = app_add_permissions(
-                DPL::ToUTF8String(tzPkgid).c_str(), perm_list);
-        if (PC_OPERATION_SUCCESS != result) {
-            LogError("Failed to add permission to privilege");
-            ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                    "SMACK check failure");
-        }
+    free(appId);
+    index = 0;
+    while (NULL != perm_list[index]) {
+        delete [] perm_list[index++];
     }
+    delete [] perm_list;
 
     m_context.job->UpdateProgress(
         InstallerContext::INSTALL_SMACK_ENABLE,
@@ -149,37 +196,90 @@ void TaskSmack::SmackPrivilegeStep()
 #endif
 }
 
-void TaskSmack::SmackTemporaryStep()
+void TaskSmack::StepRevokeForUpdate()
 {
+    LogDebug("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
 #ifdef WRT_SMACK_ENABLED
-    //This step is temporary for smack
-
-    LogInfo("----------------> SMACK: \
-            Jobs::WidgetInstall::TaskSmack::SmackTemporaryStep()");
-    std::ostringstream commStr;
-    std::string tzPkgid = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
-    commStr << SMACK_RULE_STR << " " << BashUtils::escape_arg(tzPkgid);
-    LogDebug("set smack rule command : " << commStr.str());
-
-    char readBuf[MAX_BUF_SIZE];
-    memset(readBuf, 0x00, MAX_BUF_SIZE);
-
-    FILE *fd;
-    fd = popen(commStr.str().c_str(), "r");
-    if (NULL == fd) {
-        LogError("Set smack rule failure. Failed to call script.");
-        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
-                "SMACK check failure");
-    }
-    pclose(fd);
+    if (PC_OPERATION_SUCCESS != app_revoke_permissions(m_pkgId)) {
+        LogWarning("failure in revoking smack permissions");
+    }
 #endif
 }
 
-void TaskSmack::SetEndofInstallation()
+void TaskSmack::StepAbortSmack()
 {
-    m_context.job->UpdateProgress(
-        InstallerContext::INSTALL_END,
-        "End installation");
+    LogDebug("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
+#ifdef WRT_SMACK_ENABLED
+
+    if (PC_OPERATION_SUCCESS != app_revoke_permissions(m_pkgId)) {
+        LogWarning("failure in revoking smack permissions");
+    }
+
+    if (PC_OPERATION_SUCCESS != app_uninstall(m_pkgId)) {
+        LogWarning("failure in removing smack rules file");
+    }
+    free(m_pkgId);
+#endif
+}
+
+bool TaskSmack::setLabelForSharedDir(const char* pkgId)
+{
+    /* /shared directory */
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getSharedRootDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        LogWarning("Add label to " << m_context.locations->getUserDataRootDir());
+    }
+
+    /* /shared/res directory */
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getSharedResourceDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        LogWarning("Add label to " << m_context.locations->getSharedResourceDir());
+    }
+
+    /* /shared/trusted directory */
+    CertificatePtr rootCert = m_context.widgetSecurity.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_setup_path(m_pkgId,
+                    m_context.locations->getSharedTrustedDir().c_str(),
+                    APP_PATH_GROUP_RW, sha1String.c_str())) {
+            LogWarning("Add label to " << m_context.locations->getBinaryDir());
+        }
+    }
+
+    /* /shared/data directory */
+    if (PC_OPERATION_SUCCESS != app_setup_path(m_pkgId,
+                m_context.locations->getSharedDataDir().c_str(),
+                APP_PATH_PUBLIC_RO)) {
+        LogWarning("Add label to " << m_context.locations->getSharedDataDir());
+    }
+
+    return true;
+}
+
+void TaskSmack::StartStep()
+{
+    LogDebug("--------- <TaskSmack> : START ----------");
+}
+
+void TaskSmack::EndStep()
+{
+    LogDebug("--------- <TaskSmack> : END ----------");
 }
 } //namespace WidgetInstall
 } //namespace Jobs