* @file widget_unzip.cpp
* @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
* @version 1.0
- * @brief Implementation file for installer task unzip
+ * @brief Implementation file for installer widget unzip
*/
#include <widget_install/widget_unzip.h>
#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
#include <widget_install/job_widget_install.h>
-#include <dpl/log/log.h>
#include <dpl/copy.h>
#include <dpl/file_output.h>
+#include "dpl/utils/path.h"
#include <dpl/abstract_waitable_input_adapter.h>
#include <dpl/wrt-dao-ro/global_config.h>
-#include <task_commons.h>
#include <sys/stat.h>
-#include <drm_trusted_client.h>
+#include <dlfcn.h>
+#include <installer_log.h>
using namespace WrtDB;
namespace {
+const char *const DRM_LIB_PATH = "/usr/lib/libdrm-service-core-tizen.so";
+
struct PathAndFilePair
{
std::string path;
std::string file;
PathAndFilePair(const std::string &p,
- const std::string &f) :
+ const std::string &f) :
path(p),
file(f)
- {
- }
+ {}
};
PathAndFilePair SplitFileAndPath(const std::string &filePath)
namespace Jobs {
namespace WidgetInstall {
-WidgetUnzip::WidgetUnzip(std::string source, std::string path) :
- m_source(source),
- m_destPath(path)
-{
- LogDebug("WidgetUnzip");
-}
-
void WidgetUnzip::ExtractFile(DPL::ZipInput::File *input,
- const std::string &destFileName)
+ const std::string &destFileName)
{
Try
{
}
}
-void WidgetUnzip::UnzipWidget()
+void WidgetUnzip::unzipProgress(const std::string &destination)
{
- UnzipPrepare();
- UnzipProgress();
-}
-
-void WidgetUnzip::UnzipPrepare()
-{
- LogInfo("Prepare to unzip...");
-
- Try
- {
- m_zip.reset(new DPL::ZipInput(m_source));
- LogInfo("Widget package comment: " << m_zip->GetGlobalComment());
-
- // Widget package must not be empty
- if (m_zip->empty()) {
- ThrowMsg(Exceptions::ZipEmpty, m_source);
- }
-
- // Set iterator to first file
- m_zipIterator = m_zip->begin();
- }
- Catch(DPL::ZipInput::Exception::OpenFailed)
- {
- ReThrowMsg(Exceptions::OpenZipFailed, m_source);
- }
-}
-
-void WidgetUnzip::UnzipProgress()
-{
-
// Show file info
- LogInfo("Unzipping: '" << m_zipIterator->name <<
- "', Comment: '" << m_zipIterator->comment <<
- "', Compressed size: " << m_zipIterator->compressedSize <<
- ", Uncompressed size: " << m_zipIterator->uncompressedSize);
-
+ _D("Unzipping: '%s', Comment: '%s', Compressed size: %lld, Uncompressed size: %lld",
+ m_zipIterator->name.c_str(), m_zipIterator->comment.c_str(), m_zipIterator->compressedSize, m_zipIterator->uncompressedSize);
// Normalize file paths
// FIXME: Implement checking for invalid characters
if (fileName[fileName.size() - 1] == '/') {
// This is path
- std::string newPath = m_destPath + "/" +
+ std::string newPath = destination + "/" +
fileName.substr(0, fileName.size() - 1);
- LogPedantic("Path to extract: " << newPath);
+ _D("Path to extract: %s", newPath.c_str());
// Create path in case of it is empty
- createTempPath(newPath);
+ Try
+ {
+ DPL::Utils::MakeDir(DPL::Utils::Path(newPath));
+ }
+ Catch(DPL::Utils::Path::BaseException)
+ {
+ ThrowMsg(Exceptions::FileOperationFailed, "Failed to create temporary directory");
+ }
} else {
// This is regular file
- std::string fileExtractPath = m_destPath + "/" + fileName;
+ std::string fileExtractPath = destination + "/" + fileName;
- LogPedantic("File to extract: " << fileExtractPath);
+ _D("File to extract: %s", fileExtractPath.c_str());
// Split into pat & file pair
PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath);
- LogPedantic("Path and file: " <<
- pathAndFile.path <<
- " : " << pathAndFile.file);
+ _D("Path and file: %s : %s", pathAndFile.path.c_str(), pathAndFile.file.c_str());
// First, ensure that path exists
- createTempPath(pathAndFile.path);
+ Try
+ {
+ DPL::Utils::MakeDir(DPL::Utils::Path(pathAndFile.path));
+ }
+ Catch(DPL::Utils::Path::BaseException)
+ {
+ ThrowMsg(Exceptions::FileOperationFailed, "Failed to create temporary directory");
+ }
Try
{
// Check whether there are more files to extract
if (++m_zipIterator == m_zip->end()) {
- LogInfo("Unzip progress finished successfuly");
- m_zip.reset();
+ _D("Unzip progress finished successfuly");
} else {
- UnzipProgress();
+ unzipProgress(destination);
+ }
+}
+
+bool WidgetUnzip::isDRMPackage(const std::string &source)
+{
+ _D("Enter : isDRMPackage()");
+ int ret = 0;
+ void* pHandle = NULL;
+ char* pErrorMsg = NULL;
+ int (*drm_oem_sapps_is_drm_file)(const char* pDcfPath, int dcfPathLen);
+
+ pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+ if (!pHandle) {
+ _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+ return false;
+ }
+
+ // clear existing error
+ dlerror();
+
+ drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>
+ (dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
+
+ if ((pErrorMsg = dlerror()) != NULL) {
+ _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+ dlclose(pHandle);
+ return false;
+ }
+
+ if (drm_oem_sapps_is_drm_file == NULL) {
+ _E("drm_oem_sapps_is_drm_file is NULL : %s", source.c_str());
+ dlclose(pHandle);
+ return false;
+ }
+
+ ret = drm_oem_sapps_is_drm_file(source.c_str(), source.length());
+ dlclose(pHandle);
+ if (1 == ret) {
+ _D("%s is DRM file", source.c_str());
+ return true;
}
+ _D("%s isn't DRM file", source.c_str());
+ return false;
}
-void WidgetUnzip::UnzipDRMWidget()
+bool WidgetUnzip::decryptDRMPackage(const std::string &source, const std::string
+ &decryptedSource)
{
- LogDebug("Decrypt drm widget");
- drm_trusted_sapps_decrypt_package_info_s package_info;
+ _D("Enter : decryptDRMPackage()");
+ int ret = 0;
+ void* pHandle = NULL;
+ char* pErrorMsg = NULL;
+ int (*drm_oem_sapps_decrypt_package)(const char* pDcfPath, int dcfPathLen,
+ const char* pDecryptedFile, int decryptedFileLen);
+
+ pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+ if (!pHandle) {
+ _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+ return false;
+ }
+
+ // clear existing error
+ dlerror();
+
+ drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int,
+ const char*, int)>
+ (dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
- strncpy(package_info.sadcf_filepath, m_source.c_str(),
- sizeof(package_info.sadcf_filepath));
- strncpy(package_info.decrypt_filepath, m_destPath.c_str(),
- sizeof(package_info.decrypt_filepath));
+ if ((pErrorMsg = dlerror()) != NULL) {
+ _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+ dlclose(pHandle);
+ return false;
+ }
- drm_trusted_request_type_e requestType =
- DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
+ if (drm_oem_sapps_decrypt_package == NULL) {
+ _E("drm_oem_sapps_decrypt_package is NULL : %s", source.c_str());
+ dlclose(pHandle);
+ return false;
+ }
- int ret = drm_trusted_handle_request(requestType,
- (void *)&package_info, NULL);
- if (DRM_TRUSTED_RETURN_SUCCESS != ret) {
- LogDebug("Failed unzip drm widget");
- ThrowMsg(Exceptions::ExtractFileFailed, m_destPath);
+ ret = drm_oem_sapps_decrypt_package(source.c_str(), source.length(),
+ decryptedSource.c_str(), decryptedSource.length());
+ dlclose(pHandle);
+ if (1 == ret) {
+ _D("%s is decrypted : %s", source.c_str(), decryptedSource.c_str());
+ return true;
}
+ return false;
}
+
+std::string WidgetUnzip::getDecryptedPackage(const std::string &source)
+{
+ _D("Check DRM...");
+ if (isDRMPackage(source)) {
+ std::string decryptedFile;
+ size_t found = source.find_last_of(".wgt");
+ if (found == std::string::npos) {
+ decryptedFile += source + "_tmp.wgt";
+ } else {
+ decryptedFile += source.substr(0, source.find_last_not_of(".wgt") +
+ 1) + "_tmp.wgt";
+ }
+
+ _D("decrypted file name : %s", decryptedFile.c_str());
+ if (!decryptDRMPackage(source, decryptedFile)) {
+ _E("Failed decrypt drm file");
+ ThrowMsg(Exceptions::DrmDecryptFailed, source);
+ }
+ return decryptedFile;
+ }
+ return source;
+}
+
+void WidgetUnzip::unzipWgtFile(const std::string &source, const std::string &destination)
+{
+ _D("Prepare to unzip...");
+ std::string wgtFile;
+ Try
+ {
+ wgtFile = getDecryptedPackage(source);
+ _D("wgtFile : %s", wgtFile.c_str());
+
+ m_zip.reset(new DPL::ZipInput(wgtFile));
+ _D("Widget package comment: %s", m_zip->GetGlobalComment().c_str());
+
+
+ // Widget package must not be empty
+ if (m_zip->empty()) {
+ ThrowMsg(Exceptions::ZipEmpty, wgtFile);
+ }
+
+ // Set iterator to first file
+ m_zipIterator = m_zip->begin();
+
+ unzipProgress(destination);
+
+ // Unzip finished, close internal structures
+ m_zip.reset();
+
+ // Done
+ _D("Unzip finished");
+ }
+ Catch(DPL::ZipInput::Exception::OpenFailed)
+ {
+ ReThrowMsg(Exceptions::OpenZipFailed, wgtFile);
+ }
+ Catch(DPL::ZipInput::Exception::SeekFileFailed)
+ {
+ ThrowMsg(Exceptions::ExtractFileFailed, wgtFile);
+ }
+ Catch(Exceptions::DrmDecryptFailed)
+ {
+ ReThrowMsg(Exceptions::ExtractFileFailed, wgtFile);
+ }
+}
+
} //namespace WidgetInstall
} //namespace Jobs