9d2eafb9300b19e4da245377118ca2c0c81c3b2e
[platform/core/messaging/email-service.git] / email-core / email-core-account.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21
22
23 /******************************************************************************
24  * File :  email-core-account.c
25  * Desc :  Account Management
26  *
27  * Auth :  Kyuho Jo
28  *
29  * History :
30  *    2010.08.25  :  created
31  *****************************************************************************/
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <vconf.h>
39 #include <curl/curl.h>
40 #include <sys/shm.h>
41 #include <tpkp_curl.h>
42 #include <ckmc/ckmc-manager.h>
43
44
45 #include "email-convert.h"
46 #include "email-types.h"
47 #include "email-daemon.h"
48 #include "email-debug-log.h"
49 #include "email-storage.h"
50 #include "email-network.h"
51 #include "email-utilities.h"
52 #include "email-core-utils.h"
53 #include "email-core-event.h"
54 #include "email-core-global.h"
55 #include "email-core-account.h"
56 #include "email-core-mailbox.h"
57 #include "email-core-signal.h"
58 #include "email-core-imap-mailbox.h"
59 #include "email-core-container.h"
60 #include "email-core-key-manager.h"
61
62 #include "imap4r1.h"
63
64 #include "account.h"
65 #include "account-types.h"
66
67 #define EMAIL_SERVICE_BNR_ACCOUNT_KEY "email_service_backup_restore_account_key"
68
69 char *g_default_mbox_alias[MAILBOX_COUNT] = {
70         EMAIL_INBOX_DISPLAY_NAME,
71         EMAIL_DRAFTBOX_DISPLAY_NAME,
72         EMAIL_OUTBOX_DISPLAY_NAME,
73         EMAIL_SENTBOX_DISPLAY_NAME,
74         EMAIL_TRASH_DISPLAY_NAME,
75         EMAIL_SPAMBOX_DISPLAY_NAME,
76 };
77
78 char *g_default_mbox_name[MAILBOX_COUNT] = {
79         EMAIL_INBOX_NAME,
80         EMAIL_DRAFTBOX_NAME,
81         EMAIL_OUTBOX_NAME,
82         EMAIL_SENTBOX_NAME,
83         EMAIL_TRASH_DISPLAY_NAME,
84         EMAIL_SPAMBOX_NAME,
85 };
86
87 email_mailbox_type_e g_default_mbox_type[MAILBOX_COUNT] = {
88         EMAIL_MAILBOX_TYPE_INBOX,
89         EMAIL_MAILBOX_TYPE_DRAFT,
90         EMAIL_MAILBOX_TYPE_OUTBOX,
91         EMAIL_MAILBOX_TYPE_SENTBOX,
92         EMAIL_MAILBOX_TYPE_TRASH,
93         EMAIL_MAILBOX_TYPE_SPAMBOX,
94 };
95
96 INTERNAL_FUNC email_account_t* emcore_get_account_reference(char *multi_user_name, int account_id, int with_password)
97 {
98         EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id);
99         int err = EMAIL_ERROR_NONE;
100         email_account_t *result_account = NULL;
101         emstorage_account_tbl_t *p_result_account = NULL;
102
103         if (account_id < 0) {
104                    emcore_get_account_from_unvalidated_account_list(account_id, &result_account);
105                    return result_account;
106         } else if (account_id > 0) {
107                         if (with_password) {
108                                 if (!emstorage_get_account_by_id(multi_user_name, account_id, EMAIL_ACC_GET_OPT_FULL_DATA, &p_result_account, false, &err)) {
109                                         EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", err);
110                                         return NULL;
111                                 }
112                         } else {
113                                 if (!emstorage_get_account_by_id(multi_user_name, account_id, GET_FULL_DATA_WITHOUT_PASSWORD, &p_result_account, false, &err)) {
114                                         EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", err);
115                                         return NULL;
116                                 }
117                         }
118
119                         result_account = (email_account_t *)em_malloc(sizeof(email_account_t));
120                         if (result_account == NULL) {
121                                 EM_DEBUG_EXCEPTION("em_mallocfailed");
122                                 return NULL;
123                         }
124
125                         em_convert_account_tbl_to_account(p_result_account, result_account);
126
127                         emstorage_free_account(&p_result_account, 1, NULL);
128         }
129
130         EM_DEBUG_FUNC_END("[%p]", result_account);
131         return result_account;
132 }
133
134 INTERNAL_FUNC int emcore_get_account_reference_list(char *multi_user_name, email_account_t **output_account_list, int *output_count)
135 {
136         EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%p]", output_account_list, output_count);
137     int err = EMAIL_ERROR_NONE;
138     int i = 0;
139     int account_count = 0;
140     email_account_t *account_list = NULL;
141     emstorage_account_tbl_t *account_list_tbl = NULL;
142
143     if (!emstorage_get_account_list(multi_user_name, &account_count, &account_list_tbl, false, true, &err)) {
144         EM_DEBUG_EXCEPTION("emstorage_get_account_list failed : [%d]", err);
145         goto FINISH_OFF;
146     }
147
148     if (account_count > 0) {
149         account_list = em_malloc(sizeof(email_account_t) * (account_count));
150         if (account_list == NULL) {
151             EM_DEBUG_EXCEPTION("em_mallocfailed");
152             err = EMAIL_ERROR_OUT_OF_MEMORY;
153             goto FINISH_OFF;
154         }
155     }
156
157     for (i = 0; i < account_count; i++) {
158         em_convert_account_tbl_to_account(&account_list_tbl[i], &account_list[i]);
159     }
160
161 FINISH_OFF:
162
163     if (account_list_tbl)
164         emstorage_free_account(&account_list_tbl, account_count, NULL);
165
166     if (output_account_list)
167         *output_account_list = account_list;
168
169     if (output_count)
170         *output_count = account_count;
171
172         EM_DEBUG_FUNC_END();
173         return err;
174 }
175
176 static char *emcore_get_imap_capability_string(MAILSTREAM *input_stream)
177 {
178         EM_DEBUG_FUNC_BEGIN_SEC("input_stream[%p]", input_stream);
179         char *result_string = NULL;
180         IMAPCAP *imap_capability = NULL;
181         char capability_string[512] = { 0, };
182
183         if ((imap_capability = imap_cap(input_stream))) {
184                 if (imap_capability->idle)
185                         EM_SAFE_STRNCAT(capability_string, "IDLE ", sizeof(capability_string) - EM_SAFE_STRLEN(capability_string) - 1);
186                 if (imap_capability->quota)
187                         EM_SAFE_STRNCAT(capability_string, "QUOTA ", sizeof(capability_string) - EM_SAFE_STRLEN(capability_string) - 1);
188                 if (imap_capability->starttls)
189                         EM_SAFE_STRNCAT(capability_string, "STARTTLS ", sizeof(capability_string) - EM_SAFE_STRLEN(capability_string) - 1);
190 #ifdef __FEATURE_XLIST_SUPPORT__
191                 if (imap_capability->xlist)
192                         EM_SAFE_STRNCAT(capability_string, "XLIST ", sizeof(capability_string) - EM_SAFE_STRLEN(capability_string) - 1);
193 #endif /* __FEATURE_XLIST_SUPPORT__ */
194                 result_string = EM_SAFE_STRDUP(capability_string);
195         }
196
197         EM_DEBUG_FUNC_END("[%s]", result_string);
198         return result_string;
199 }
200
201 INTERNAL_FUNC int emcore_validate_account_with_account_info(char *multi_user_name, email_account_t *account, email_event_type_t event_type, char **output_server_capability_string, int event_handle, int *err_code)
202 {
203         EM_DEBUG_FUNC_BEGIN_SEC("account[%p] output_server_capability_string[%p] err_code[%p] incoming_server_address [%s]", account, output_server_capability_string, err_code, account->incoming_server_address);
204
205         int ret = false;
206         int err = EMAIL_ERROR_NONE;
207         int server_capability_string_length = 0;
208         email_session_t *session = NULL;
209         char *imap_capability_string = NULL;
210         char smtp_capability_string[128] = { 0, };
211         SENDSTREAM *stream = NULL;
212         MAILSTREAM *tmp_stream = NULL;
213
214         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
215
216         if (!emnetwork_check_network_status(&err)) {
217                 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed [%d]", err);
218                 goto FINISH_OFF;
219         }
220         EM_DEBUG_LOG("Network available");
221
222         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
223
224         if (!emcore_get_empty_session(&session)) {
225                 EM_DEBUG_EXCEPTION("emcore_get_empty_session failed...");
226 /*              err = EMAIL_ERROR_SESSION_NOT_FOUND;
227                 goto FINISH_OFF; */
228         }
229
230         /* validate connection for pop3/imap */
231         EM_DEBUG_LOG("Validate connection for POP3/IMAP4");
232
233         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
234
235         if (!emcore_connect_to_remote_mailbox_with_account_info(multi_user_name,
236                                                                                                                         account,
237                                                                                                                         0,
238                                                                                                                         true,
239                                                                                                                         (void **)&tmp_stream,
240                                                                                                                         &err) || !tmp_stream) {
241                 EM_DEBUG_LOG("emcore_connect_to_remote_mailbox failed [%d]", err);
242                 if (EMAIL_ERROR_AUTHENTICATE == err || EMAIL_ERROR_LOGIN_FAILURE == err) {      /*  wrong password or etc */
243                         EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed : Login or Authentication failed - %d", err);
244                 } else if (EMAIL_ERROR_CONNECTION_FAILURE != err) {
245                         /* err = EMAIL_ERROR_VALIDATE_ACCOUNT */
246                 }
247                 goto FINISH_OFF;
248         }
249
250         if (account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)
251                 imap_capability_string = emcore_get_imap_capability_string(tmp_stream);
252
253 #ifdef __FEATURE_SMTP_VALIDATION__
254         /* validate connection for SMTP */
255         EM_DEBUG_LOG("Validate connection for SMTP server");
256
257         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
258
259         if (!emcore_connect_to_remote_mailbox_with_account_info(multi_user_name,
260                                                                                                                         account,
261                                                                                                                         EMAIL_CONNECT_FOR_SENDING,
262                                                                                                                         true,
263                                                                                                                         (void **)&stream,
264                                                                                                                         &err) || !stream) {
265                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed [%d]", err);
266                 err = EMAIL_ERROR_VALIDATE_ACCOUNT_OF_SMTP;
267                 goto FINISH_OFF;
268
269 #if 0
270                 if (account->outgoing_server_secure_connection == 0x01) /*  0x01 == SSL */ {
271                         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
272
273                         EM_DEBUG_LOG("Retry with TLS");
274                         account->outgoing_server_secure_connection = 0x02;      /*  0x02 == TLS */
275
276                         if (!emcore_connect_to_remote_mailbox_with_account_info(multi_user_name,
277                                                                                                                                         account,
278                                                                                                                                         EMAIL_CONNECT_FOR_SENDING,
279                                                                                                                                         true,
280                                                                                                                                         (void **)&stream,
281                                                                                                                                         &err) || !stream) {
282                                 EM_DEBUG_LOG("emcore_connect_to_remote_mailbox failed [%d]", err);
283                                 err = EMAIL_ERROR_VALIDATE_ACCOUNT_OF_SMTP;
284                                 account->outgoing_server_secure_connection = 0x01;      /*  restore to the previous value */
285                                 goto FINISH_OFF;
286                         }
287
288                         FINISH_OFF_IF_EVENT_CANCELED(err, event_handle);
289                 } else {
290                         err = EMAIL_ERROR_VALIDATE_ACCOUNT_OF_SMTP;
291                         goto FINISH_OFF;
292                 }
293 #endif
294         }
295         if (stream && stream->protocol.esmtp.ok) {
296                 if (stream->protocol.esmtp.size.ok && stream->protocol.esmtp.size.limit > 0) {
297                         account->outgoing_server_size_limit = stream->protocol.esmtp.size.limit;
298                         SNPRINTF(smtp_capability_string, 128, "SMTP_MAIL_SIZE_LIMIT=%d ", account->outgoing_server_size_limit);
299                         EM_DEBUG_LOG("%s", smtp_capability_string);
300                 }
301         }
302 #endif /* __FEATURE_SMTP_VALIDATION__ */
303
304         int dummy = 0;
305         if (!emcore_check_event_thread_status(&dummy, event_handle)) {
306                 EM_DEBUG_LOG("canceled event: [%d]", dummy);
307                 if (event_type == EMAIL_EVENT_VALIDATE_AND_CREATE_ACCOUNT || event_type == EMAIL_EVENT_VALIDATE_ACCOUNT_EX) {
308                         if (!emcore_delete_account(multi_user_name, account->account_id, false, NULL))
309                                 EM_DEBUG_EXCEPTION("emdaemon_delete_account failed [%d]", account->account_id);
310                 }
311                 err = EMAIL_ERROR_CANCELLED;
312                 goto FINISH_OFF;
313         }
314
315         if (output_server_capability_string) {
316                 server_capability_string_length = EM_SAFE_STRLEN(imap_capability_string) + EM_SAFE_STRLEN(smtp_capability_string);
317                 if (server_capability_string_length) {
318                         *output_server_capability_string = em_malloc(server_capability_string_length + 1);
319
320                         if      (*output_server_capability_string == NULL) {
321                                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_OUT_OF_MEMORY");
322                                 err = EMAIL_ERROR_OUT_OF_MEMORY;
323                                 goto FINISH_OFF;
324                         }
325                         EM_SAFE_STRNCAT(*output_server_capability_string, smtp_capability_string, (server_capability_string_length + 1) - EM_SAFE_STRLEN(*output_server_capability_string) - 1);
326                         EM_SAFE_STRNCAT(*output_server_capability_string, imap_capability_string, (server_capability_string_length + 1) - EM_SAFE_STRLEN(*output_server_capability_string) - 1);
327                         EM_DEBUG_LOG("%s", *output_server_capability_string);
328                 }
329         }
330
331         ret = true;
332
333 FINISH_OFF:
334         if (stream)
335                 smtp_close(stream);
336
337         if (tmp_stream)
338                 tmp_stream = mail_close(tmp_stream);
339
340         if (err_code != NULL)
341                 *err_code = err;
342
343         EM_SAFE_FREE(imap_capability_string);
344
345         emcore_clear_session(session);
346
347         EM_DEBUG_FUNC_END();
348         return ret;
349 }
350
351
352 INTERNAL_FUNC int emcore_validate_account(char *multi_user_name, int account_id, int handle, int *err_code)
353 {
354         EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code);
355
356         int err = EMAIL_ERROR_NONE, ret = false;
357         email_account_t *ref_account = NULL;
358
359
360         if (account_id <= 0) {
361                 EM_DEBUG_EXCEPTION("account_id[%d]", account_id);
362                 err = EMAIL_ERROR_INVALID_PARAM;
363                 goto FINISH_OFF;
364         }
365
366         ref_account = emcore_get_account_reference(multi_user_name, account_id, false);
367
368         if (ref_account && emcore_validate_account_with_account_info(multi_user_name, ref_account, EMAIL_EVENT_VALIDATE_ACCOUNT, NULL, handle, &err) == false) {
369                 EM_DEBUG_EXCEPTION("emcore_validate_account_with_account_info failed (%d)", err);
370                 goto FINISH_OFF;
371         }
372
373         ret = true;
374
375 FINISH_OFF:
376
377         if (ref_account) {
378                 emcore_free_account(ref_account);
379                 EM_SAFE_FREE(ref_account);
380         }
381
382         if (err_code)
383                 *err_code = err;
384
385         EM_DEBUG_FUNC_END();
386
387         return ret;
388 }
389
390 key_t del_account_key = 4511; /* name of the segment d/4 e/5 l/11 */
391
392 INTERNAL_FUNC int emcore_delete_account(char *multi_user_name, int account_id, int input_delete_from_account_svc, int *err_code)
393 {
394         EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code);
395
396         int shmid = 0;
397         int *del_account_id = NULL;
398
399         EM_DEBUG_LOG("begin account_id [%d]", account_id);
400         /* worker thread is single instance, so multiple accounts cant be deleted concurrently */
401         if ((shmid = shmget(del_account_key, sizeof(int), IPC_CREAT | 0666)) != -1) {
402                 /* attaching the segment to the current process space */
403                 if ((del_account_id = (int*) shmat(shmid, NULL, 0)) != (int*) -1) {
404                         /* write it */
405                         *del_account_id = account_id;
406                         EM_DEBUG_LOG("recorded account_id [%d]", *del_account_id);
407                 } else
408                         EM_DEBUG_EXCEPTION("shmget error[%d]", errno);
409
410         } else
411                 EM_DEBUG_EXCEPTION("shmget error[%d]", errno);
412
413         /*  default variabl */
414         int ret = false;
415         int err = EMAIL_ERROR_NONE;
416         int before_tr_begin = 0;
417
418         if (account_id < FIRST_ACCOUNT_ID)  {
419                 EM_DEBUG_EXCEPTION("account_id[%d]", account_id);
420                 err = EMAIL_ERROR_INVALID_PARAM;
421                 before_tr_begin = 1;
422                 goto FINISH_OFF;
423         }
424
425 #ifdef __FEATURE_LOCAL_ACTIVITY__
426         /* Delete all local activities of previous account */
427         emstorage_activity_tbl_t activity;
428         memset(&activity, 0x00, sizeof(emstorage_activity_tbl_t));
429         activity.account_id = account_id;
430     activity.multi_user_name = EM_SAFE_STRDUP(multi_user_name);
431
432         if (!emcore_delete_activity(&activity, &err)) {
433                 EM_DEBUG_LOG("\t emcore_delete_activity failed - %d", err);
434                 before_tr_begin = 1;
435                 goto FINISH_OFF;
436         }
437 #endif
438
439 #ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__
440         if (false == emcore_clear_partial_body_thd_event_que(&err))
441                 EM_DEBUG_EXCEPTION(" emcore_clear_partial_body_thd_event_que [%d]", err);
442
443         if (false == emstorage_delete_full_pbd_activity_data(multi_user_name, account_id, true, &err))
444                 EM_DEBUG_EXCEPTION("emstorage_delete_full_pbd_activity_data failed [%d]", err);
445
446 #endif
447
448 #ifdef __FEATURE_WIFI_AUTO_DOWNLOAD__
449         if (!emcore_clear_auto_download_queue())
450                 EM_DEBUG_EXCEPTION("emcore_clear_auto_download_queue failed");
451
452         if (!emstorage_delete_all_auto_download_activity(multi_user_name, account_id, true, &err))
453                 EM_DEBUG_EXCEPTION("emstorage_delete_all_auto_download_activity failed [%d]", err);
454 #endif
455
456         if (input_delete_from_account_svc == true) {
457                 int error_code_from_account_svc = 0;
458                 email_account_t *account_to_be_deleted;
459                 void *join_zone = NULL;
460
461                 account_to_be_deleted = emcore_get_account_reference(multi_user_name, account_id, false);
462                 if (account_to_be_deleted && account_to_be_deleted->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
463                         EM_DEBUG_LOG("Calling account_svc_delete with account_svc_id[%d]", account_to_be_deleted->account_svc_id);
464                         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
465                                 if ((err = emcore_set_join_zone(multi_user_name, &join_zone)) != EMAIL_ERROR_NONE) {
466                                         EM_DEBUG_EXCEPTION("emcore_set_join_zone failed : [%d]", err);
467                                         goto FINISH_OFF;
468                                 }
469                         }
470
471                         error_code_from_account_svc = account_delete_from_db_by_id(account_to_be_deleted->account_svc_id);
472                         EM_DEBUG_LOG("account_delete_from_db_by_id returns [%d]", error_code_from_account_svc);
473
474                         if (join_zone)
475                                 emcore_unset_join_zone(join_zone);
476                 }
477
478                 if (account_to_be_deleted) {
479                         emcore_free_account(account_to_be_deleted);
480                         EM_SAFE_FREE(account_to_be_deleted);
481                 }
482         }
483
484         if (emcore_cancel_all_threads_of_an_account(multi_user_name, account_id) < EMAIL_ERROR_NONE) {
485                 EM_DEBUG_EXCEPTION("There are some remaining jobs. I couldn't stop them.");
486                 err = EMAIL_ERROR_CANNOT_STOP_THREAD;
487                 before_tr_begin = 1;
488                 goto FINISH_OFF;
489         }
490
491         /* Delete contact log */
492         if (((err = emcore_delete_contacts_log(multi_user_name, account_id)) != EMAIL_ERROR_NONE) && (err != EMAIL_ERROR_DATA_NOT_FOUND)) {
493         EM_DEBUG_EXCEPTION("emcore_delete_contacts_log failed : [%d]", err);
494         }
495
496         /*  BEGIN TRANSACTION;           */
497         if (!emstorage_begin_transaction(multi_user_name, NULL, NULL, &err)) {
498                 EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed [%d]", err);
499                 before_tr_begin = 1;
500                 goto FINISH_OFF;
501         }
502
503         if (!emstorage_delete_account(multi_user_name, account_id, false, &err)) {
504                 if (err != EMAIL_ERROR_SYSTEM_FAILURE) {
505                         EM_DEBUG_EXCEPTION("emstorage_delete_account failed [%d]", err);
506                         goto FINISH_OFF;
507                 }
508         }
509
510 #ifdef __FEATURE_KEEP_CONNECTION__
511         /* emcore_reset_streams(); */
512         if (emcore_remove_connection_info(account_id) != EMAIL_ERROR_NONE)
513                 EM_DEBUG_EXCEPTION("emcore_remove_connection_info failed \n");
514 #endif
515
516         if ((err = emcore_delete_all_mails_of_acount(multi_user_name, account_id)) != EMAIL_ERROR_NONE) {
517                 EM_DEBUG_EXCEPTION("emcore_delete_all_mails_of_acount failed [%d]", err);
518                 goto FINISH_OFF;
519         }
520
521         /*  delete all mailboxes */
522         if (!emstorage_delete_mailbox(multi_user_name, account_id, -1, 0, false, &err)) {
523                 if (err != EMAIL_ERROR_MAILBOX_NOT_FOUND) {
524                         EM_DEBUG_EXCEPTION("emstorage_delete_mailbox failed - %d", err);
525                         goto FINISH_OFF;
526                 }
527         }
528
529         /*  delete local imap sync mailbox from imap mailbox table */
530         if (!emstorage_remove_downloaded_mail(multi_user_name, account_id, 0, NULL, NULL, false, &err)) {
531                 EM_DEBUG_EXCEPTION("emstorage_remove_downloaded_mail failed - %d", err);
532                 goto FINISH_OFF;
533         }
534
535         emcore_display_unread_in_badge(multi_user_name);
536         if (emcore_delete_notification_by_account(multi_user_name, account_id, true, true, true) != EMAIL_ERROR_NONE)
537                 EM_DEBUG_EXCEPTION("emcore_delete_notification_by_account failed \n");
538
539         ret = true;
540
541 FINISH_OFF:
542         if (ret == true) {      /*  COMMIT TRANSACTION; */
543                 if (emstorage_commit_transaction(multi_user_name, NULL, NULL, NULL) == false) {
544                         err = EMAIL_ERROR_DB_FAILURE;
545                         ret = false;
546                 }
547                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_DELETE, account_id, 0, NULL, 0))
548                         EM_DEBUG_EXCEPTION(" emcore_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> ");
549
550         } else {        /*  ROLLBACK TRANSACTION; */
551                 if (!before_tr_begin && emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL) == false)
552                         err = EMAIL_ERROR_DB_FAILURE;
553                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_DELETE_FAIL, account_id, err, NULL, 0))
554                         EM_DEBUG_EXCEPTION(" emcore_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> ");
555         }
556
557         if (err_code)
558                 *err_code = err;
559
560         /* del the segment */
561         if (shmid != -1) {
562                 shmctl(shmid, IPC_RMID, NULL);
563         }
564
565         EM_DEBUG_FUNC_END();
566
567         return ret;
568 }
569
570 INTERNAL_FUNC int emcore_create_account(char *multi_user_name, email_account_t *account, int add_account_to_account_svc, int *err_code)
571 {
572         EM_DEBUG_FUNC_BEGIN("account[%p] add_account_to_account_svc [%d] err_code[%p]", account, add_account_to_account_svc, err_code);
573
574         int ret = false;
575         int err = EMAIL_ERROR_NONE;
576         int i, count = 0;
577         int private_id = 0;
578         char vconf_private_id[MAX_PATH] = {0, };
579         email_mailbox_t local_mailbox = {0};
580         emstorage_account_tbl_t *temp_account_tbl = NULL;
581
582         if (account == NULL)  {
583                 EM_DEBUG_EXCEPTION("account[%p]", account);
584                 err = EMAIL_ERROR_INVALID_PARAM;
585                 goto FINISH_OFF;
586         }
587
588         if (!emstorage_get_account_count(multi_user_name, &count, true, &err))  {
589                 EM_DEBUG_EXCEPTION("emstorage_get_account_count failed - %d", err);
590                 goto FINISH_OFF;
591         }
592
593
594         if (count >= EMAIL_ACCOUNT_MAX)  {
595                 EM_DEBUG_EXCEPTION("too many accounts...");
596                 err = EMAIL_ERROR_ACCOUNT_MAX_COUNT;
597                 goto FINISH_OFF;
598         }
599
600         account->account_id = 0;
601
602         /* Temporarily code - begin */
603         if (account->default_mail_slot_size == 0) {
604                 account->default_mail_slot_size = 50;
605                 EM_DEBUG_LOG("account->default_mail_slot_size [%d]", account->default_mail_slot_size);
606         }
607         /* Temporarily code - end */
608
609         /* check for email address validation */
610         EM_DEBUG_LOG_SEC("account->user_email_address[%s]", account->user_email_address);
611         if (account->user_email_address) {
612                 if ((err = em_verify_email_address(account->user_email_address)) != EMAIL_ERROR_NONE) {
613                         EM_DEBUG_EXCEPTION("em_verify_email_address error [%d]", err);
614                         goto FINISH_OFF;
615                 }
616         }
617
618         if (EM_SAFE_STRLEN(account->options.alert_ringtone_path) == 0) {
619                 char *tempPtr = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
620                 account->options.alert_ringtone_path = EM_SAFE_STRDUP(tempPtr);
621                 free(tempPtr);
622                 tempPtr = NULL;
623         }
624
625         if (add_account_to_account_svc) {
626                 if (account->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
627                         int account_svc_id = 0;
628                         int error_code = 0;
629                         account_h account_handle = NULL;
630                         void *join_zone = NULL;
631
632                         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
633                                 err = emcore_set_join_zone(multi_user_name, &join_zone);
634                                 if (err != EMAIL_ERROR_NONE) {
635                                         EM_DEBUG_EXCEPTION("emcore_set_join_zone failed : [%d]", err);
636                                         goto FINISH_OFF;
637                                 }
638                         }
639
640
641                         error_code = account_create(&account_handle);
642                         if (error_code != ACCOUNT_ERROR_NONE) {
643                                 EM_DEBUG_EXCEPTION("account_create failed [%d]", error_code);
644                                 err = error_code;
645                                 if (join_zone) emcore_unset_join_zone(join_zone);
646                                 goto FINISH_OFF;
647                         }
648
649                         error_code = account_set_user_name(account_handle, account->incoming_server_user_name);
650                         if (error_code != ACCOUNT_ERROR_NONE) {
651                                 EM_DEBUG_LOG("account_set_user_name failed [%d]", error_code);
652                         }
653
654                         error_code = account_set_domain_name(account_handle, account->account_name);
655                         if (error_code != ACCOUNT_ERROR_NONE) {
656                                 EM_DEBUG_LOG("account_set_domain_name failed [%d]", error_code);
657                         }
658
659                         error_code = account_set_email_address(account_handle,  account->user_email_address);
660                         if (error_code != ACCOUNT_ERROR_NONE) {
661                                 EM_DEBUG_LOG("account_set_email_address failed [%d]", error_code);
662                         }
663
664                         error_code = account_set_source(account_handle, "SLP EMAIL");
665                         if (error_code != ACCOUNT_ERROR_NONE) {
666                                 EM_DEBUG_LOG("account_set_source failed [%d]", error_code);
667                         }
668
669                         error_code = account_set_package_name(account_handle, "email-setting-efl");
670                         if (error_code != ACCOUNT_ERROR_NONE) {
671                                 EM_DEBUG_LOG("account_set_package_name failed [%d]", error_code);
672                         }
673
674                         /* account_set_capability(account_handle , ACCOUNT_CAPABILITY_EMAIL, ACCOUNT_CAPABILITY_ENABLED); OLD API */
675                         error_code = account_set_capability(account_handle , ACCOUNT_SUPPORTS_CAPABILITY_EMAIL , ACCOUNT_CAPABILITY_ENABLED);
676                         if (error_code != ACCOUNT_ERROR_NONE) {
677                                 EM_DEBUG_LOG("account_set_capability failed [%d]", error_code);
678                         }
679
680                         error_code = account_set_sync_support(account_handle, ACCOUNT_SYNC_STATUS_IDLE); /* This means "The account is supporting 'sync' and initialized as idle status" */
681                         if (error_code != ACCOUNT_ERROR_NONE) {
682                                 EM_DEBUG_LOG("account_set_sync_support failed [%d]", error_code);
683                         }
684
685                         if (account->logo_icon_path) {
686                                 error_code = account_set_icon_path(account_handle, account->logo_icon_path);
687                                 if (error_code != ACCOUNT_ERROR_NONE) {
688                                         EM_DEBUG_LOG("account_set_icon_path failed [%d]", error_code);
689                                 }
690                         }
691
692                         error_code = account_insert_to_db(account_handle, &account_svc_id);
693                         if (error_code != ACCOUNT_ERROR_NONE) {
694                                 EM_DEBUG_EXCEPTION("account_insert_to_db failed [%d]", error_code);
695                         } else {
696                                 account->account_svc_id = account_svc_id;
697                                 EM_DEBUG_LOG("account_insert_to_db succeed");
698                         }
699
700                         if (account_handle)
701                                 account_destroy(account_handle);
702
703                         if (join_zone) emcore_unset_join_zone(join_zone);
704                 }
705         }
706
707         temp_account_tbl = em_malloc(sizeof(emstorage_account_tbl_t));
708         if (!temp_account_tbl) {
709                 EM_DEBUG_EXCEPTION("allocation failed [%d]", err);
710                 goto FINISH_OFF;
711         }
712
713         em_convert_account_to_account_tbl(account, temp_account_tbl);
714
715         if (!emstorage_add_account(multi_user_name, temp_account_tbl, true, &err))  {
716                 EM_DEBUG_EXCEPTION("emstorage_add_account failed - %d", err);
717                 goto FINISH_OFF;
718         }
719         account->account_id = temp_account_tbl->account_id;
720
721         if (account->incoming_server_type == EMAIL_SERVER_TYPE_POP3) {
722                 /* 1. create default local mailbox
723                 *    (Inbox, Draft, Outbox, Sentbox) */
724                 for (i = 0; i < MAILBOX_COUNT; i++) {
725                         EM_DEBUG_LOG_SEC("g_default_mbox_name [%d/%d] is [%s]", i, MAILBOX_COUNT, g_default_mbox_name[i]);
726                         local_mailbox.account_id      = temp_account_tbl->account_id;
727                         local_mailbox.mailbox_name    = EM_SAFE_STRDUP(g_default_mbox_name[i]);
728                         local_mailbox.alias           = EM_SAFE_STRDUP(g_default_mbox_alias[i]);
729                         local_mailbox.mailbox_type    = g_default_mbox_type[i];
730                         local_mailbox.mail_slot_size  = temp_account_tbl->default_mail_slot_size;
731                         local_mailbox.eas_data        = NULL;
732                         local_mailbox.eas_data_length = 0;
733
734                         if (local_mailbox.mailbox_type == EMAIL_MAILBOX_TYPE_INBOX)
735                                 local_mailbox.local = EMAIL_MAILBOX_FROM_SERVER;
736                         else
737                                 local_mailbox.local = EMAIL_MAILBOX_FROM_LOCAL;
738
739                         if (!emcore_create_mailbox(multi_user_name, &local_mailbox, 0, account->incoming_server_type, account->default_mail_slot_size, &err)) {
740                                 EM_DEBUG_EXCEPTION("emcore_create failed [%d]", err);
741                                 emcore_free_mailbox(&local_mailbox);
742                                 goto FINISH_OFF;
743                         }
744
745                         emcore_free_mailbox(&local_mailbox);
746                 }
747         }
748
749         /* Initialize the noti private id */
750         SNPRINTF(vconf_private_id, sizeof(vconf_private_id), "%s/%d", VCONF_KEY_NOTI_PRIVATE_ID, account->account_id);
751         if (vconf_get_int(vconf_private_id, &private_id) != 0) {
752                 EM_DEBUG_EXCEPTION("vconf_get_int failed");
753         } else {
754                 if (vconf_set_int(vconf_private_id, 0) != 0) {
755                         EM_DEBUG_EXCEPTION("vconf_set_int failed : [NOTI key initialize]");
756                 }
757         }
758
759         ret = true;
760
761 FINISH_OFF:
762         if (temp_account_tbl)
763                 emstorage_free_account(&temp_account_tbl, 1, NULL);
764
765         if (ret == false && account != NULL)  {
766                 if (!emcore_delete_account(multi_user_name, account->account_id, false, NULL))
767                         EM_DEBUG_EXCEPTION("emdaemon_delete_account Failed [%d]", account->account_id);
768         }
769
770         if (err_code)
771                 *err_code = err;
772
773         EM_DEBUG_FUNC_END("Return value [%d]", ret);
774         return ret;
775 }
776
777 INTERNAL_FUNC int emcore_free_account_list(email_account_t **account_list, int count, int *err_code)
778 {
779         EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%d], err_code[%p]", account_list, count, err_code);
780
781         int ret = false;
782         int err = EMAIL_ERROR_NONE;
783
784         if (count <= 0 || !account_list || !*account_list) {
785                 err = EMAIL_ERROR_INVALID_PARAM;
786                 goto FINISH_OFF;
787         }
788
789         email_account_t *p = *account_list;
790         int i;
791         for (i = 0; i < count; i++)
792                 emcore_free_account(p+i);
793
794         EM_SAFE_FREE(p);
795         *account_list = NULL;
796
797         ret = true;
798
799 FINISH_OFF:
800         if (err_code)
801                 *err_code = err;
802         EM_DEBUG_FUNC_END();
803         return ret;
804 }
805
806 INTERNAL_FUNC void emcore_free_option(email_option_t *option)
807 {
808         EM_SAFE_FREE(option->display_name_from);
809         EM_SAFE_FREE(option->signature);
810 }
811
812
813 INTERNAL_FUNC void emcore_free_account(email_account_t *account)
814 {
815         if (!account) return;
816
817         EM_SAFE_FREE(account->account_name);
818         EM_SAFE_FREE(account->logo_icon_path);
819         EM_SAFE_FREE(account->user_data);
820         account->user_data_length = 0;
821         EM_SAFE_FREE(account->user_display_name);
822         EM_SAFE_FREE(account->user_email_address);
823         EM_SAFE_FREE(account->reply_to_address);
824         EM_SAFE_FREE(account->return_address);
825         EM_SAFE_FREE(account->incoming_server_address);
826         EM_SAFE_FREE(account->incoming_server_user_name);
827         EM_SAFE_FREE(account->incoming_server_password);
828         EM_SAFE_FREE(account->outgoing_server_address);
829         EM_SAFE_FREE(account->outgoing_server_user_name);
830         EM_SAFE_FREE(account->outgoing_server_password);
831         emcore_free_option(&account->options);
832         EM_SAFE_FREE(account->certificate_path);
833
834         EM_DEBUG_FUNC_END();
835 }
836
837 INTERNAL_FUNC int emcore_duplicate_account_members(const email_account_t *input_account, email_account_t *output_account_dup)
838 {
839         memcpy(output_account_dup, input_account , sizeof(email_account_t));
840
841         output_account_dup->account_name                             = EM_SAFE_STRDUP(input_account->account_name);
842         output_account_dup->incoming_server_address                  = EM_SAFE_STRDUP(input_account->incoming_server_address);
843         output_account_dup->user_email_address                       = EM_SAFE_STRDUP(input_account->user_email_address);
844         output_account_dup->incoming_server_user_name                = EM_SAFE_STRDUP(input_account->incoming_server_user_name);
845         output_account_dup->incoming_server_password                 = EM_SAFE_STRDUP(input_account->incoming_server_password);
846         output_account_dup->outgoing_server_address                  = EM_SAFE_STRDUP(input_account->outgoing_server_address);
847         output_account_dup->outgoing_server_user_name                = EM_SAFE_STRDUP(input_account->outgoing_server_user_name);
848         output_account_dup->outgoing_server_password                 = EM_SAFE_STRDUP(input_account->outgoing_server_password);
849         output_account_dup->user_display_name                        = EM_SAFE_STRDUP(input_account->user_display_name);
850         output_account_dup->reply_to_address                         = EM_SAFE_STRDUP(input_account->reply_to_address);
851         output_account_dup->return_address                           = EM_SAFE_STRDUP(input_account->return_address);
852         output_account_dup->logo_icon_path                           = EM_SAFE_STRDUP(input_account->logo_icon_path);
853         output_account_dup->user_data                                = em_memdup(input_account->user_data, input_account->user_data_length);
854         output_account_dup->options.display_name_from                = EM_SAFE_STRDUP(input_account->options.display_name_from);
855         output_account_dup->options.signature                        = EM_SAFE_STRDUP(input_account->options.signature);
856         output_account_dup->certificate_path                         = EM_SAFE_STRDUP(input_account->certificate_path);
857
858         return EMAIL_ERROR_NONE;
859 }
860
861
862 INTERNAL_FUNC void emcore_duplicate_account(const email_account_t *account, email_account_t **account_dup, int *err_code)
863 {
864         EM_DEBUG_FUNC_BEGIN("account[%p]", account);
865
866         if (!account || !account_dup) { /*prevent 40514*/
867                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
868                 if (err_code) *err_code = EMAIL_ERROR_INVALID_PARAM;
869                 return;
870         }
871
872         *account_dup = em_malloc(sizeof(email_account_t));
873         if (!*account_dup) { /*prevent 40514*/
874                 EM_DEBUG_EXCEPTION("malloc failed...");
875                 if (err_code) *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
876                 return;
877         }
878
879         emcore_duplicate_account_members(account, *account_dup);
880
881         if (err_code != NULL)
882                 *err_code = EMAIL_ERROR_NONE;
883
884         EM_DEBUG_FUNC_END();
885 }
886
887 #ifdef __FEATURE_BACKUP_ACCOUNT__
888
889 static int append_data_into_buffer(char **target_buffer, int *target_buffer_lenth, char *input_data, int input_data_length, int *error_code)
890 {
891         EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], input_data [%p], input_data_length[%d]", target_buffer, target_buffer_lenth, input_data, input_data_length);
892         int local_error_code = EMAIL_ERROR_NONE, ret_code = false;
893
894         if (!target_buffer || !target_buffer_lenth || !input_data) {
895                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
896                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
897                 goto FINISH_OFF;
898         }
899
900         if (*target_buffer_lenth > 0 && input_data_length) {
901                 EM_DEBUG_LOG("*target_buffer_lenth [%d]", *target_buffer_lenth);
902                 *target_buffer = realloc(*target_buffer, (*target_buffer_lenth) + input_data_length);
903                 if (!*target_buffer) {
904                         EM_DEBUG_EXCEPTION("realloc failed");
905                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
906                         goto FINISH_OFF;
907                 }
908                 memcpy(*target_buffer + (*target_buffer_lenth), input_data, input_data_length);
909                 *target_buffer_lenth += input_data_length;
910                 EM_DEBUG_LOG("*target_buffer_lenth [%d] input_data_length [%d]", *target_buffer_lenth, input_data_length);
911         } else {
912                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
913                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
914                 goto FINISH_OFF;
915         }
916
917         ret_code = true;
918
919 FINISH_OFF:
920
921         if (error_code)
922                 *error_code = local_error_code;
923         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
924
925         return ret_code;
926 }
927
928
929 static int emcore_write_account_into_buffer(char **target_buffer, int *target_buffer_lenth, emstorage_account_tbl_t *account_tbl_ptr, int *error_code)
930 {
931         EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], account_tbl_ptr [%p], error_code [%p]", target_buffer, target_buffer_lenth, account_tbl_ptr, error_code);
932         int local_error_code = EMAIL_ERROR_NONE, ret_code = false, stream_length = 0;
933         email_account_t temp_account = {0};
934         char *byte_stream = NULL;
935
936         if (em_convert_account_tbl_to_account(account_tbl_ptr, &temp_account)) {
937                 byte_stream = em_convert_account_to_byte_stream(&temp_account, &stream_length);
938                 EM_DEBUG_LOG("stream_length [%d]", stream_length);
939                 /*  EM_DEBUG_LOG_SEC("incoming_server_password [%s]", temp_account->password) */
940
941                 if (byte_stream) {
942                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, (char *)&stream_length, sizeof(int), &local_error_code)) {
943                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
944                                 goto FINISH_OFF;
945                         }
946                         EM_DEBUG_LOG("append_data_into_buffer succeed for stream_length");
947
948                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, byte_stream, stream_length, &local_error_code)) {
949                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
950                                 goto FINISH_OFF;
951                         }
952                         EM_DEBUG_LOG("append_data_into_buffer succeed for byte_stream");
953                 }
954         } else {
955                 EM_DEBUG_EXCEPTION("em_convert_account_tbl_to_account failed");
956                 local_error_code = EMAIL_ERROR_SYSTEM_FAILURE;
957                 goto FINISH_OFF;
958         }
959
960         ret_code = true;
961 FINISH_OFF:
962         emcore_free_account(&temp_account);
963         if (error_code)
964                 *error_code = local_error_code;
965
966         EM_SAFE_FREE(byte_stream);
967
968         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
969         return ret_code;
970 }
971
972 INTERNAL_FUNC int emcore_backup_accounts(char *multi_user_name, const char *file_path, int *error_code)
973 {
974         EM_DEBUG_LOG("file_path [%s], error_code [%p]", file_path, error_code);
975         int local_error_code = EMAIL_ERROR_NONE, local_error_code_2 = EMAIL_ERROR_NONE, ret_code = false;
976         int select_num, i, target_buff_length = 0;
977         int normal_email_account_count = 0;
978         char *target_buffer = NULL;
979         unsigned char *output_data = NULL;
980         emstorage_account_tbl_t *account_list = NULL;
981         int fd = -1;
982
983         if (!file_path) {
984                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
985                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
986                 goto FINISH_OFF;
987         }
988
989         select_num = 1000;
990
991         if (!emstorage_get_account_list(multi_user_name, &select_num, &account_list, true, true, &local_error_code)) {
992                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", local_error_code);
993                 goto FINISH_OFF;
994         }
995
996         EM_DEBUG_LOG("select_num [%d]", select_num);
997
998         if (account_list) {
999                 for (i = 0; i < select_num; i++) {
1000                         if (account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3 || account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)
1001                                 normal_email_account_count++;
1002                 }
1003         }
1004
1005         EM_DEBUG_LOG("normal_email_account_count [%d]", normal_email_account_count);
1006
1007         if (normal_email_account_count == 0) {
1008                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_ACCOUNT_NOT_FOUND");
1009                 local_error_code = EMAIL_ERROR_ACCOUNT_NOT_FOUND;
1010                 goto FINISH_OFF;
1011         } else {
1012                 target_buffer = em_malloc(sizeof(int));
1013                 if (!target_buffer)  {
1014                         EM_DEBUG_EXCEPTION("malloc failed");
1015                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
1016                         goto FINISH_OFF;
1017                 }
1018
1019                 memcpy(target_buffer, (char *)&normal_email_account_count, sizeof(int));
1020                 target_buff_length = sizeof(int);
1021
1022                 for (i = 0; i < select_num; i++) {
1023                         if (account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3 || account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) {
1024                                 if (!emcore_write_account_into_buffer(&target_buffer, &target_buff_length, account_list + i, &local_error_code)) {
1025                                         EM_DEBUG_EXCEPTION("emcore_write_account_into_buffer failed [%d]", local_error_code);
1026                                         goto FINISH_OFF;
1027                                 }
1028                         }
1029                 }
1030
1031                 EM_DEBUG_LOG("target_buff_length [%d]", target_buff_length);
1032
1033                 local_error_code = em_open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR, &fd);
1034                 if (local_error_code != EMAIL_ERROR_NONE) {
1035                                 EM_DEBUG_EXCEPTION("em_open failed - %d [%s] : ", local_error_code, file_path);
1036                                 goto FINISH_OFF;
1037                 }
1038
1039
1040                 int tmp = emcore_check_key_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY);
1041
1042                         if (tmp == EMAIL_ERROR_KEY_NOT_FOUND){
1043                                         EM_DEBUG_LOG("Key not exist");
1044
1045                                         int ret = 0;
1046
1047                                         ret = emcore_save_key_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY);
1048
1049                                         if(ret != EMAIL_ERROR_NONE){
1050                                                 EM_DEBUG_EXCEPTION("save key failed %d", ret);
1051                                                 goto FINISH_OFF;
1052                                         }
1053
1054                         } else if (tmp == EMAIL_ERROR_INVALID_PARAM) {
1055
1056                                 EM_DEBUG_EXCEPTION("Invalid parameter");
1057                                 goto FINISH_OFF;
1058
1059                         }
1060                 int output_length = 0;
1061                 emcore_encryption_data_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY, target_buffer, target_buff_length, &output_data, &output_length);
1062
1063                 EM_DEBUG_LOG("output length %d", output_length);
1064                 int write_length = write(fd, (char *)output_data, output_length);
1065                 EM_DEBUG_LOG("write length : %d", write_length);
1066
1067         }
1068
1069         ret_code = true;
1070 FINISH_OFF:
1071
1072         EM_SAFE_CLOSE(fd);
1073         EM_SAFE_FREE(target_buffer);
1074         EM_SAFE_FREE(output_data);
1075
1076         if (account_list)
1077                 emstorage_free_account(&account_list, select_num, &local_error_code_2);
1078
1079         if (error_code)
1080                 *error_code = local_error_code;
1081
1082         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1083         return ret_code;
1084 }
1085
1086 INTERNAL_FUNC int emcore_restore_accounts(char *multi_user_name, const char *file_path)
1087 {
1088         EM_DEBUG_FUNC_BEGIN_SEC("file_path [%s]", file_path);
1089         int err = EMAIL_ERROR_NONE;
1090         int account_count = 0, i = 0, account_stream_length = 0;
1091         char *temp_buffer = NULL, *account_stream = NULL, *buffer_ptr = NULL;
1092         email_account_t temp_account = {0};
1093         email_account_t *account_list = NULL;
1094         char *encrypt_buffer = NULL;
1095
1096
1097         if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_START, 0, 0, NULL, 0))
1098                 EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_START] failed");
1099
1100         if (!file_path) {
1101                 err = EMAIL_ERROR_INVALID_PARAM;
1102                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1103                 goto FINISH_OFF;
1104         }
1105
1106         if ((err = emcore_get_account_reference_list(multi_user_name, &account_list, &account_count)) == EMAIL_ERROR_NONE) {
1107                 for (i = 0; i < account_count; i++) {
1108                         if (account_list[i].incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
1109                                 if (!emcore_delete_account(multi_user_name, account_list[i].account_id, true, &err)) {
1110                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed [%d]", err);
1111                                         goto FINISH_OFF;
1112                                 }
1113                         }
1114                 }
1115
1116                 if (account_list) {
1117                         emcore_free_account_list(&account_list, account_count, NULL);
1118                         account_list = NULL;
1119                 }
1120         }
1121
1122         int output_length = 0;
1123         char *output_data = NULL;
1124
1125         emcore_decryption_data_from_file_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY, file_path, &output_data, &output_length);
1126
1127         if (output_length > 0) {
1128                 memcpy((void *)&account_count, output_data, sizeof(int));
1129                 buffer_ptr = output_data + sizeof(int);
1130
1131                 EM_DEBUG_LOG("account_count[%d]", account_count);
1132
1133                 for (i = 0; i < account_count; i++) {
1134                         memcpy((void *)&account_stream_length, buffer_ptr, sizeof(int));
1135                         buffer_ptr += sizeof(int);
1136                         EM_DEBUG_LOG("account_stream_length [%d]", account_stream_length);
1137                         if (account_stream_length) {
1138                                 account_stream = em_malloc(account_stream_length);
1139                                 if (!account_stream) {
1140                                         EM_DEBUG_EXCEPTION("em_malloc() failed.");
1141                                         err = EMAIL_ERROR_OUT_OF_MEMORY ;
1142                                         goto FINISH_OFF;
1143                                 }
1144                                 memcpy(account_stream, buffer_ptr, account_stream_length);
1145
1146                                 em_convert_byte_stream_to_account(account_stream, account_stream_length, &temp_account);
1147                                 EM_SAFE_FREE(account_stream);
1148
1149
1150
1151                                 if ((emstorage_check_duplicated_account(multi_user_name,
1152                                                                                                                 &temp_account,
1153                                                                                                                 true,
1154                                                                                                                 &err) == false) && (err = EMAIL_ERROR_ALREADY_EXISTS)) {
1155                                         EM_DEBUG_EXCEPTION("An account is duplicated. ");
1156                                         buffer_ptr += account_stream_length;
1157                                         account_stream_length = 0;
1158                                         emcore_free_account(&temp_account);
1159                                         err = EMAIL_ERROR_NONE;
1160                                         continue;
1161                                 }
1162
1163                                 if (!emcore_create_account(multi_user_name, &temp_account, true, &err)) {
1164                                         EM_DEBUG_EXCEPTION("emcore_create_account() failed. [%d]", err);
1165                                         goto FINISH_OFF;
1166                                 }
1167
1168                                 emcore_free_account(&temp_account);
1169                         }
1170                         buffer_ptr += account_stream_length;
1171                         account_stream_length = 0;
1172                 }
1173         } else {
1174                 EM_DEBUG_EXCEPTION("ssm_read() failed.");
1175                 err = EMAIL_ERROR_SYSTEM_FAILURE;
1176                 goto FINISH_OFF;
1177         }
1178
1179 FINISH_OFF:
1180 #ifdef FEATURE_SSS_ENABLE
1181         EM_SAFE_CLOSE(fd);
1182 #endif
1183
1184         if (err == EMAIL_ERROR_NONE) {
1185                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_FINISH, 0, 0, NULL, err))
1186                         EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_FINISH] failed");
1187         } else {
1188                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_FAIL, 0, 0, NULL, err))
1189                         EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_FAIL] failed");
1190         }
1191
1192         if (account_list) {
1193                 emcore_free_account_list(&account_list, account_count, NULL);
1194                 account_list = NULL;
1195         }
1196         emcore_free_account(&temp_account);
1197         EM_SAFE_FREE(account_stream);
1198         EM_SAFE_FREE(temp_buffer);
1199         EM_SAFE_FREE(encrypt_buffer);
1200         EM_SAFE_FREE(output_data);
1201
1202         EM_DEBUG_FUNC_END("err [%d]", err);
1203         return err;
1204 }
1205
1206 #endif /*  __FEATURE_BACKUP_ACCOUNT_ */
1207
1208 INTERNAL_FUNC int emcore_save_default_account_id(char *multi_user_name, int input_account_id)
1209 {
1210         EM_DEBUG_FUNC_BEGIN("account_id [%d]", input_account_id);
1211         int ret_code = EMAIL_ERROR_NONE, result_value = 0;
1212
1213         result_value = vconf_set_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, input_account_id);
1214         if (result_value < 0) {
1215                 EM_DEBUG_EXCEPTION("vconf_set_int failed [%d]", result_value);
1216                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1217         }
1218
1219         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1220         return ret_code;
1221 }
1222
1223 static int _recover_from_invalid_default_account_id(char *multi_user_name, int *output_account_id)
1224 {
1225         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1226         int ret_code = EMAIL_ERROR_NONE;
1227         int account_count = 100;
1228         emstorage_account_tbl_t *result_account_list = NULL;
1229
1230         if (output_account_id == NULL) {
1231                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1232                 goto FINISH_OFF;
1233         }
1234
1235         if (!emstorage_get_account_list(multi_user_name, &account_count, &result_account_list, false, false, &ret_code) || !result_account_list) {
1236                 if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND)
1237                         EM_DEBUG_LOG("no account found");
1238                 else
1239                         EM_DEBUG_EXCEPTION("emstorage_get_account_list() failed [%d]", ret_code);
1240                 *output_account_id = 0;
1241                 goto FINISH_OFF;
1242         }
1243
1244         if (account_count > 0) {
1245                 *output_account_id = result_account_list[0].account_id;
1246         }
1247
1248         EM_DEBUG_LOG_DEV("output_account_id [%d]", *output_account_id);
1249
1250 FINISH_OFF:
1251
1252         if (result_account_list)
1253                 emstorage_free_account(&result_account_list, account_count, NULL);
1254
1255         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1256         return ret_code;
1257 }
1258
1259 INTERNAL_FUNC int emcore_load_default_account_id(char *multi_user_name, int *output_account_id)
1260 {
1261         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1262         int ret_code = EMAIL_ERROR_NONE;
1263         int result_value = 0;
1264         emstorage_account_tbl_t *result_account = NULL;
1265
1266         if (output_account_id == NULL) {
1267                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1268                 goto FINISH_OFF;
1269         }
1270
1271         result_value = vconf_get_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, output_account_id);
1272
1273         if (result_value < 0) {
1274                 EM_DEBUG_EXCEPTION("vconf_get_int() failed [%d]", result_value);
1275                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1276                 *output_account_id = 0;
1277         }
1278
1279         if (*output_account_id != 0) {
1280                 if (!emstorage_get_account_by_id(multi_user_name, *output_account_id, EMAIL_ACC_GET_OPT_DEFAULT, &result_account, false, &ret_code)) {
1281                         if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND) {
1282                                 EM_DEBUG_LOG("no account found account_id[%d]", *output_account_id);
1283                                 *output_account_id = 0;
1284                         } else {
1285                                 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id() failed account_id[%d] err[%d]", *output_account_id, ret_code);
1286                                 goto FINISH_OFF;
1287                         }
1288                 }
1289         }
1290
1291         if (*output_account_id == 0) {
1292                 if ((ret_code = _recover_from_invalid_default_account_id(multi_user_name, output_account_id)) != EMAIL_ERROR_NONE) {
1293                         if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND)
1294                                 EM_DEBUG_LOG("no account found");
1295                         else
1296                                 EM_DEBUG_EXCEPTION("_recover_from_invalid_default_account() failed [%d]", ret_code);
1297                         *output_account_id = 0;
1298                 }
1299         }
1300
1301 FINISH_OFF:
1302         if (result_account)
1303                 emstorage_free_account(&result_account, 1, NULL);
1304
1305         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1306         return ret_code;
1307 }
1308
1309 INTERNAL_FUNC int emcore_recover_from_secured_storage_failure(char *multi_user_name)
1310 {
1311         EM_DEBUG_FUNC_BEGIN();
1312         int err = EMAIL_ERROR_NONE;
1313         int i = 0;
1314         int account_count = 50;
1315         emstorage_account_tbl_t *temp_account_tbl_list = NULL;
1316         emstorage_account_tbl_t *temp_account_tbl      = NULL;
1317
1318         if (!emstorage_get_account_list(multi_user_name, &account_count, &temp_account_tbl_list, true, false, &err)) {
1319                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", err);
1320                 goto FINISH_OFF;
1321         }
1322
1323         for (i = 0; i < account_count; i++) {
1324                 if (!emstorage_get_account_by_id(multi_user_name, temp_account_tbl_list[i].account_id, EMAIL_ACC_GET_OPT_DEFAULT | EMAIL_ACC_GET_OPT_PASSWORD, &temp_account_tbl, true, &err)) {
1325                         if (err == EMAIL_ERROR_SECURED_STORAGE_FAILURE) {
1326                                 if (!emcore_delete_account(multi_user_name, temp_account_tbl_list[i].account_id, true, &err)) {
1327                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed [%d]", err);
1328                                         goto FINISH_OFF;
1329                                 }
1330                         }
1331                 }
1332         }
1333
1334 FINISH_OFF:
1335
1336         emstorage_free_account(&temp_account_tbl_list, account_count, NULL);
1337         emstorage_free_account(&temp_account_tbl, 1, NULL);
1338
1339         EM_DEBUG_FUNC_END("err [%d]", err);
1340         return err;
1341 }
1342
1343 INTERNAL_FUNC int emcore_update_sync_status_of_account(char *multi_user_name, int input_account_id, email_set_type_t input_set_operator, int input_sync_status)
1344 {
1345         EM_DEBUG_FUNC_BEGIN("input_account_id [%d], input_set_operator [%d], input_sync_status [%d]", input_account_id, input_set_operator, input_sync_status);
1346         int err = EMAIL_ERROR_NONE;
1347
1348 #ifdef __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__
1349         int err_from_account_svc = 0;
1350         emstorage_account_tbl_t *account_tbl_data = NULL;
1351         void *join_zone = NULL;
1352
1353         if (input_account_id != ALL_ACCOUNT && (input_sync_status == SYNC_STATUS_SYNCING)) {
1354                 if (!emstorage_get_account_by_id(multi_user_name, input_account_id, EMAIL_ACC_GET_OPT_DEFAULT | EMAIL_ACC_GET_OPT_OPTIONS, &account_tbl_data, true, &err)) {
1355                         EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed [%d]", err);
1356                         goto FINISH_OFF;
1357                 }
1358
1359                 if (EM_SAFE_STRLEN(multi_user_name) > 0) {
1360                         err = emcore_set_join_zone(multi_user_name, &join_zone);
1361                         if (err != EMAIL_ERROR_NONE) {
1362                                 EM_DEBUG_EXCEPTION("emcore_set_join_zone failed : [%d]", err);
1363                                 goto FINISH_OFF;
1364                         }
1365                 }
1366
1367                 if (input_set_operator == SET_TYPE_SET)
1368                         err_from_account_svc = account_update_sync_status_by_id(account_tbl_data->account_svc_id, ACCOUNT_SYNC_STATUS_RUNNING);
1369                 else if (input_set_operator == SET_TYPE_MINUS)
1370                         err_from_account_svc = account_update_sync_status_by_id(account_tbl_data->account_svc_id, ACCOUNT_SYNC_STATUS_IDLE);
1371
1372                 EM_DEBUG_LOG("account_update_sync_status_by_id returns [%d] by id[%d]", err_from_account_svc, account_tbl_data->account_svc_id);
1373
1374                 emcore_unset_join_zone(join_zone);
1375         }
1376 #endif /* __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__ */
1377
1378         if (!emstorage_update_sync_status_of_account(multi_user_name, input_account_id, input_set_operator, input_sync_status, true, &err))
1379                 EM_DEBUG_EXCEPTION("emstorage_update_sync_status_of_account failed [%d]", err);
1380
1381 #ifdef __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__
1382 FINISH_OFF:
1383         if (account_tbl_data)
1384                 emstorage_free_account(&account_tbl_data, 1, NULL);
1385 #endif /* __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__ */
1386
1387         EM_DEBUG_FUNC_END("err [%d]", err);
1388         return err;
1389 }
1390
1391 #define GOOGLE_PIM_SYNC_GET_TOKEN_URL "https://accounts.google.com/o/oauth2/token"
1392 #define GOOGLE_PIM_SYNC_CLIENT_ID     "233916860221.apps.googleusercontent.com"
1393 #define GOOGLE_PIM_SYNC_CLIENT_SECRET "dI8wRLGMJ16Ioxfl8KaujmuU"
1394 #define CALCURL_TIMEOUT               30
1395
1396 int emcore_curl_progress_callback(void *p, double dtot, double dnow, double utot, double unow)
1397 {
1398         EM_DEBUG_LOG("%0.0lf %0.0lf %0.0lf %0.0lf", dtot, dnow, utot, unow);
1399         return 0;
1400 }
1401
1402 size_t emcore_curl_write_callback(char* data, size_t size, size_t nmemb, void* target)
1403 {
1404         EM_DEBUG_FUNC_BEGIN("data[%p] size[%d] nmemb[%d] target[%p]", data, size, nmemb, target);
1405         int last_pos = 0;
1406         char **result_string = (char**)target;
1407         size_t received_length = size * nmemb;
1408
1409         if (*result_string == NULL) {
1410                 EM_DEBUG_LOG("received_length[%zu]", received_length);
1411                 *result_string = em_malloc(received_length + 1);
1412         } else {
1413                 int new_buffer_length = 0;
1414                 last_pos = EM_SAFE_STRLEN(*result_string);
1415                 new_buffer_length = last_pos + received_length + 1;
1416                 EM_DEBUG_LOG("new_buffer_length[%d]", new_buffer_length);
1417
1418                 char *new_result_string = NULL;
1419                 new_result_string = realloc(*result_string, new_buffer_length);
1420                 if (NULL == new_result_string) {
1421                         EM_DEBUG_EXCEPTION("memory reallocation failed");
1422                         EM_SAFE_FREE(*result_string);
1423                         received_length = 0;
1424                         goto FINISH_OFF;
1425                 }
1426
1427                 *result_string = new_result_string;
1428         }
1429
1430         if (*result_string == NULL) {
1431                 EM_DEBUG_EXCEPTION("memory allocation failed");
1432                 received_length = 0;
1433                 goto FINISH_OFF;
1434         }
1435
1436         memcpy(*result_string + last_pos, data, received_length);
1437         /*EM_DEBUG_LOG_SEC("result_string[%s]", *result_string);*/
1438
1439 FINISH_OFF:
1440         EM_DEBUG_FUNC_END("received_length [%d]", received_length);
1441         return received_length;
1442 }
1443
1444 static int emcore_get_xoauth2_access_token(char *input_refresh_token, char **output_access_token)
1445 {
1446         EM_DEBUG_FUNC_BEGIN("input_refresh_token [%p] output_access_token [%p]", input_refresh_token, output_access_token);
1447         int err = EMAIL_ERROR_NONE;
1448
1449         CURL *curl = NULL;
1450         CURLcode curl_ressult_code;
1451         char *result_string = NULL;
1452         char *pos = NULL;
1453         char *savepos = NULL;
1454         char *access_token = NULL;
1455         long response_code;
1456         double speed_upload, total_time, download_size;
1457
1458         if (input_refresh_token == NULL || output_access_token == NULL) {
1459                 EM_DEBUG_EXCEPTION("curl_easy_init() failed");
1460                 err = EMAIL_ERROR_INVALID_PARAM;
1461                 goto FINISH_OFF;
1462         }
1463
1464         curl = curl_easy_init();
1465         if (NULL == curl) {
1466                 EM_DEBUG_EXCEPTION("curl_easy_init() failed");
1467                 err = EMAIL_ERROR_SYSTEM_FAILURE;
1468                 goto FINISH_OFF;
1469         }
1470
1471         char buf[1024] = {0};
1472         snprintf(buf, sizeof(buf),
1473                                 "client_id=%s&"
1474                                 "client_secret=%s&"
1475                                 "refresh_token=%s&"
1476                                 "grant_type=refresh_token",
1477                                 GOOGLE_PIM_SYNC_CLIENT_ID,
1478                                 GOOGLE_PIM_SYNC_CLIENT_SECRET,
1479                                 input_refresh_token);
1480         curl_easy_setopt(curl, CURLOPT_URL, GOOGLE_PIM_SYNC_GET_TOKEN_URL);
1481         curl_easy_setopt(curl, CURLOPT_POST, 1);
1482         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
1483         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
1484         curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CALCURL_TIMEOUT);
1485         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
1486         curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
1487         curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, emcore_curl_progress_callback);
1488         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, emcore_curl_write_callback);
1489         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&result_string);
1490         curl_easy_setopt(curl, CURLOPT_HEADER, true);
1491
1492         /* pinning */
1493         curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, tpkp_curl_ssl_ctx_callback);
1494
1495         curl_ressult_code = curl_easy_perform(curl);
1496
1497         EM_DEBUG_LOG_SEC("CURLcode: %d (%s)", curl_ressult_code, curl_easy_strerror(curl_ressult_code));
1498
1499         if (0 == curl_ressult_code) {
1500                 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
1501                 curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD,  &speed_upload);
1502                 curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME,    &total_time);
1503                 curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
1504
1505                 EM_DEBUG_LOG("Speed: %.3f bytes/sec during %.3f seconds", speed_upload, total_time);
1506                 EM_DEBUG_LOG("response code = %ld , length = %.3f", response_code, download_size);
1507         }
1508
1509         if (result_string == NULL) {
1510                 EM_DEBUG_EXCEPTION("Getting result string failed");
1511                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1512                 goto FINISH_OFF;
1513         }
1514
1515         if (strstr(result_string, "error")) {
1516                 if (strstr(result_string, "\"invalid_grant\""))
1517                         err = EMAIL_ERROR_XOAUTH_INVALID_GRANT;
1518                 else
1519                         err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1520                 goto FINISH_OFF;
1521         }
1522
1523         pos = strstr(result_string, "\"access_token\" : \"");
1524
1525         if (!pos) {
1526                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1527                 goto FINISH_OFF;
1528         }
1529
1530         pos = pos + strlen("\"access_token\" : \"");
1531
1532         access_token = strtok_r(pos, "\"", &savepos);
1533
1534         if (access_token) {
1535                 *output_access_token = EM_SAFE_STRDUP(access_token);
1536
1537                 if (*output_access_token == NULL) {
1538                         EM_DEBUG_EXCEPTION("strdup failed");
1539                         err = EMAIL_ERROR_SYSTEM_FAILURE;
1540                         goto FINISH_OFF;
1541                 }
1542         }
1543
1544 FINISH_OFF:
1545
1546         EM_SAFE_FREE(result_string);
1547
1548         if (curl)
1549                 curl_easy_cleanup(curl);
1550
1551         tpkp_curl_cleanup();
1552
1553         EM_DEBUG_FUNC_END("err [%d]", err);
1554         return err;
1555 }
1556
1557 INTERNAL_FUNC int emcore_refresh_xoauth2_access_token(char *multi_user_name, int input_account_id)
1558 {
1559         EM_DEBUG_FUNC_BEGIN("input_account_id [%d]", input_account_id);
1560         int err = EMAIL_ERROR_NONE;
1561         int new_password_string_length = 0;
1562         char *access_token = NULL;
1563         char *refresh_token = NULL;
1564         char *new_access_token = NULL;
1565         char *new_password_string = NULL;
1566         char *saveptr = NULL;
1567         email_account_t *ref_account = NULL;
1568
1569
1570         ref_account = emcore_get_account_reference(multi_user_name, input_account_id, true);
1571         if (ref_account == NULL) {
1572                 EM_DEBUG_EXCEPTION("emcore_get_account_reference() failed");
1573                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1574                 goto FINISH_OFF;
1575         }
1576
1577         access_token = EM_SAFE_STRDUP(strtok_r(ref_account->incoming_server_password, "\001", &saveptr));
1578         if (access_token == NULL) {
1579                 EM_DEBUG_EXCEPTION("invalid token string.");
1580                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1581                 goto FINISH_OFF;
1582         }
1583
1584         EM_DEBUG_LOG_SEC("access_token [%s]", access_token);
1585
1586         refresh_token = EM_SAFE_STRDUP(strtok_r(NULL, "\001", &saveptr));
1587
1588         if (refresh_token == NULL) {
1589                 EM_DEBUG_EXCEPTION("invalid token string.");
1590                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1591                 goto FINISH_OFF;
1592         }
1593
1594         EM_DEBUG_LOG_SEC("refresh_token [%s]", refresh_token);
1595
1596         if ((err = emcore_get_xoauth2_access_token(refresh_token, &new_access_token)) != EMAIL_ERROR_NONE) {
1597                 EM_DEBUG_EXCEPTION("emcore_get_xoauth2_access_token() failed [%d]", err);
1598                 goto FINISH_OFF;
1599         }
1600
1601         new_password_string_length = EM_SAFE_STRLEN(new_access_token) + EM_SAFE_STRLEN(refresh_token) + 2;
1602
1603         new_password_string = em_malloc(new_password_string_length);
1604         if (new_password_string == NULL) {
1605                 EM_DEBUG_EXCEPTION("em_malloc() failed");
1606                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1607                 goto FINISH_OFF;
1608         }
1609
1610         SNPRINTF(new_password_string, new_password_string_length, "%s\001%s", new_access_token, refresh_token);
1611
1612         if ((err = emstorage_update_account_password(multi_user_name, input_account_id, new_password_string, new_password_string)) != EMAIL_ERROR_NONE) {
1613                 EM_DEBUG_EXCEPTION("emstorage_update_account_password() failed [%d]", err);
1614                 goto FINISH_OFF;
1615         }
1616
1617 FINISH_OFF:
1618
1619         EM_SAFE_FREE(access_token);
1620         EM_SAFE_FREE(refresh_token);
1621         EM_SAFE_FREE(new_access_token);
1622         EM_SAFE_FREE(new_password_string);
1623
1624         if (ref_account) {
1625                 emcore_free_account(ref_account);
1626                 EM_SAFE_FREE(ref_account);
1627         }
1628
1629         EM_DEBUG_FUNC_END("err [%d]", err);
1630         return err;
1631 }