Update wrt-installer_0.0.53
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_encrypt_resource.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    task_ecnrypt_resource.cpp
18  * @author  Soyoung Kim (sy037.kim@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task encrypt resource
21  */
22 #include "task_encrypt_resource.h"
23
24 #include <unistd.h>
25 #include <string>
26 #include <sys/stat.h>
27 #include <dirent.h>
28
29 #include <dpl/log/log.h>
30 #include <dpl/errno_string.h>
31 #include <dpl/foreach.h>
32 #include <dpl/wrt-dao-ro/global_config.h>
33
34 #include <widget_install/job_widget_install.h>
35 #include <widget_install/widget_install_context.h>
36 #include <widget_install/widget_install_errors.h>
37
38 using namespace WrtDB;
39 using namespace WRTEncryptor;
40
41 namespace {
42 std::set<std::string>& getSupportedForEncryption()
43 {
44     static std::set<std::string> encryptSet;
45     if (encryptSet.empty()) {
46         encryptSet.insert(".html");
47         encryptSet.insert(".css");
48         encryptSet.insert(".js");
49     }
50     return encryptSet;
51 }
52
53 bool isSupportedForEncryption(std::string file)
54 {
55     size_t foundKey = file.rfind(".");
56     if (std::string::npos != foundKey) {
57         std::string mimeType = file.substr(foundKey);
58         return getSupportedForEncryption().count(mimeType) > 0;
59     }
60     return false;
61 }
62 }
63
64 namespace Jobs {
65 namespace WidgetInstall {
66 TaskEncryptResource::TaskEncryptResource(InstallerContext& context) :
67     DPL::TaskDecl<TaskEncryptResource>(this),
68     m_context(context)
69 {
70     AddStep(&TaskEncryptResource::StepEncryptResource);
71 }
72
73 void TaskEncryptResource::StepEncryptResource()
74 {
75     LogDebug("Step Encrypt resource");
76     m_resEnc = new ResourceEncryptor;
77     m_resEnc->CreateEncryptionKey(DPL::ToUTF8String(*m_context.
78                 widgetConfig.pkgname));
79
80     if (m_context.widgetConfig.pType == PKG_TYPE_TIZEN_WITHSVCAPP) {
81         tempInstalledPath = m_context.tempWidgetPath;
82     } else {
83         tempInstalledPath = m_context.tempWidgetRoot;
84     }
85
86     EncryptDirectory(tempInstalledPath);
87 }
88
89 void TaskEncryptResource::EncryptDirectory(std::string path)
90 {
91     DIR* pkgDir = opendir(path.c_str());
92     if (!pkgDir) {
93         LogDebug("Package directory doesn't exist");
94         ThrowMsg(Exceptions::InternalError, "Error occurs during read \
95                 directory");
96     }
97
98     struct dirent* dirent;
99     struct stat statInfo;
100     do {
101         if ((dirent = readdir(pkgDir))) {
102             std::string dirName = dirent->d_name;
103             std::string absFileName = path + "/" + dirName;
104             if (stat(absFileName.c_str(), &statInfo) != 0) {
105                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
106             }
107
108             if (S_ISDIR(statInfo.st_mode)) {
109                 if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name,
110                             "..") == 0) {
111                     continue;
112                 }
113                 EncryptDirectory(absFileName);
114             } else {
115                 if (isSupportedForEncryption(absFileName)) {
116                     EncryptFile(absFileName);
117                 }
118             }
119         }
120     }
121     while(dirent);
122     if (closedir(pkgDir)) {
123         LogError("Fail to close directory : " << path);
124     }
125 }
126
127 void TaskEncryptResource::EncryptFile(const std::string &fileName)
128 {
129     Try
130     {
131         LogDebug("Need to ecnrypt file Name " << fileName);
132         std::string encFile = fileName + ".enc";
133
134         struct stat buf;
135         int ret = stat(fileName.c_str(), &buf);
136         if(ret == 0) {
137             size_t fileSize = buf.st_size;
138
139             FILE* resFp = fopen(fileName.c_str(), "r");
140             if ( NULL == resFp) {
141                 LogDebug("Couldnot open file : " << fileName);
142                 return;
143             }
144
145             int blockSize = m_resEnc->GetBlockSize(fileSize);
146             LogDebug("Get block size : " << blockSize);
147
148             unsigned char readBuf[fileSize];
149             unsigned char outEncBuf[blockSize];
150             memset(readBuf, 0, fileSize);
151             memset(outEncBuf, 0, blockSize);
152
153             fread(readBuf, sizeof(unsigned char), fileSize, resFp);
154
155             m_resEnc->EncryptChunk(readBuf, outEncBuf, fileSize);
156
157             FILE* encFp = fopen(encFile.c_str(), "w");
158             if (NULL == encFp) {
159                 LogError("Failed to open ecryption file");
160                 return;
161             }
162             fwrite(outEncBuf, sizeof(unsigned char), blockSize, encFp);
163
164             fclose(resFp);
165             fclose(encFp);
166
167             LogDebug("Success to encrypt file");
168             LogDebug("Remove unecrypted file : " << fileName);
169
170             unlink(fileName.c_str());
171             if ((rename(encFile.c_str(), fileName.c_str())) != 0) {
172                 ThrowMsg(Exceptions::ExtractFileFailed, fileName);
173             }
174
175             std::string realPath = fileName;
176             realPath.replace(0, tempInstalledPath.length(),
177                     m_context.installPath);
178
179             WrtDB::EncryptedFileInfo info;
180             info.fileName = DPL::FromUTF8String(realPath);
181             info.fileSize = fileSize;
182
183             m_context.widgetConfig.encryptedFiles.insert(info);
184         }
185     }
186     Catch(ResourceEncryptor::Exception::Base)
187     {
188         ReThrowMsg(Exceptions::ExtractFileFailed, fileName);
189     }
190 }
191 } //namespace WidgetInstall
192 } //namespace Jobs