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