Coverity issue fixes for email service
[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                 account->options.alert_ringtone_path = EM_SAFE_STRDUP(vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR));
620         }
621
622         if (add_account_to_account_svc) {
623                 if (account->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
624                         int account_svc_id = 0;
625                         int error_code = 0;
626                         account_h account_handle = NULL;
627                         void *join_zone = NULL;
628
629                         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
630                                 err = emcore_set_join_zone(multi_user_name, &join_zone);
631                                 if (err != EMAIL_ERROR_NONE) {
632                                         EM_DEBUG_EXCEPTION("emcore_set_join_zone failed : [%d]", err);
633                                         goto FINISH_OFF;
634                                 }
635                         }
636
637
638                         error_code = account_create(&account_handle);
639                         if (error_code != ACCOUNT_ERROR_NONE) {
640                                 EM_DEBUG_EXCEPTION("account_create failed [%d]", error_code);
641                                 err = error_code;
642                                 if (join_zone) emcore_unset_join_zone(join_zone);
643                                 goto FINISH_OFF;
644                         }
645
646                         error_code = account_set_user_name(account_handle, account->incoming_server_user_name);
647                         if (error_code != ACCOUNT_ERROR_NONE) {
648                                 EM_DEBUG_LOG("account_set_user_name failed [%d]", error_code);
649                         }
650
651                         error_code = account_set_domain_name(account_handle, account->account_name);
652                         if (error_code != ACCOUNT_ERROR_NONE) {
653                                 EM_DEBUG_LOG("account_set_domain_name failed [%d]", error_code);
654                         }
655
656                         error_code = account_set_email_address(account_handle,  account->user_email_address);
657                         if (error_code != ACCOUNT_ERROR_NONE) {
658                                 EM_DEBUG_LOG("account_set_email_address failed [%d]", error_code);
659                         }
660
661                         error_code = account_set_source(account_handle, "SLP EMAIL");
662                         if (error_code != ACCOUNT_ERROR_NONE) {
663                                 EM_DEBUG_LOG("account_set_source failed [%d]", error_code);
664                         }
665
666                         error_code = account_set_package_name(account_handle, "email-setting-efl");
667                         if (error_code != ACCOUNT_ERROR_NONE) {
668                                 EM_DEBUG_LOG("account_set_package_name failed [%d]", error_code);
669                         }
670
671                         /* account_set_capability(account_handle , ACCOUNT_CAPABILITY_EMAIL, ACCOUNT_CAPABILITY_ENABLED); OLD API */
672                         error_code = account_set_capability(account_handle , ACCOUNT_SUPPORTS_CAPABILITY_EMAIL , ACCOUNT_CAPABILITY_ENABLED);
673                         if (error_code != ACCOUNT_ERROR_NONE) {
674                                 EM_DEBUG_LOG("account_set_capability failed [%d]", error_code);
675                         }
676
677                         error_code = account_set_sync_support(account_handle, ACCOUNT_SYNC_STATUS_IDLE); /* This means "The account is supporting 'sync' and initialized as idle status" */
678                         if (error_code != ACCOUNT_ERROR_NONE) {
679                                 EM_DEBUG_LOG("account_set_sync_support failed [%d]", error_code);
680                         }
681
682                         if (account->logo_icon_path) {
683                                 error_code = account_set_icon_path(account_handle, account->logo_icon_path);
684                                 if (error_code != ACCOUNT_ERROR_NONE) {
685                                         EM_DEBUG_LOG("account_set_icon_path failed [%d]", error_code);
686                                 }
687                         }
688
689                         error_code = account_insert_to_db(account_handle, &account_svc_id);
690                         if (error_code != ACCOUNT_ERROR_NONE) {
691                                 EM_DEBUG_EXCEPTION("account_insert_to_db failed [%d]", error_code);
692                         } else {
693                                 account->account_svc_id = account_svc_id;
694                                 EM_DEBUG_LOG("account_insert_to_db succeed");
695                         }
696
697                         if (account_handle)
698                                 account_destroy(account_handle);
699
700                         if (join_zone) emcore_unset_join_zone(join_zone);
701                 }
702         }
703
704         temp_account_tbl = em_malloc(sizeof(emstorage_account_tbl_t));
705         if (!temp_account_tbl) {
706                 EM_DEBUG_EXCEPTION("allocation failed [%d]", err);
707                 goto FINISH_OFF;
708         }
709
710         em_convert_account_to_account_tbl(account, temp_account_tbl);
711
712         if (!emstorage_add_account(multi_user_name, temp_account_tbl, true, &err))  {
713                 EM_DEBUG_EXCEPTION("emstorage_add_account failed - %d", err);
714                 goto FINISH_OFF;
715         }
716         account->account_id = temp_account_tbl->account_id;
717
718         if (account->incoming_server_type == EMAIL_SERVER_TYPE_POP3) {
719                 /* 1. create default local mailbox
720                 *    (Inbox, Draft, Outbox, Sentbox) */
721                 for (i = 0; i < MAILBOX_COUNT; i++) {
722                         EM_DEBUG_LOG_SEC("g_default_mbox_name [%d/%d] is [%s]", i, MAILBOX_COUNT, g_default_mbox_name[i]);
723                         local_mailbox.account_id      = temp_account_tbl->account_id;
724                         local_mailbox.mailbox_name    = EM_SAFE_STRDUP(g_default_mbox_name[i]);
725                         local_mailbox.alias           = EM_SAFE_STRDUP(g_default_mbox_alias[i]);
726                         local_mailbox.mailbox_type    = g_default_mbox_type[i];
727                         local_mailbox.mail_slot_size  = temp_account_tbl->default_mail_slot_size;
728                         local_mailbox.eas_data        = NULL;
729                         local_mailbox.eas_data_length = 0;
730
731                         if (local_mailbox.mailbox_type == EMAIL_MAILBOX_TYPE_INBOX)
732                                 local_mailbox.local = EMAIL_MAILBOX_FROM_SERVER;
733                         else
734                                 local_mailbox.local = EMAIL_MAILBOX_FROM_LOCAL;
735
736                         if (!emcore_create_mailbox(multi_user_name, &local_mailbox, 0, account->incoming_server_type, account->default_mail_slot_size, &err)) {
737                                 EM_DEBUG_EXCEPTION("emcore_create failed [%d]", err);
738                                 emcore_free_mailbox(&local_mailbox);
739                                 goto FINISH_OFF;
740                         }
741
742                         emcore_free_mailbox(&local_mailbox);
743                 }
744         }
745
746         /* Initialize the noti private id */
747         SNPRINTF(vconf_private_id, sizeof(vconf_private_id), "%s/%d", VCONF_KEY_NOTI_PRIVATE_ID, account->account_id);
748         if (vconf_get_int(vconf_private_id, &private_id) != 0) {
749                 EM_DEBUG_EXCEPTION("vconf_get_int failed");
750         } else {
751                 if (vconf_set_int(vconf_private_id, 0) != 0) {
752                         EM_DEBUG_EXCEPTION("vconf_set_int failed : [NOTI key initialize]");
753                 }
754         }
755
756         ret = true;
757
758 FINISH_OFF:
759         if (temp_account_tbl)
760                 emstorage_free_account(&temp_account_tbl, 1, NULL);
761
762         if (ret == false && account != NULL)  {
763                 if (!emcore_delete_account(multi_user_name, account->account_id, false, NULL))
764                         EM_DEBUG_EXCEPTION("emdaemon_delete_account Failed [%d]", account->account_id);
765         }
766
767         if (err_code)
768                 *err_code = err;
769
770         EM_DEBUG_FUNC_END("Return value [%d]", ret);
771         return ret;
772 }
773
774 INTERNAL_FUNC int emcore_free_account_list(email_account_t **account_list, int count, int *err_code)
775 {
776         EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%d], err_code[%p]", account_list, count, err_code);
777
778         int ret = false;
779         int err = EMAIL_ERROR_NONE;
780
781         if (count <= 0 || !account_list || !*account_list) {
782                 err = EMAIL_ERROR_INVALID_PARAM;
783                 goto FINISH_OFF;
784         }
785
786         email_account_t *p = *account_list;
787         int i;
788         for (i = 0; i < count; i++)
789                 emcore_free_account(p+i);
790
791         EM_SAFE_FREE(p);
792         *account_list = NULL;
793
794         ret = true;
795
796 FINISH_OFF:
797         if (err_code)
798                 *err_code = err;
799         EM_DEBUG_FUNC_END();
800         return ret;
801 }
802
803 INTERNAL_FUNC void emcore_free_option(email_option_t *option)
804 {
805         EM_SAFE_FREE(option->display_name_from);
806         EM_SAFE_FREE(option->signature);
807 }
808
809
810 INTERNAL_FUNC void emcore_free_account(email_account_t *account)
811 {
812         if (!account) return;
813
814         EM_SAFE_FREE(account->account_name);
815         EM_SAFE_FREE(account->logo_icon_path);
816         EM_SAFE_FREE(account->user_data);
817         account->user_data_length = 0;
818         EM_SAFE_FREE(account->user_display_name);
819         EM_SAFE_FREE(account->user_email_address);
820         EM_SAFE_FREE(account->reply_to_address);
821         EM_SAFE_FREE(account->return_address);
822         EM_SAFE_FREE(account->incoming_server_address);
823         EM_SAFE_FREE(account->incoming_server_user_name);
824         EM_SAFE_FREE(account->incoming_server_password);
825         EM_SAFE_FREE(account->outgoing_server_address);
826         EM_SAFE_FREE(account->outgoing_server_user_name);
827         EM_SAFE_FREE(account->outgoing_server_password);
828         emcore_free_option(&account->options);
829         EM_SAFE_FREE(account->certificate_path);
830
831         EM_DEBUG_FUNC_END();
832 }
833
834 INTERNAL_FUNC int emcore_duplicate_account_members(const email_account_t *input_account, email_account_t *output_account_dup)
835 {
836         memcpy(output_account_dup, input_account , sizeof(email_account_t));
837
838         output_account_dup->account_name                             = EM_SAFE_STRDUP(input_account->account_name);
839         output_account_dup->incoming_server_address                  = EM_SAFE_STRDUP(input_account->incoming_server_address);
840         output_account_dup->user_email_address                       = EM_SAFE_STRDUP(input_account->user_email_address);
841         output_account_dup->incoming_server_user_name                = EM_SAFE_STRDUP(input_account->incoming_server_user_name);
842         output_account_dup->incoming_server_password                 = EM_SAFE_STRDUP(input_account->incoming_server_password);
843         output_account_dup->outgoing_server_address                  = EM_SAFE_STRDUP(input_account->outgoing_server_address);
844         output_account_dup->outgoing_server_user_name                = EM_SAFE_STRDUP(input_account->outgoing_server_user_name);
845         output_account_dup->outgoing_server_password                 = EM_SAFE_STRDUP(input_account->outgoing_server_password);
846         output_account_dup->user_display_name                        = EM_SAFE_STRDUP(input_account->user_display_name);
847         output_account_dup->reply_to_address                         = EM_SAFE_STRDUP(input_account->reply_to_address);
848         output_account_dup->return_address                           = EM_SAFE_STRDUP(input_account->return_address);
849         output_account_dup->logo_icon_path                           = EM_SAFE_STRDUP(input_account->logo_icon_path);
850         output_account_dup->user_data                                = em_memdup(input_account->user_data, input_account->user_data_length);
851         output_account_dup->options.display_name_from                = EM_SAFE_STRDUP(input_account->options.display_name_from);
852         output_account_dup->options.signature                        = EM_SAFE_STRDUP(input_account->options.signature);
853         output_account_dup->certificate_path                         = EM_SAFE_STRDUP(input_account->certificate_path);
854
855         return EMAIL_ERROR_NONE;
856 }
857
858
859 INTERNAL_FUNC void emcore_duplicate_account(const email_account_t *account, email_account_t **account_dup, int *err_code)
860 {
861         EM_DEBUG_FUNC_BEGIN("account[%p]", account);
862
863         if (!account || !account_dup) { /*prevent 40514*/
864                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
865                 if (err_code) *err_code = EMAIL_ERROR_INVALID_PARAM;
866                 return;
867         }
868
869         *account_dup = em_malloc(sizeof(email_account_t));
870         if (!*account_dup) { /*prevent 40514*/
871                 EM_DEBUG_EXCEPTION("malloc failed...");
872                 if (err_code) *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
873                 return;
874         }
875
876         emcore_duplicate_account_members(account, *account_dup);
877
878         if (err_code != NULL)
879                 *err_code = EMAIL_ERROR_NONE;
880
881         EM_DEBUG_FUNC_END();
882 }
883
884 #ifdef __FEATURE_BACKUP_ACCOUNT__
885
886 static int append_data_into_buffer(char **target_buffer, int *target_buffer_lenth, char *input_data, int input_data_length, int *error_code)
887 {
888         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);
889         int local_error_code = EMAIL_ERROR_NONE, ret_code = false;
890
891         if (!target_buffer || !target_buffer_lenth || !input_data) {
892                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
893                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
894                 goto FINISH_OFF;
895         }
896
897         if (*target_buffer_lenth > 0 && input_data_length) {
898                 EM_DEBUG_LOG("*target_buffer_lenth [%d]", *target_buffer_lenth);
899                 *target_buffer = realloc(*target_buffer, (*target_buffer_lenth) + input_data_length);
900                 if (!*target_buffer) {
901                         EM_DEBUG_EXCEPTION("realloc failed");
902                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
903                         goto FINISH_OFF;
904                 }
905                 memcpy(*target_buffer + (*target_buffer_lenth), input_data, input_data_length);
906                 *target_buffer_lenth += input_data_length;
907                 EM_DEBUG_LOG("*target_buffer_lenth [%d] input_data_length [%d]", *target_buffer_lenth, input_data_length);
908         } else {
909                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
910                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
911                 goto FINISH_OFF;
912         }
913
914         ret_code = true;
915
916 FINISH_OFF:
917
918         if (error_code)
919                 *error_code = local_error_code;
920         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
921
922         return ret_code;
923 }
924
925
926 static int emcore_write_account_into_buffer(char **target_buffer, int *target_buffer_lenth, emstorage_account_tbl_t *account_tbl_ptr, int *error_code)
927 {
928         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);
929         int local_error_code = EMAIL_ERROR_NONE, ret_code = false, stream_length = 0;
930         email_account_t temp_account = {0};
931         char *byte_stream = NULL;
932
933         if (em_convert_account_tbl_to_account(account_tbl_ptr, &temp_account)) {
934                 byte_stream = em_convert_account_to_byte_stream(&temp_account, &stream_length);
935                 EM_DEBUG_LOG("stream_length [%d]", stream_length);
936                 /*  EM_DEBUG_LOG_SEC("incoming_server_password [%s]", temp_account->password) */
937
938                 if (byte_stream) {
939                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, (char *)&stream_length, sizeof(int), &local_error_code)) {
940                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
941                                 goto FINISH_OFF;
942                         }
943                         EM_DEBUG_LOG("append_data_into_buffer succeed for stream_length");
944
945                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, byte_stream, stream_length, &local_error_code)) {
946                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
947                                 goto FINISH_OFF;
948                         }
949                         EM_DEBUG_LOG("append_data_into_buffer succeed for byte_stream");
950                 }
951         } else {
952                 EM_DEBUG_EXCEPTION("em_convert_account_tbl_to_account failed");
953                 local_error_code = EMAIL_ERROR_SYSTEM_FAILURE;
954                 goto FINISH_OFF;
955         }
956
957         ret_code = true;
958 FINISH_OFF:
959         emcore_free_account(&temp_account);
960         if (error_code)
961                 *error_code = local_error_code;
962
963         EM_SAFE_FREE(byte_stream);
964
965         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
966         return ret_code;
967 }
968
969 INTERNAL_FUNC int emcore_backup_accounts(char *multi_user_name, const char *file_path, int *error_code)
970 {
971         EM_DEBUG_LOG("file_path [%s], error_code [%p]", file_path, error_code);
972         int local_error_code = EMAIL_ERROR_NONE, local_error_code_2 = EMAIL_ERROR_NONE, ret_code = false;
973         int select_num, i, target_buff_length = 0;
974         int normal_email_account_count = 0;
975         char *target_buffer = NULL;
976         unsigned char *output_data = NULL;
977         emstorage_account_tbl_t *account_list = NULL;
978         int fd = -1;
979
980         if (!file_path) {
981                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
982                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
983                 goto FINISH_OFF;
984         }
985
986         select_num = 1000;
987
988         if (!emstorage_get_account_list(multi_user_name, &select_num, &account_list, true, true, &local_error_code)) {
989                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", local_error_code);
990                 goto FINISH_OFF;
991         }
992
993         EM_DEBUG_LOG("select_num [%d]", select_num);
994
995         if (account_list) {
996                 for (i = 0; i < select_num; i++) {
997                         if (account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3 || account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)
998                                 normal_email_account_count++;
999                 }
1000         }
1001
1002         EM_DEBUG_LOG("normal_email_account_count [%d]", normal_email_account_count);
1003
1004         if (normal_email_account_count == 0) {
1005                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_ACCOUNT_NOT_FOUND");
1006                 local_error_code = EMAIL_ERROR_ACCOUNT_NOT_FOUND;
1007                 goto FINISH_OFF;
1008         } else {
1009                 target_buffer = em_malloc(sizeof(int));
1010                 if (!target_buffer)  {
1011                         EM_DEBUG_EXCEPTION("malloc failed");
1012                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
1013                         goto FINISH_OFF;
1014                 }
1015
1016                 memcpy(target_buffer, (char *)&normal_email_account_count, sizeof(int));
1017                 target_buff_length = sizeof(int);
1018
1019                 for (i = 0; i < select_num; i++) {
1020                         if (account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3 || account_list[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) {
1021                                 if (!emcore_write_account_into_buffer(&target_buffer, &target_buff_length, account_list + i, &local_error_code)) {
1022                                         EM_DEBUG_EXCEPTION("emcore_write_account_into_buffer failed [%d]", local_error_code);
1023                                         goto FINISH_OFF;
1024                                 }
1025                         }
1026                 }
1027
1028                 EM_DEBUG_LOG("target_buff_length [%d]", target_buff_length);
1029
1030                 local_error_code = em_open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR, &fd);
1031                 if (local_error_code != EMAIL_ERROR_NONE) {
1032                                 EM_DEBUG_EXCEPTION("em_open failed - %d [%s] : ", local_error_code, file_path);
1033                                 goto FINISH_OFF;
1034                 }
1035
1036
1037                 int tmp = emcore_check_key_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY);
1038
1039                         if (tmp == EMAIL_ERROR_KEY_NOT_FOUND){
1040                                         EM_DEBUG_LOG("Key not exist");
1041
1042                                         int ret = 0;
1043
1044                                         ret = emcore_save_key_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY);
1045
1046                                         if(ret != EMAIL_ERROR_NONE){
1047                                                 EM_DEBUG_EXCEPTION("save key failed %d", ret);
1048                                                 goto FINISH_OFF;
1049                                         }
1050
1051                         } else if (tmp == EMAIL_ERROR_INVALID_PARAM) {
1052
1053                                 EM_DEBUG_EXCEPTION("Invalid parameter");
1054                                 goto FINISH_OFF;
1055
1056                         }
1057                 int output_length = 0;
1058                 emcore_encryption_data_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY, target_buffer, target_buff_length, &output_data, &output_length);
1059
1060                 EM_DEBUG_LOG("output length %d", output_length);
1061                 int write_length = write(fd, (char *)output_data, output_length);
1062                 EM_DEBUG_LOG("write length : %d", write_length);
1063
1064         }
1065
1066         ret_code = true;
1067 FINISH_OFF:
1068
1069         EM_SAFE_CLOSE(fd);
1070         EM_SAFE_FREE(target_buffer);
1071         EM_SAFE_FREE(output_data);
1072
1073         if (account_list)
1074                 emstorage_free_account(&account_list, select_num, &local_error_code_2);
1075
1076         if (error_code)
1077                 *error_code = local_error_code;
1078
1079         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1080         return ret_code;
1081 }
1082
1083 INTERNAL_FUNC int emcore_restore_accounts(char *multi_user_name, const char *file_path)
1084 {
1085         EM_DEBUG_FUNC_BEGIN_SEC("file_path [%s]", file_path);
1086         int err = EMAIL_ERROR_NONE;
1087         int account_count = 0, i = 0, account_stream_length = 0;
1088         char *temp_buffer = NULL, *account_stream = NULL, *buffer_ptr = NULL;
1089         email_account_t temp_account = {0};
1090         email_account_t *account_list = NULL;
1091         char *encrypt_buffer = NULL;
1092
1093
1094         if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_START, 0, 0, NULL, 0))
1095                 EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_START] failed");
1096
1097         if (!file_path) {
1098                 err = EMAIL_ERROR_INVALID_PARAM;
1099                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1100                 goto FINISH_OFF;
1101         }
1102
1103         if ((err = emcore_get_account_reference_list(multi_user_name, &account_list, &account_count)) == EMAIL_ERROR_NONE) {
1104                 for (i = 0; i < account_count; i++) {
1105                         if (account_list[i].incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
1106                                 if (!emcore_delete_account(multi_user_name, account_list[i].account_id, true, &err)) {
1107                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed [%d]", err);
1108                                         goto FINISH_OFF;
1109                                 }
1110                         }
1111                 }
1112
1113                 if (account_list) {
1114                         emcore_free_account_list(&account_list, account_count, NULL);
1115                         account_list = NULL;
1116                 }
1117         }
1118
1119         int output_length = 0;
1120         char *output_data = NULL;
1121
1122         emcore_decryption_data_from_file_in_key_manager(EMAIL_SERVICE_BNR_ACCOUNT_KEY, file_path, &output_data, &output_length);
1123
1124         if (output_length > 0) {
1125                 memcpy((void *)&account_count, output_data, sizeof(int));
1126                 buffer_ptr = output_data + sizeof(int);
1127
1128                 EM_DEBUG_LOG("account_count[%d]", account_count);
1129
1130                 for (i = 0; i < account_count; i++) {
1131                         memcpy((void *)&account_stream_length, buffer_ptr, sizeof(int));
1132                         buffer_ptr += sizeof(int);
1133                         EM_DEBUG_LOG("account_stream_length [%d]", account_stream_length);
1134                         if (account_stream_length) {
1135                                 account_stream = em_malloc(account_stream_length);
1136                                 if (!account_stream) {
1137                                         EM_DEBUG_EXCEPTION("em_malloc() failed.");
1138                                         err = EMAIL_ERROR_OUT_OF_MEMORY ;
1139                                         goto FINISH_OFF;
1140                                 }
1141                                 memcpy(account_stream, buffer_ptr, account_stream_length);
1142
1143                                 em_convert_byte_stream_to_account(account_stream, account_stream_length, &temp_account);
1144                                 EM_SAFE_FREE(account_stream);
1145
1146
1147
1148                                 if ((emstorage_check_duplicated_account(multi_user_name,
1149                                                                                                                 &temp_account,
1150                                                                                                                 true,
1151                                                                                                                 &err) == false) && (err = EMAIL_ERROR_ALREADY_EXISTS)) {
1152                                         EM_DEBUG_EXCEPTION("An account is duplicated. ");
1153                                         buffer_ptr += account_stream_length;
1154                                         account_stream_length = 0;
1155                                         emcore_free_account(&temp_account);
1156                                         err = EMAIL_ERROR_NONE;
1157                                         continue;
1158                                 }
1159
1160                                 if (!emcore_create_account(multi_user_name, &temp_account, true, &err)) {
1161                                         EM_DEBUG_EXCEPTION("emcore_create_account() failed. [%d]", err);
1162                                         goto FINISH_OFF;
1163                                 }
1164
1165                                 emcore_free_account(&temp_account);
1166                         }
1167                         buffer_ptr += account_stream_length;
1168                         account_stream_length = 0;
1169                 }
1170         } else {
1171                 EM_DEBUG_EXCEPTION("ssm_read() failed.");
1172                 err = EMAIL_ERROR_SYSTEM_FAILURE;
1173                 goto FINISH_OFF;
1174         }
1175
1176 FINISH_OFF:
1177 #ifdef FEATURE_SSS_ENABLE
1178         EM_SAFE_CLOSE(fd);
1179 #endif
1180
1181         if (err == EMAIL_ERROR_NONE) {
1182                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_FINISH, 0, 0, NULL, err))
1183                         EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_FINISH] failed");
1184         } else {
1185                 if (!emcore_notify_storage_event(NOTI_ACCOUNT_RESTORE_FAIL, 0, 0, NULL, err))
1186                         EM_DEBUG_EXCEPTION("emcore_notify_storage_event[NOTI_ACCOUNT_RESTORE_FAIL] failed");
1187         }
1188
1189         if (account_list) {
1190                 emcore_free_account_list(&account_list, account_count, NULL);
1191                 account_list = NULL;
1192         }
1193         emcore_free_account(&temp_account);
1194         EM_SAFE_FREE(account_stream);
1195         EM_SAFE_FREE(temp_buffer);
1196         EM_SAFE_FREE(encrypt_buffer);
1197         EM_SAFE_FREE(output_data);
1198
1199         EM_DEBUG_FUNC_END("err [%d]", err);
1200         return err;
1201 }
1202
1203 #endif /*  __FEATURE_BACKUP_ACCOUNT_ */
1204
1205 INTERNAL_FUNC int emcore_save_default_account_id(char *multi_user_name, int input_account_id)
1206 {
1207         EM_DEBUG_FUNC_BEGIN("account_id [%d]", input_account_id);
1208         int ret_code = EMAIL_ERROR_NONE, result_value = 0;
1209
1210         result_value = vconf_set_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, input_account_id);
1211         if (result_value < 0) {
1212                 EM_DEBUG_EXCEPTION("vconf_set_int failed [%d]", result_value);
1213                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1214         }
1215
1216         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1217         return ret_code;
1218 }
1219
1220 static int _recover_from_invalid_default_account_id(char *multi_user_name, int *output_account_id)
1221 {
1222         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1223         int ret_code = EMAIL_ERROR_NONE;
1224         int account_count = 100;
1225         emstorage_account_tbl_t *result_account_list = NULL;
1226
1227         if (output_account_id == NULL) {
1228                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1229                 goto FINISH_OFF;
1230         }
1231
1232         if (!emstorage_get_account_list(multi_user_name, &account_count, &result_account_list, false, false, &ret_code) || !result_account_list) {
1233                 if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND)
1234                         EM_DEBUG_LOG("no account found");
1235                 else
1236                         EM_DEBUG_EXCEPTION("emstorage_get_account_list() failed [%d]", ret_code);
1237                 *output_account_id = 0;
1238                 goto FINISH_OFF;
1239         }
1240
1241         if (account_count > 0) {
1242                 *output_account_id = result_account_list[0].account_id;
1243         }
1244
1245         EM_DEBUG_LOG_DEV("output_account_id [%d]", *output_account_id);
1246
1247 FINISH_OFF:
1248
1249         if (result_account_list)
1250                 emstorage_free_account(&result_account_list, account_count, NULL);
1251
1252         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1253         return ret_code;
1254 }
1255
1256 INTERNAL_FUNC int emcore_load_default_account_id(char *multi_user_name, int *output_account_id)
1257 {
1258         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1259         int ret_code = EMAIL_ERROR_NONE;
1260         int result_value = 0;
1261         emstorage_account_tbl_t *result_account = NULL;
1262
1263         if (output_account_id == NULL) {
1264                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1265                 goto FINISH_OFF;
1266         }
1267
1268         result_value = vconf_get_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, output_account_id);
1269
1270         if (result_value < 0) {
1271                 EM_DEBUG_EXCEPTION("vconf_get_int() failed [%d]", result_value);
1272                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1273                 *output_account_id = 0;
1274         }
1275
1276         if (*output_account_id != 0) {
1277                 if (!emstorage_get_account_by_id(multi_user_name, *output_account_id, EMAIL_ACC_GET_OPT_DEFAULT, &result_account, false, &ret_code)) {
1278                         if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND) {
1279                                 EM_DEBUG_LOG("no account found account_id[%d]", *output_account_id);
1280                                 *output_account_id = 0;
1281                         } else {
1282                                 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id() failed account_id[%d] err[%d]", *output_account_id, ret_code);
1283                                 goto FINISH_OFF;
1284                         }
1285                 }
1286         }
1287
1288         if (*output_account_id == 0) {
1289                 if ((ret_code = _recover_from_invalid_default_account_id(multi_user_name, output_account_id)) != EMAIL_ERROR_NONE) {
1290                         if (ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND)
1291                                 EM_DEBUG_LOG("no account found");
1292                         else
1293                                 EM_DEBUG_EXCEPTION("_recover_from_invalid_default_account() failed [%d]", ret_code);
1294                         *output_account_id = 0;
1295                 }
1296         }
1297
1298 FINISH_OFF:
1299         if (result_account)
1300                 emstorage_free_account(&result_account, 1, NULL);
1301
1302         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1303         return ret_code;
1304 }
1305
1306 INTERNAL_FUNC int emcore_recover_from_secured_storage_failure(char *multi_user_name)
1307 {
1308         EM_DEBUG_FUNC_BEGIN();
1309         int err = EMAIL_ERROR_NONE;
1310         int i = 0;
1311         int account_count = 50;
1312         emstorage_account_tbl_t *temp_account_tbl_list = NULL;
1313         emstorage_account_tbl_t *temp_account_tbl      = NULL;
1314
1315         if (!emstorage_get_account_list(multi_user_name, &account_count, &temp_account_tbl_list, true, false, &err)) {
1316                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", err);
1317                 goto FINISH_OFF;
1318         }
1319
1320         for (i = 0; i < account_count; i++) {
1321                 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)) {
1322                         if (err == EMAIL_ERROR_SECURED_STORAGE_FAILURE) {
1323                                 if (!emcore_delete_account(multi_user_name, temp_account_tbl_list[i].account_id, true, &err)) {
1324                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed [%d]", err);
1325                                         goto FINISH_OFF;
1326                                 }
1327                         }
1328                 }
1329         }
1330
1331 FINISH_OFF:
1332
1333         emstorage_free_account(&temp_account_tbl_list, account_count, NULL);
1334         emstorage_free_account(&temp_account_tbl, 1, NULL);
1335
1336         EM_DEBUG_FUNC_END("err [%d]", err);
1337         return err;
1338 }
1339
1340 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)
1341 {
1342         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);
1343         int err = EMAIL_ERROR_NONE;
1344
1345 #ifdef __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__
1346         int err_from_account_svc = 0;
1347         emstorage_account_tbl_t *account_tbl_data = NULL;
1348         void *join_zone = NULL;
1349
1350         if (input_account_id != ALL_ACCOUNT && (input_sync_status == SYNC_STATUS_SYNCING)) {
1351                 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)) {
1352                         EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed [%d]", err);
1353                         goto FINISH_OFF;
1354                 }
1355
1356                 if (EM_SAFE_STRLEN(multi_user_name) > 0) {
1357                         err = emcore_set_join_zone(multi_user_name, &join_zone);
1358                         if (err != EMAIL_ERROR_NONE) {
1359                                 EM_DEBUG_EXCEPTION("emcore_set_join_zone failed : [%d]", err);
1360                                 goto FINISH_OFF;
1361                         }
1362                 }
1363
1364                 if (input_set_operator == SET_TYPE_SET)
1365                         err_from_account_svc = account_update_sync_status_by_id(account_tbl_data->account_svc_id, ACCOUNT_SYNC_STATUS_RUNNING);
1366                 else if (input_set_operator == SET_TYPE_MINUS)
1367                         err_from_account_svc = account_update_sync_status_by_id(account_tbl_data->account_svc_id, ACCOUNT_SYNC_STATUS_IDLE);
1368
1369                 EM_DEBUG_LOG("account_update_sync_status_by_id returns [%d] by id[%d]", err_from_account_svc, account_tbl_data->account_svc_id);
1370
1371                 emcore_unset_join_zone(join_zone);
1372         }
1373 #endif /* __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__ */
1374
1375         if (!emstorage_update_sync_status_of_account(multi_user_name, input_account_id, input_set_operator, input_sync_status, true, &err))
1376                 EM_DEBUG_EXCEPTION("emstorage_update_sync_status_of_account failed [%d]", err);
1377
1378 #ifdef __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__
1379 FINISH_OFF:
1380         if (account_tbl_data)
1381                 emstorage_free_account(&account_tbl_data, 1, NULL);
1382 #endif /* __FEATURE_USING_ACCOUNT_SVC_FOR_SYNC_STATUS__ */
1383
1384         EM_DEBUG_FUNC_END("err [%d]", err);
1385         return err;
1386 }
1387
1388 #define GOOGLE_PIM_SYNC_GET_TOKEN_URL "https://accounts.google.com/o/oauth2/token"
1389 #define GOOGLE_PIM_SYNC_CLIENT_ID     "233916860221.apps.googleusercontent.com"
1390 #define GOOGLE_PIM_SYNC_CLIENT_SECRET "dI8wRLGMJ16Ioxfl8KaujmuU"
1391 #define CALCURL_TIMEOUT               30
1392
1393 int emcore_curl_progress_callback(void *p, double dtot, double dnow, double utot, double unow)
1394 {
1395         EM_DEBUG_LOG("%0.0lf %0.0lf %0.0lf %0.0lf", dtot, dnow, utot, unow);
1396         return 0;
1397 }
1398
1399 size_t emcore_curl_write_callback(char* data, size_t size, size_t nmemb, void* target)
1400 {
1401         EM_DEBUG_FUNC_BEGIN("data[%p] size[%d] nmemb[%d] target[%p]", data, size, nmemb, target);
1402         int last_pos = 0;
1403         char **result_string = (char**)target;
1404         size_t received_length = size * nmemb;
1405
1406         if (*result_string == NULL) {
1407                 EM_DEBUG_LOG("received_length[%zu]", received_length);
1408                 *result_string = em_malloc(received_length + 1);
1409         } else {
1410                 int new_buffer_length = 0;
1411                 last_pos = EM_SAFE_STRLEN(*result_string);
1412                 new_buffer_length = last_pos + received_length + 1;
1413                 EM_DEBUG_LOG("new_buffer_length[%d]", new_buffer_length);
1414
1415                 char *new_result_string = NULL;
1416                 new_result_string = realloc(*result_string, new_buffer_length);
1417                 if (NULL == new_result_string) {
1418                         EM_DEBUG_EXCEPTION("memory reallocation failed");
1419                         EM_SAFE_FREE(*result_string);
1420                         received_length = 0;
1421                         goto FINISH_OFF;
1422                 }
1423
1424                 *result_string = new_result_string;
1425         }
1426
1427         if (*result_string == NULL) {
1428                 EM_DEBUG_EXCEPTION("memory allocation failed");
1429                 received_length = 0;
1430                 goto FINISH_OFF;
1431         }
1432
1433         memcpy(*result_string + last_pos, data, received_length);
1434         /*EM_DEBUG_LOG_SEC("result_string[%s]", *result_string);*/
1435
1436 FINISH_OFF:
1437         EM_DEBUG_FUNC_END("received_length [%d]", received_length);
1438         return received_length;
1439 }
1440
1441 static int emcore_get_xoauth2_access_token(char *input_refresh_token, char **output_access_token)
1442 {
1443         EM_DEBUG_FUNC_BEGIN("input_refresh_token [%p] output_access_token [%p]", input_refresh_token, output_access_token);
1444         int err = EMAIL_ERROR_NONE;
1445
1446         CURL *curl = NULL;
1447         CURLcode curl_ressult_code;
1448         char *result_string = NULL;
1449         char *pos = NULL;
1450         char *savepos = NULL;
1451         char *access_token = NULL;
1452         long response_code;
1453         double speed_upload, total_time, download_size;
1454
1455         if (input_refresh_token == NULL || output_access_token == NULL) {
1456                 EM_DEBUG_EXCEPTION("curl_easy_init() failed");
1457                 err = EMAIL_ERROR_INVALID_PARAM;
1458                 goto FINISH_OFF;
1459         }
1460
1461         curl = curl_easy_init();
1462         if (NULL == curl) {
1463                 EM_DEBUG_EXCEPTION("curl_easy_init() failed");
1464                 err = EMAIL_ERROR_SYSTEM_FAILURE;
1465                 goto FINISH_OFF;
1466         }
1467
1468         char buf[1024] = {0};
1469         snprintf(buf, sizeof(buf),
1470                                 "client_id=%s&"
1471                                 "client_secret=%s&"
1472                                 "refresh_token=%s&"
1473                                 "grant_type=refresh_token",
1474                                 GOOGLE_PIM_SYNC_CLIENT_ID,
1475                                 GOOGLE_PIM_SYNC_CLIENT_SECRET,
1476                                 input_refresh_token);
1477         curl_easy_setopt(curl, CURLOPT_URL, GOOGLE_PIM_SYNC_GET_TOKEN_URL);
1478         curl_easy_setopt(curl, CURLOPT_POST, 1);
1479         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
1480         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
1481         curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CALCURL_TIMEOUT);
1482         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
1483         curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
1484         curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, emcore_curl_progress_callback);
1485         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, emcore_curl_write_callback);
1486         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&result_string);
1487         curl_easy_setopt(curl, CURLOPT_HEADER, true);
1488
1489         /* pinning */
1490         curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, tpkp_curl_ssl_ctx_callback);
1491
1492         curl_ressult_code = curl_easy_perform(curl);
1493
1494         EM_DEBUG_LOG_SEC("CURLcode: %d (%s)", curl_ressult_code, curl_easy_strerror(curl_ressult_code));
1495
1496         if (0 == curl_ressult_code) {
1497                 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
1498                 curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD,  &speed_upload);
1499                 curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME,    &total_time);
1500                 curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
1501
1502                 EM_DEBUG_LOG("Speed: %.3f bytes/sec during %.3f seconds", speed_upload, total_time);
1503                 EM_DEBUG_LOG("response code = %ld , length = %.3f", response_code, download_size);
1504         }
1505
1506         if (result_string == NULL) {
1507                 EM_DEBUG_EXCEPTION("Getting result string failed");
1508                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1509                 goto FINISH_OFF;
1510         }
1511
1512         if (strstr(result_string, "error")) {
1513                 if (strstr(result_string, "\"invalid_grant\""))
1514                         err = EMAIL_ERROR_XOAUTH_INVALID_GRANT;
1515                 else
1516                         err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1517                 goto FINISH_OFF;
1518         }
1519
1520         pos = strstr(result_string, "\"access_token\" : \"");
1521
1522         if (!pos) {
1523                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1524                 goto FINISH_OFF;
1525         }
1526
1527         pos = pos + strlen("\"access_token\" : \"");
1528
1529         access_token = strtok_r(pos, "\"", &savepos);
1530
1531         if (access_token) {
1532                 *output_access_token = EM_SAFE_STRDUP(access_token);
1533
1534                 if (*output_access_token == NULL) {
1535                         EM_DEBUG_EXCEPTION("strdup failed");
1536                         err = EMAIL_ERROR_SYSTEM_FAILURE;
1537                         goto FINISH_OFF;
1538                 }
1539         }
1540
1541 FINISH_OFF:
1542
1543         EM_SAFE_FREE(result_string);
1544
1545         if (curl)
1546                 curl_easy_cleanup(curl);
1547
1548         tpkp_curl_cleanup();
1549
1550         EM_DEBUG_FUNC_END("err [%d]", err);
1551         return err;
1552 }
1553
1554 INTERNAL_FUNC int emcore_refresh_xoauth2_access_token(char *multi_user_name, int input_account_id)
1555 {
1556         EM_DEBUG_FUNC_BEGIN("input_account_id [%d]", input_account_id);
1557         int err = EMAIL_ERROR_NONE;
1558         int new_password_string_length = 0;
1559         char *access_token = NULL;
1560         char *refresh_token = NULL;
1561         char *new_access_token = NULL;
1562         char *new_password_string = NULL;
1563         char *saveptr = NULL;
1564         email_account_t *ref_account = NULL;
1565
1566
1567         ref_account = emcore_get_account_reference(multi_user_name, input_account_id, true);
1568         if (ref_account == NULL) {
1569                 EM_DEBUG_EXCEPTION("emcore_get_account_reference() failed");
1570                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1571                 goto FINISH_OFF;
1572         }
1573
1574         access_token = EM_SAFE_STRDUP(strtok_r(ref_account->incoming_server_password, "\001", &saveptr));
1575         if (access_token == NULL) {
1576                 EM_DEBUG_EXCEPTION("invalid token string.");
1577                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1578                 goto FINISH_OFF;
1579         }
1580
1581         EM_DEBUG_LOG_SEC("access_token [%s]", access_token);
1582
1583         refresh_token = EM_SAFE_STRDUP(strtok_r(NULL, "\001", &saveptr));
1584
1585         if (refresh_token == NULL) {
1586                 EM_DEBUG_EXCEPTION("invalid token string.");
1587                 err = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
1588                 goto FINISH_OFF;
1589         }
1590
1591         EM_DEBUG_LOG_SEC("refresh_token [%s]", refresh_token);
1592
1593         if ((err = emcore_get_xoauth2_access_token(refresh_token, &new_access_token)) != EMAIL_ERROR_NONE) {
1594                 EM_DEBUG_EXCEPTION("emcore_get_xoauth2_access_token() failed [%d]", err);
1595                 goto FINISH_OFF;
1596         }
1597
1598         new_password_string_length = EM_SAFE_STRLEN(new_access_token) + EM_SAFE_STRLEN(refresh_token) + 2;
1599
1600         new_password_string = em_malloc(new_password_string_length);
1601         if (new_password_string == NULL) {
1602                 EM_DEBUG_EXCEPTION("em_malloc() failed");
1603                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1604                 goto FINISH_OFF;
1605         }
1606
1607         SNPRINTF(new_password_string, new_password_string_length, "%s\001%s", new_access_token, refresh_token);
1608
1609         if ((err = emstorage_update_account_password(multi_user_name, input_account_id, new_password_string, new_password_string)) != EMAIL_ERROR_NONE) {
1610                 EM_DEBUG_EXCEPTION("emstorage_update_account_password() failed [%d]", err);
1611                 goto FINISH_OFF;
1612         }
1613
1614 FINISH_OFF:
1615
1616         EM_SAFE_FREE(access_token);
1617         EM_SAFE_FREE(refresh_token);
1618         EM_SAFE_FREE(new_access_token);
1619         EM_SAFE_FREE(new_password_string);
1620
1621         if (ref_account) {
1622                 emcore_free_account(ref_account);
1623                 EM_SAFE_FREE(ref_account);
1624         }
1625
1626         EM_DEBUG_FUNC_END("err [%d]", err);
1627         return err;
1628 }