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