79001d38e8d2a38ccb9a1c43dc805cbe4019177a
[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 <fstream>
17 #include <sstream>
18
19 #include <signal.h>
20 #include <unistd.h>
21 #include <sys/mount.h>
22
23 #include <vconf.h>
24 #include <tzplatform_config.h>
25
26 #include <klay/file-user.h>
27 #include <klay/filesystem.h>
28 #include <klay/audit/logger.h>
29 #include <klay/dbus/variant.h>
30 #include <klay/dbus/connection.h>
31
32 #include "vconf.h"
33 #include "launchpad.h"
34 #include "app-bundle.h"
35 #include "progress-bar.h"
36 #include "engine/ecryptfs-engine.h"
37 #include "key-manager/key-manager.h"
38
39 #include "rmi/external-encryption.h"
40
41 #define EXTERNAL_ENGINE EcryptfsEngine
42 #define EXTERNAL_PATH   "/opt/media/SDCardA1"
43 #define EXTERNAL_STATE_VCONF_KEY VCONFKEY_SDE_CRYPTO_STATE
44 #define EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY VCONFKEY_SDE_ENCRYPT_NEWFILE
45 #define EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY VCONFKEY_SDE_EXCLUDE_MEDIAFILE
46
47 #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
48
49 namespace ode {
50
51 namespace {
52
53 std::unique_ptr<EXTERNAL_ENGINE> engine;
54
55 void killDependedApplications()
56 {
57         for (pid_t pid : runtime::FileUser::getList(EXTERNAL_PATH, true)) {
58                 INFO("Close process - " + std::to_string(pid));
59                 ::kill(pid, SIGKILL);
60         }
61 }
62
63 void externalCallback(dbus::Variant parameters)
64 {
65         int intparams[6];
66         char* strparams[7];
67
68         parameters.get("(issssssisibii)",
69                 &intparams[0], // block type: 0 - scsi, 1 : mmc
70                 &strparams[0], // devnode
71                 &strparams[1], // syspath
72                 &strparams[2], // usage
73                 &strparams[3], // fs type
74                 &strparams[4], // fs version
75                 &strparams[5], // fs uuid enc
76                 &intparams[1], // readonly: 0 - rw, 1 - ro
77                 &strparams[6], // mount point
78                 &intparams[2], // state: 0 - unmount, 1 - mount
79                 &intparams[3], // primary: 0 - flase, 1 - true
80                 &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
81                 &intparams[5]); // strage id
82
83         if(intparams[2] == 0) {
84                 INFO("Unmounted");
85         } else {
86                 INFO("Mounted");
87                 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
88                 if (value != NULL) {
89                         std::string valueStr(value);
90                         free(value);
91                         if (valueStr == "encrypted") {
92                                 try {
93                                         INFO("Launch SD card password popup");
94                                         AppBundle bundle;
95                                         bundle.add("viewtype", "SD_CARD_PASSWORD");
96
97                                         Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
98                                         launchpad.launch("org.tizen.ode", bundle);
99                                 } catch (runtime::Exception &e) {
100                                         ERROR("Failed to launch SD card password popup");
101                                 }
102                         }
103                 }
104         }
105 }
106
107 void externalAddEventReceiver()
108 {
109         dbus::Connection &systemDBus = dbus::Connection::getSystem();
110
111         systemDBus.subscribeSignal("",
112                                                                 "/Org/Tizen/System/Storage/Block/Manager",
113                                                                 "org.tizen.system.storage.BlockManager",
114                                                                 "DeviceChanged",
115                                                                 externalCallback);
116 }
117
118 unsigned int getOptions()
119 {
120         unsigned int result = 0;
121         int value;
122
123         value = 0;
124         ::vconf_get_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, &value);
125         if (value) {
126                 result |= ExternalEncryption::Option::OnlyNewFile;
127         }
128
129         value = 0;
130         ::vconf_get_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, &value);
131         if (value) {
132                 result |= ExternalEncryption::Option::ExceptForMediaFile;
133         }
134
135         return result;
136 }
137
138 void setOptions(unsigned int options)
139 {
140         bool value;
141
142         if (options & ExternalEncryption::Option::OnlyNewFile) {
143                 value = true;
144         } else {
145                 value = false;
146         }
147         ::vconf_set_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, value);
148
149         if (options & ExternalEncryption::Option::ExceptForMediaFile) {
150                 value = true;
151         } else {
152                 value = false;
153         }
154         ::vconf_set_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, value);
155 }
156
157 } // namsepace
158
159 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
160         context(ctx)
161 {
162         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::mount)(std::string));
163         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::umount)());
164         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::encrypt)(std::string, unsigned int));
165         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::decrypt)(std::string));
166         context.expose(this, "", (int)(ExternalEncryption::isPasswordInitialized)());
167         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::initPassword)(std::string));
168         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::cleanPassword)(std::string));
169         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::changePassword)(std::string, std::string));
170         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::verifyPassword)(std::string));
171         context.expose(this, "", (int)(ExternalEncryption::getState)());
172         context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
173
174         engine.reset(new EXTERNAL_ENGINE(
175                 EXTERNAL_PATH, EXTERNAL_PATH,
176                 ProgressBar([](int v) {
177                 ::vconf_set_str(VCONFKEY_SDE_ENCRYPT_PROGRESS,
178                                                 std::to_string(v).c_str());
179                 })
180         ));
181
182         externalAddEventReceiver();
183 }
184
185 ExternalEncryption::~ExternalEncryption()
186 {
187 }
188
189 int ExternalEncryption::mount(const std::string &password)
190 {
191         if (getState() != State::Encrypted) {
192                 return -1;
193         }
194
195         KeyManager::data data(password.begin(), password.end());
196         KeyManager keyManager(engine->getKeyMeta());
197
198         if (!keyManager.verifyPassword(data)) {
199                 return -2;
200         }
201
202         engine->mount(keyManager.getMasterKey(data), getOptions());
203         return 0;
204 }
205
206 int ExternalEncryption::umount()
207 {
208         if (getState() != State::Encrypted) {
209                 return -1;
210         }
211
212         INFO("Close all applications using external storage...");
213         killDependedApplications();
214         INFO("Umount external storage...");
215         engine->umount();
216
217         return 0;
218 }
219
220 int ExternalEncryption::encrypt(const std::string &password, unsigned int options)
221 {
222         if (getState() != State::Unencrypted) {
223                 return -1;
224         }
225
226         KeyManager::data pwData(password.begin(), password.end());
227         KeyManager keyManager(engine->getKeyMeta());
228
229         if (!keyManager.verifyPassword(pwData)) {
230                 return -2;
231         }
232
233         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
234         auto encryptWorker = [MasterKey, options, this]() {
235                 try {
236                         INFO("Close all applications using external storage...");
237                         killDependedApplications();
238                         INFO("Encryption started...");
239                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
240                         engine->encrypt(MasterKey, options);
241                         setOptions(options & getSupportedOptions());
242                         INFO("Sync disk...");
243                         sync();
244                         INFO("Encryption completed");
245                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "encrypted");
246                 } catch (runtime::Exception &e) {
247                         ERROR("Encryption failed - " + std::string(e.what()));
248                 }
249         };
250
251         std::thread asyncWork(encryptWorker);
252         asyncWork.detach();
253
254         return 0;
255 }
256
257 int ExternalEncryption::decrypt(const std::string &password)
258 {
259         if (getState() != State::Encrypted) {
260                 return -1;
261         }
262
263         KeyManager::data pwData(password.begin(), password.end());
264         KeyManager keyManager(engine->getKeyMeta());
265
266         if (!keyManager.verifyPassword(pwData)) {
267                 return -2;
268         }
269
270         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
271         auto decryptWorker = [MasterKey, this]() {
272                 try {
273                         INFO("Close all applications using external storage...");
274                         killDependedApplications();
275                         INFO("Umount external storage...");
276                         while (1) {
277                                 try {
278                                         engine->umount();
279                                         break;
280                                 } catch (runtime::Exception &e) {
281                                         killDependedApplications();
282                                 }
283                         }
284
285                         INFO("Decryption started...");
286                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
287                         engine->decrypt(MasterKey, getOptions());
288                         INFO("Sync disk...");
289                         sync();
290                         INFO("Decryption completed");
291                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
292                 } catch (runtime::Exception &e) {
293                         ERROR("Decryption failed - " + std::string(e.what()));
294                 }
295         };
296
297         std::thread asyncWork(decryptWorker);
298         asyncWork.detach();
299
300         return 0;
301 }
302
303 int ExternalEncryption::isPasswordInitialized()
304 {
305         if (engine->isKeyMetaSet()) {
306                 return 1;
307         }
308         return 0;
309 }
310
311 int ExternalEncryption::initPassword(const std::string& password)
312 {
313         KeyManager::data pwData(password.begin(), password.end());
314         KeyManager keyManager;
315
316         keyManager.initPassword(pwData);
317         engine->setKeyMeta(keyManager.serialize());
318         return 0;
319 }
320
321 int ExternalEncryption::cleanPassword(const std::string& password)
322 {
323         KeyManager::data pwData(password.begin(), password.end());
324         KeyManager keyManager(engine->getKeyMeta());
325
326         if (!keyManager.verifyPassword(pwData)) {
327                 return -2;
328         }
329
330         engine->clearKeyMeta();
331         return 0;
332 }
333
334 int ExternalEncryption::changePassword(const std::string &oldPassword,
335                                                                            const std::string &newPassword)
336 {
337         KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
338         KeyManager::data newPwData(newPassword.begin(), newPassword.end());
339         KeyManager keyManager(engine->getKeyMeta());
340
341         if (!keyManager.verifyPassword(oldPwData)) {
342                 return -2;
343         }
344
345         keyManager.changePassword(oldPwData, newPwData);
346         engine->setKeyMeta(keyManager.serialize());
347
348         return 0;
349 }
350
351 int ExternalEncryption::verifyPassword(const std::string& password)
352 {
353         KeyManager::data pwData(password.begin(), password.end());
354         KeyManager keyManager(engine->getKeyMeta());
355
356         if (keyManager.verifyPassword(pwData)) {
357                 return 1;
358         }
359         return 0;
360 }
361
362 int ExternalEncryption::getState()
363 {
364         char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
365         if (value == NULL) {
366                 throw runtime::Exception("Failed to get vconf value");
367         }
368
369         std::string valueStr(value);
370         free(value);
371
372         if (valueStr == "encrypted") {
373                 return State::Encrypted;
374         } else if (valueStr == "unencrypted") {
375                 return State::Unencrypted;
376         } else {
377                 return State::Corrupted;
378         }
379
380         return 0;
381 }
382
383 unsigned int ExternalEncryption::getSupportedOptions()
384 {
385         return engine->getSupportedOptions();
386 }
387
388 } // namespace ode