Apply GUI resource and layout to progressbar
[platform/core/security/ode.git] / server / external-encryption.cpp
1 /*
2  *  Copyright (c) 2015 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 #include <signal.h>
17 #include <unistd.h>
18 #include <sys/mount.h>
19
20 #include <vconf.h>
21 #include <tzplatform_config.h>
22
23 #include <klay/file-user.h>
24 #include <klay/filesystem.h>
25 #include <klay/audit/logger.h>
26
27 #include "launchpad.h"
28 #include "app-bundle.h"
29 #include "engine/ecryptfs-engine.h"
30 #include "key-manager/key-manager.h"
31 #include <klay/dbus/variant.h>
32 #include <klay/dbus/connection.h>
33
34 #include "rmi/external-encryption.h"
35 #include "progress-bar.h"
36 #include "progress-vconf-backend.h"
37
38 #define EXTERNAL_STORAGE_PATH   "/opt/media/SDCardA1"
39 #define DEFAULT_USER "owner"
40 #define EXTERNAL_STORAGE_VCONF_KEY VCONFKEY_SDE_CRYPTO_STATE
41
42 namespace ode {
43
44 namespace {
45
46 VConfBackend vconfBackend(VCONFKEY_SDE_ENCRYPT_PROGRESS);
47 ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
48
49 EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH, progressBar);
50
51 void killDependedApplications()
52 {
53         for (pid_t pid : runtime::FileUser::getList(EXTERNAL_STORAGE_PATH, true)) {
54                 INFO("Close process - " + std::to_string(pid));
55                 ::kill(pid, SIGKILL);
56         }
57 }
58
59 void showProgressUI(const std::string type)
60 {
61         AppBundle bundle;
62         bundle.add("mode", "progress");
63         bundle.add("type", type);
64         bundle.add("target", "External");
65
66         Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
67         launchpad.launch("org.tizen.ode-gui", bundle);
68 }
69
70 void externalCallback(dbus::Variant parameters)
71 {
72         INFO("SD Card State Changed");
73         int intparams[6];
74         char* strparams[7];
75
76         parameters.get("(issssssisibii)",
77                      &intparams[0], // block type: 0 - scsi, 1 : mmc
78                      &strparams[0], // devnode
79                      &strparams[1], // syspath
80                      &strparams[2], // usage
81                      &strparams[3], // fs type
82                      &strparams[4], // fs version
83                      &strparams[5], // fs uuid enc
84                      &intparams[1], // readonly: 0 - rw, 1 - ro
85                      &strparams[6], // mount point
86                      &intparams[2], // state: 0 - unmount, 1 - mount
87                      &intparams[3], // primary: 0 - flase, 1 - true
88                      &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
89                      &intparams[5]); // strage id
90         if(intparams[2] == 0) {
91                 INFO("Unmounted!!!");
92         }
93         else {
94                 INFO("Mounted!!!");
95                 // TODO
96                 // Password Popup
97 //              std::string pw = "tizen";
98 //              KeyManager::data pwData(pw.begin(), pw.end());
99 //              engine.mount(keyManager.getDEK(pwData));
100         }
101 }
102
103 void externalAddEventReceiver()
104 {
105         dbus::Connection &systemDBus = dbus::Connection::getSystem();
106
107         systemDBus.subscribeSignal("",
108                                                             "org.tizen.system.storage.BlockManager",
109                                                             "DeviceChanged",
110                                                             "/Org/Tizen/System/Storage/Block/Manager",
111                                                             externalCallback);
112 }
113
114 void externalCheckMount()
115 {
116         INFO("EcryptfsEncrypt");
117         if (!engine.isMountpointMounted(EXTERNAL_STORAGE_PATH)) {
118                 INFO("SD Card not inserted!");
119         }
120         else {
121                 INFO("SD Card inserted!");
122                 if (engine.checkEncryptMetaData(ORIG_META_FILE_PATH) == 0) {
123                         INFO("SD Card encrypted!");
124                         if (engine.isEcryptfsMountpointMounted(EXTERNAL_STORAGE_PATH) == 0) {
125                                 INFO("Already Ecryptfs Mounted");
126                         }
127                         else {
128 //                              std::string pw = "tizen";
129 //                              KeyManager::data pwData(pw.begin(), pw.end());
130 //                              engine.mount(keyManager.getDEK(pwData));
131                         }
132                 }
133                 else {
134                         INFO("SD Card not encrypted!");
135                 }
136         }
137 }
138
139 }
140
141 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
142         context(ctx)
143 {
144         context.registerParametricMethod(this, "", (int)(ExternalEncryption::mount)(std::string));
145         context.registerNonparametricMethod(this, "", (int)(ExternalEncryption::umount));
146         context.registerParametricMethod(this, "", (int)(ExternalEncryption::encrypt)(std::string));
147         context.registerParametricMethod(this, "", (int)(ExternalEncryption::decrypt)(std::string));
148         context.registerParametricMethod(this, "", (int)(ExternalEncryption::changePassword)(std::string, std::string));
149         context.registerNonparametricMethod(this, "", (int)(ExternalEncryption::getState));
150
151         externalAddEventReceiver();
152         externalCheckMount();
153 }
154
155
156 ExternalEncryption::~ExternalEncryption()
157 {
158 }
159
160 int ExternalEncryption::mount(const std::string &password)
161 {
162         KeyManager::data pwData(password.begin(), password.end());
163         KeyManager keyManager(engine.getKeyMeta());
164
165         if (!keyManager.verifyPassword(pwData)) {
166                 return -2;
167         }
168
169         engine.mount(keyManager.getMasterKey(pwData));
170         return 0;
171 }
172
173 int ExternalEncryption::umount()
174 {
175         INFO("Close all applications using external storage...");
176         killDependedApplications();
177         INFO("Umount internal storage...");
178         engine.umount();
179
180         return 0;
181 }
182
183 int ExternalEncryption::encrypt(const std::string &password)
184 {
185         KeyManager::data pwData(password.begin(), password.end());
186         KeyManager keyManager;
187
188         keyManager.initPassword(pwData);
189         engine.setKeyMeta(keyManager.serialize());
190
191         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
192         auto encryptWorker = [MasterKey, this]() {
193                 showProgressUI("Encrypting");
194
195                 INFO("Close all applications using external storage...");
196                 killDependedApplications();
197                 INFO("Encryption started...");
198                 engine.encrypt(MasterKey);
199                 INFO("Sync disk...");
200                 sync();
201                 INFO("Encryption completed");
202         };
203
204         std::thread asyncWork(encryptWorker);
205         asyncWork.detach();
206
207         return 0;
208 }
209
210 int ExternalEncryption::decrypt(const std::string &password)
211 {
212         KeyManager::data pwData(password.begin(), password.end());
213         KeyManager keyManager(engine.getKeyMeta());
214
215         if (!keyManager.verifyPassword(pwData)) {
216                 return -2;
217         }
218
219         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
220         auto decryptWorker = [MasterKey, this]() {
221                 showProgressUI("Decrypting");
222
223                 INFO("Close all applications using external storage...");
224                 killDependedApplications();
225                 INFO("Umount internal storage...");
226                 try {
227                         engine.umount();
228                 } catch (runtime::Exception &e) {}
229
230                 INFO("Decryption started...");
231                 engine.decrypt(MasterKey);
232                 INFO("Sync disk...");
233                 sync();
234                 INFO("Decryption completed");
235         };
236
237         std::thread asyncWork(decryptWorker);
238         asyncWork.detach();
239
240         return 0;
241 }
242
243 int ExternalEncryption::changePassword(const std::string &oldPassword,
244                                                                            const std::string &newPassword)
245 {
246         KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
247         KeyManager::data newPwData(newPassword.begin(), newPassword.end());
248         KeyManager keyManager(engine.getKeyMeta());
249
250         if (!keyManager.verifyPassword(oldPwData)) {
251                 return -2;
252         }
253
254         keyManager.changePassword(oldPwData, newPwData);
255         engine.setKeyMeta(keyManager.serialize());
256
257         return 0;
258 }
259
260 int ExternalEncryption::getState()
261 {
262         char *value = ::vconf_get_str(EXTERNAL_STORAGE_VCONF_KEY);
263         if (value == NULL) {
264                 throw runtime::Exception("Failed to get vconf value");
265         }
266
267         std::string valueStr(value);
268         free(value);
269
270         if (valueStr == "encrypted") {
271                 return State::Encrypted;
272         } else if (valueStr == "unencrypted") {
273                 return State::Unencrypted;
274         } else {
275                 return State::Corrupted;
276         }
277
278         return 0;
279 }
280
281 } // namespace ode