tizen 2.3 release
[framework/system/deviced.git] / src / ode / ode.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <vconf.h>
24 #include <sys/stat.h>
25 #include <sys/statfs.h>
26 #include <sys/mount.h>
27 #include <errno.h>
28 #include <mntent.h>
29
30 #include "display/poll.h"
31 #include "display/core.h"
32 #include "core/log.h"
33 #include "core/devices.h"
34 #include "core/device-notifier.h"
35 #include "core/edbus-handler.h"
36 #include "core/common.h"
37 #include "ode.h"
38 #include "noti.h"
39 #include "mmc/mmc-handler.h"
40
41 #define SIGNAL_REQUEST_GENERAL_MOUNT            "RequestGeneralMount"
42 #define SIGNAL_REQUEST_ODE_MOUNT                        "RequestOdeMount"
43 #define SIGNAL_REQUEST_REMOVE_ERROR_NOTI        "RequestRemoveErrorNoti"
44 #define SIGNAL_REMOVE_MMC                                       "RemoveMmc"
45
46 #define VCONFKEY_ENCRYPT_NEEDED_SIZE            "db/sde/encrypt_size"
47
48 #define ODE_CRYPT_META_FILE ".MetaEcfsFile"
49 #define ODE_CRYPT_PROGRESS_FILE ".EncOngoing"
50 #define ODE_VERIFY_ENC_KEY      "/opt/etc/edk_p_sd"
51
52 #define PWLOCK_LAUNCH_NAME      "launch-app"
53 #define PWLOCK_NAME             "pwlock"
54
55 enum ode_progress_id {
56         ENCRYPT_START,
57         DECRYPT_START,
58         ENCRYPT_MOUNTED,
59         ODE_PROGRESS_MAX,
60 };
61
62 /* EN_DEV : Enable device policy
63  * DE_DEV : Disable device policy
64  * EN_MMC : Encrypted mmc
65  * DE_MMC : Decrypted mmc
66  * NO_MMC : no mmc
67  */
68 enum ode_state {
69         ENCRYPTED_DEVICE_ENCRYPTED_MMC = 0,                     /* device policy ENABLE, mmc encryption ENABLE */
70         ENCRYPTED_DEVICE_DECRYPTED_MMC,
71         ENCRPYTED_DEVICE_NO_MMC,
72         DECRYPTED_DEVICE_ENCRYPTED_MMC,
73         DECRPYTED_DEVICE_DECRYPTED_MMC,
74         ENCRYPT_ONGOING,
75 };
76
77 struct popup_data {
78         char *name;
79         char *key;
80         char *value;
81 };
82
83 static const char *ode_state_str[] = {
84         [ENCRYPTED_DEVICE_ENCRYPTED_MMC] = "ENCRYPTED_DEVICE_ENCRYPTED_MMC",
85         [ENCRYPTED_DEVICE_DECRYPTED_MMC] = "ENCRYPTED_DEVICE_DECRYPTED_MMC",
86         [ENCRPYTED_DEVICE_NO_MMC] = "ENCRPYTED_DEVICE_NO_MMC",
87         [DECRYPTED_DEVICE_ENCRYPTED_MMC] = "DECRYPTED_DEVICE_ENCRYPTED_MMC",
88         [DECRPYTED_DEVICE_DECRYPTED_MMC] = "DECRPYTED_DEVICE_DECRYPTED_MMC",
89         [ENCRYPT_ONGOING] = "ENCRYPT_OR_DECRYPT_ONGOING",
90 };
91
92 static int display_state = S_NORMAL;
93 static int ode_display_changed(void *data)
94 {
95         enum state_t state = (enum state_t)data;
96         char *str;
97         int rate;
98         if (display_state == S_LCDOFF && (state == S_NORMAL || state == S_LCDDIM)) {
99                 str = vconf_get_str(VCONFKEY_SDE_ENCRYPT_PROGRESS);
100                 if (str) {
101                         rate = atoi(str);
102                         if (rate >= 0 && rate <  100)
103                                 noti_progress_update(rate);
104                 }
105         }
106         display_state = state;
107         return 0;
108 }
109
110 static int ode_check_encrypt_sdcard()
111 {
112         int ret = 0;
113         struct stat src_stat, enc_stat;
114         const char * cryptTempFile = ODE_CRYPT_META_FILE;
115         const char * cryptProgressFile = ODE_CRYPT_PROGRESS_FILE;
116         char *mMetaDataFile;
117
118         mMetaDataFile = malloc(strlen (MMC_MOUNT_POINT) + strlen (cryptTempFile) +2);
119         if (mMetaDataFile)
120         {
121                 sprintf (mMetaDataFile, "%s%s%s", MMC_MOUNT_POINT, "/", cryptTempFile);
122                 if (lstat (mMetaDataFile, &src_stat) < 0)
123                         if (errno == ENOENT)
124                                 ret = -1;
125                 free(mMetaDataFile);
126         }
127         if (!ret && lstat (ODE_VERIFY_ENC_KEY, &enc_stat) < 0)
128                 if (errno == ENOENT)
129                         ret = -1;
130         _D("check sd card ecryption : %d", ret);
131         return ret;
132 }
133
134 static int ode_check_encrypt_progress()
135 {
136         int ret = 0;
137         struct stat src_stat;
138         const char * cryptProgressFile = ODE_CRYPT_PROGRESS_FILE;
139         char *mMetaDataFile;
140
141         mMetaDataFile = malloc(strlen (MMC_MOUNT_POINT) + strlen (cryptProgressFile) +2);
142         if (mMetaDataFile)
143         {
144                 sprintf (mMetaDataFile, "%s%s%s", MMC_MOUNT_POINT, "/", cryptProgressFile);
145                 if (lstat (mMetaDataFile, &src_stat) == 0)
146                         ret = -1;
147                 free(mMetaDataFile);
148         }
149         return ret;
150 }
151
152 static int ode_check_ecryptfs(char* path)
153 {
154         int ret = false;
155         struct mntent* mnt;
156         const char* table = "/etc/mtab";
157         FILE* fp;
158         fp = setmntent(table, "r");
159         if (!fp)
160                 return ret;
161         while (mnt=getmntent(fp)) {
162                 if (!strcmp(mnt->mnt_type, "ecryptfs") && !strcmp(mnt->mnt_dir, path)) {
163                         ret = true;
164                         break;
165                 }
166         }
167         endmntent(fp);
168         return ret;
169 }
170
171 static int ode_unmount_encrypt_sdcard(char* path)
172 {
173         int result = 0;
174         if ( ode_check_ecryptfs(path)) {
175                 if(umount2(path, MNT_DETACH) != 0) {
176                         if(umount2(path, MNT_EXPIRE) != 0) {
177                                 _E("Unmount failed for drive %s err(%d %s)\n", path, errno, strerror(errno));
178                                 if(errno == EAGAIN) {
179                                         SLOGE("Trying Unmount again\n");
180                                         if(umount2(path, MNT_EXPIRE) != 0) {
181                                                 result = -1;
182                                                 _E("Unmount failed for drive %s err(%d %s)\n", path, errno, strerror(errno));
183                                         }
184                                 } else {
185                                         _E("Drive %s unmounted failed \n", path);
186                                         result = -1;
187                                 }
188                         }
189                 }
190                 if (result == 0)
191                         _D("Drive %s unmounted successfully \n", path);
192         }
193         return result;
194 }
195
196 static void launch_syspopup(const char *option)
197 {
198         int r;
199         char str[256];
200         struct popup_data *params;
201         static const struct device_ops *apps = NULL;
202
203         snprintf(str, sizeof(str), "%s%s", "ode", option);
204
205         FIND_DEVICE_VOID(apps, "apps");
206
207         params = malloc(sizeof(struct popup_data));
208         if (params == NULL) {
209                 _E("Malloc failed");
210                 return;
211         }
212         params->name = MMC_POPUP_NAME;
213         params->key = POPUP_KEY_CONTENT;
214         params->value = strdup(str);
215         apps->init((void *)params);
216         free(params);
217         return;
218 }
219
220 static int ode_check_error_state(void)
221 {
222         char *str;
223         int type, state, val, r;
224
225         /* get progress value */
226         str = vconf_get_str(VCONFKEY_SDE_ENCRYPT_PROGRESS);
227         if (str) {
228                 if (strcmp(str, "-1")) {        /* normal state */
229                         free(str);
230                         return 0;
231                 } else                                          /* error state */
232                         free(str);
233         }
234
235         /* get memory size */
236         r = vconf_get_int(VCONFKEY_ENCRYPT_NEEDED_SIZE, &val);
237         /* get crypto state */
238         str = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
239         if (r == 0 && val == 0) {
240                 state = OPERATION_FAIL;
241                 if (!strcmp(str, "encryption_start"))
242                         type = ENCRYPT_TYPE;
243                 else
244                         type = DECRYPT_TYPE;
245         }
246         else {
247                 state = NOT_ENOUGH_SPACE;
248                 if (!strcmp(str, "unencrypted"))
249                         type = ENCRYPT_TYPE;
250                 else
251                         type = DECRYPT_TYPE;
252         }
253
254         free(str);
255
256         /* get memory size */
257         r = vconf_get_int(VCONFKEY_ENCRYPT_NEEDED_SIZE, &val);
258         if (r == 0 && val == 0)
259                 state = OPERATION_FAIL;
260         else
261                 state = NOT_ENOUGH_SPACE;
262
263         noti_error_show(type, state, val);
264         return -EPERM;
265 }
266
267 int ode_judge_state(void)
268 {
269         int dev, mmc_en;
270         int r;
271         char *en_state;
272
273         if (vconf_get_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, &dev) < 0) {
274                 _E("fail to get ode policy vconf");
275                 return -EPERM;
276         }
277
278         en_state = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
279         if (en_state) {
280                 if (ode_check_encrypt_progress() &&
281                             (!strcmp(en_state, "encryption_start")  || !strcmp(en_state, "decryption_start"))) {
282                         r = ENCRYPT_ONGOING;
283                         _I("ODE state : %s(%d)", ode_state_str[r], r);
284                         free(en_state);
285                         return r;
286                 } else
287                         free(en_state);
288         }
289
290         mmc_en = ode_check_encrypt_sdcard();
291
292         /* although mmc does not exist, this api will return ENCRYPTED_DEVICE_DECRYPTED_MMC */
293         if (dev && mmc_en)
294                 r = ENCRYPTED_DEVICE_DECRYPTED_MMC;
295         else if (dev && !mmc_en)
296                 r = ENCRYPTED_DEVICE_ENCRYPTED_MMC;
297         else if (!dev && !mmc_en)
298                 r = DECRYPTED_DEVICE_ENCRYPTED_MMC;
299         else
300                 r = DECRPYTED_DEVICE_DECRYPTED_MMC;
301
302         _I("ODE state : %s(%d)", ode_state_str[r], r);
303         return r;
304 }
305
306 static void launch_pwlock(void)
307 {
308         struct popup_data *params;
309         static const struct device_ops *apps = NULL;
310
311         FIND_DEVICE_VOID(apps, "apps");
312
313         params = malloc(sizeof(struct popup_data));
314         if (params == NULL) {
315                 _E("Malloc failed");
316                 return;
317         }
318         params->name = PWLOCK_LAUNCH_NAME;
319         params->key = PWLOCK_NAME;
320         apps->init((void *)params);
321         free(params);
322 }
323
324 int ode_launch_app(int state)
325 {
326         switch (state) {
327         case ENCRYPTED_DEVICE_DECRYPTED_MMC: launch_syspopup("encrypt"); break;
328         case DECRYPTED_DEVICE_ENCRYPTED_MMC: launch_syspopup("decrypt"); break;
329         case ENCRYPTED_DEVICE_ENCRYPTED_MMC:
330         case ENCRYPT_ONGOING:
331                 launch_pwlock();
332                 break;
333         default: break;
334         }
335         return 0;
336 }
337
338 static void progress_start(void *value)
339 {
340         pm_lock_internal(1, LCD_OFF, STAY_CUR_STATE, 0);
341         register_notifier(DEVICE_NOTIFIER_LCD, ode_display_changed);
342         noti_progress_show((int)value);
343         _D("progress start : type(%d)", (int)value);
344 }
345
346 static void progress_finish(int rate)
347 {
348         char *str;
349         int ret;
350
351         pm_unlock_internal(1, LCD_OFF, PM_SLEEP_MARGIN);
352         unregister_notifier(DEVICE_NOTIFIER_LCD, ode_display_changed);
353         noti_progress_clear();
354         _D("progress finish");
355
356         /* in case of error state */
357         ret = ode_check_error_state();
358         if (ret < 0)
359                 return;
360
361         /* when finished to encrypt or decrypt, update mount vconf in this time */
362         mmc_mount_done();
363
364         str = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
365         if (!strcmp(str, "encrypted")) {
366                 noti_finish_show(ENCRYPT_TYPE);
367                 vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, true);
368         }
369         else if (!strcmp(str, "unencrypted")) {
370                 noti_finish_show(DECRYPT_TYPE);
371                 vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, false);
372         }
373
374         free(str);
375 }
376
377 static void ode_mount(void *value)
378 {
379         mmc_mount_done();
380         _D("set mount complete vconf");
381 }
382
383 static struct ode_progress_cb {
384         const char *str;
385         void (*func) (void *value);
386         void *value;
387 } ode_progress[ODE_PROGRESS_MAX] = {
388         [ENCRYPT_START] = {"encryption_start", progress_start, (void*)ENCRYPT_TYPE},
389         [DECRYPT_START] = {"decryption_start", progress_start, (void*)DECRYPT_TYPE},
390         [ENCRYPT_MOUNTED] = {"mounted", ode_mount, NULL},
391 };
392
393 static void ode_crypto_state_cb(keynode_t *key, void* data)
394 {
395         char *str;
396         int i;
397
398         str = vconf_keynode_get_str(key);
399         if (!str)
400                 return;
401
402         for (i = 0; i < ODE_PROGRESS_MAX; ++i) {
403                 if (!strcmp(str, ode_progress[i].str)) {
404                         if (ode_progress[i].func)
405                                 ode_progress[i].func(ode_progress[i].value);
406                         break;
407                 }
408         }
409 }
410
411 static void ode_crypto_progress_cb(keynode_t *key, void* data)
412 {
413         char *str;
414         int rate;
415
416         str = vconf_keynode_get_str(key);
417         if (!str)
418                 return;
419
420         rate = atoi(str);
421
422         if (display_state == S_NORMAL || display_state == S_LCDDIM)
423                 noti_progress_update(rate);
424         _D("progress update : rate(%d)", rate);
425
426         if (rate == 100 || rate < 0)
427                 progress_finish(rate);
428 }
429
430 static void ode_request_general_mount(void *data, DBusMessage *msg)
431 {
432         mmc_mount_done();
433         vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, false);
434         _D("ode_request_general_mount occurs!!!");
435 }
436
437 static void ode_request_ode_mount(void *data, DBusMessage *msg)
438 {
439         launch_pwlock();
440         vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, true);
441         _D("ode_request_ode_mount occurs!!!");
442 }
443
444 static void ode_request_remove_error_noti(void *data, DBusMessage *msg)
445 {
446         if (noti_error_clear() < 0)
447                 _E("Failed to remove error notification");
448 }
449
450 int ode_mmc_removed(void)
451 {
452         int r;
453
454         r = ode_unmount_encrypt_sdcard(MMC_MOUNT_POINT);
455         if (r < 0)
456                 _E("fail to sde_crypto_unmount");
457
458         /* delete error noti */
459         noti_error_clear();
460
461         /* send signal to syspopup for deleting a popup when removed mmc */
462         broadcast_edbus_signal(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
463                         SIGNAL_REMOVE_MMC, NULL, NULL);
464         return r;
465 }
466
467 int ode_mmc_inserted(void)
468 {
469         int op;
470
471         op = ode_judge_state();
472         switch (op) {
473         case ENCRYPTED_DEVICE_ENCRYPTED_MMC:
474         case DECRYPTED_DEVICE_ENCRYPTED_MMC:
475                 vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "encrypted");
476                 break;
477         case ENCRYPT_ONGOING:
478                 break;
479         default:
480                 vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
481                 break;
482         }
483
484         if (op != DECRPYTED_DEVICE_DECRYPTED_MMC) {
485                 ode_launch_app(op);
486                 return -1;
487         }
488
489         return 0;
490 }
491
492 static void ode_internal_init(void *data)
493 {
494         /* init dbus interface */
495         register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
496                         SIGNAL_REQUEST_GENERAL_MOUNT,
497                         ode_request_general_mount);
498         register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
499                         SIGNAL_REQUEST_ODE_MOUNT,
500                         ode_request_ode_mount);
501         register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
502                         SIGNAL_REQUEST_REMOVE_ERROR_NOTI,
503                         ode_request_remove_error_noti);
504
505
506         /* register vconf callback */
507         vconf_notify_key_changed(VCONFKEY_SDE_CRYPTO_STATE,
508                         ode_crypto_state_cb, NULL);
509         vconf_notify_key_changed(VCONFKEY_SDE_ENCRYPT_PROGRESS,
510                         ode_crypto_progress_cb, NULL);
511 }
512
513 static void ode_internal_exit(void *data)
514 {
515         /* unregister vconf callback */
516         vconf_ignore_key_changed(VCONFKEY_SDE_CRYPTO_STATE,
517                         ode_crypto_state_cb);
518         vconf_ignore_key_changed(VCONFKEY_SDE_ENCRYPT_PROGRESS,
519                         ode_crypto_progress_cb);
520 }
521
522 static const struct device_ops ode_device_ops = {
523         .priority = DEVICE_PRIORITY_NORMAL,
524         .name     = "ode",
525         .init     = ode_internal_init,
526         .exit     = ode_internal_exit,
527 };
528
529 DEVICE_OPS_REGISTER(&ode_device_ops)