Coverity issue fixes for email service
[platform/core/messaging/email-service.git] / email-core / email-core-mm-callbacks.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-mm_callbacks.c
25  * Desc :  mm_callbacks for IMAP-2004g
26  *
27  * Auth :
28  *
29  * History :
30  * 2006.08.22  :  created
31  *****************************************************************************/
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "email-internal-types.h"
36 #include "c-client.h"
37 #include "email-core-global.h"
38 #include "email-core-utils.h"
39 #include "email-debug-log.h"
40 #include "email-core-mailbox.h"
41 #include "email-core-account.h"
42
43 static void mm_get_error(char *string, int *err_code);
44
45 /*
46  * callback mm_lsub
47  *              get subscribed mailbox list
48  */
49 INTERNAL_FUNC void mm_lsub(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes)
50 {
51         EM_DEBUG_FUNC_BEGIN();
52         email_callback_holder_t *p_holder = (email_callback_holder_t *)stream->sparep;
53         email_mailbox_t *p, *p_old = p_holder->data;
54         int count = p_holder->num;
55         char *s, *enc_path;
56
57         /* memory allocation */
58         p = realloc(p_old, sizeof(email_mailbox_t) * (count + 1));
59         if (!p) return ;
60
61         /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */
62         enc_path = strchr(mailbox, '}');
63         if (enc_path)
64                 enc_path += 1;
65         else {
66                 emcore_free_mailbox_list(&p, count+1);
67                 return ;
68         }
69
70         /* Convert UTF7 mailbox name to UTF8 mailbox name */
71
72         /* convert directory delimiter to '/' */
73         for (s = enc_path; *s; s++) {
74                 if (*s == (char)delimiter)
75                         *s = '/';
76         }
77
78         /* coyp string */
79         p[count].mailbox_name = cpystr(enc_path);
80         p[count].alias        = cpystr(enc_path);
81         p[count].local        = 0;
82         p[count].account_id   = stream->spare8;
83
84
85         p_holder->data = p;
86         p_holder->num++;
87
88         /* ignore attributes */
89         /*  if (attributes & latt_noinferiors) fputs (", no inferiors", fp_log); */
90         /*  if (attributes & latt_noselect) fputs (", no select", fp_log); */
91         /*  if (attributes & latt_marked) fputs (", marked", fp_log); */
92         /*  if (attributes & latt_unmarked) fputs (", unmarked", fp_log); */
93         EM_DEBUG_FUNC_END();
94 }
95
96
97 /*
98  * callback mm_lsub
99  * get mailbox list
100  */
101 INTERNAL_FUNC void mm_list(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes)
102 {
103         EM_DEBUG_FUNC_BEGIN();
104         email_callback_holder_t *p_holder = (email_callback_holder_t *)stream->sparep;
105         email_internal_mailbox_t *p, *p_old = p_holder->data;
106         int count = p_holder->num;
107         char *s, *enc_path;
108
109         /* memory allocation */
110         p = realloc(p_old, sizeof(email_internal_mailbox_t) * (count + 1));
111         if (!p) return ;
112
113         /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */
114         enc_path = strchr(mailbox, '}');
115         if (enc_path)
116                 enc_path += 1;
117         else {
118                 emcore_free_internal_mailbox(&p, count+1, NULL);
119                 return ;
120         }
121
122         /* convert directory delimiter to '/' */
123         for (s = enc_path; *s; s++)
124                 if (*s == (char)delimiter)
125                         *s = '/';
126
127         /* copy string */
128         memset(p + count, 0x00, sizeof(email_internal_mailbox_t));
129
130 #ifdef __FEATURE_XLIST_SUPPORT__
131         if (attributes & LATT_XLIST_INBOX)
132                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_INBOX;
133         else if (attributes & LATT_XLIST_ALL)
134                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_ALL_EMAILS;
135         else if (attributes & LATT_XLIST_DRAFTS)
136                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_DRAFT;
137         else if (attributes & LATT_XLIST_SENT)
138                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_SENTBOX;
139         else if (attributes & LATT_XLIST_JUNK)
140                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_SPAMBOX;
141         else if (attributes & LATT_XLIST_FLAGGED)
142                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_USER_DEFINED; //EMAIL_MAILBOX_TYPE_FLAGGED; P141122-00523 sync starred folder as Inbox sync
143         else if (attributes & LATT_XLIST_TRASH)
144                 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_TRASH;
145 #endif /* __FEATURE_XLIST_SUPPORT__ */
146
147         if (attributes & LATT_NOSELECT)
148                 p[count].no_select    = true;
149
150         if (p[count].mailbox_type == EMAIL_MAILBOX_TYPE_INBOX) /* For exception handling of Gmail inbox*/
151                 p[count].mailbox_name  = cpystr("INBOX");
152         else
153                 p[count].mailbox_name  = cpystr(enc_path);
154
155         EM_DEBUG_LOG_SEC("mailbox name [%s] mailbox_type [%d] no_select [%d]", p[count].mailbox_name, p[count].mailbox_type, p[count].no_select);
156
157         p[count].alias = emcore_get_alias_of_mailbox((const char *)enc_path);
158         p[count].local = 0;
159
160         EM_DEBUG_LOG("mm_list account_id %d", stream->spare8);
161
162         char *tmp = NULL;
163         /* in mailbox name parse n get user = %d - which is account_id */
164         tmp = strstr(mailbox, "user=");
165         if (tmp) {
166                 tmp = tmp+5;
167                 for (s = tmp; *s != '/' &&  *s != '}' && *s != '\0'; s++);
168                 *s = '\0';
169                 if (strlen(tmp) > 0)
170                         p[count].account_id = atoi(tmp);
171         }
172         EM_DEBUG_LOG("mm_list account_id %d ", p[count].account_id);
173
174         p_holder->data = p;
175         p_holder->num++;
176
177         /* ignore attributes */
178         EM_DEBUG_FUNC_END();
179 }
180
181
182 /*
183  * callback mm_status
184  * get mailbox status
185  */
186 INTERNAL_FUNC void mm_status(MAILSTREAM *stream, char *mailbox, MAILSTATUS* status)
187 {
188         EM_DEBUG_FUNC_BEGIN();
189         email_callback_holder_t *p = stream->sparep;
190
191         EM_DEBUG_FUNC_BEGIN();
192         if (status->flags & SA_MESSAGES)
193                 p->num = status->messages;
194         if (status->flags & SA_UNSEEN)
195                 p->data = (void *)status->unseen;
196         EM_DEBUG_FUNC_END();
197 }
198
199 /* callback mm_login
200  * get user_name and password
201  */
202
203 INTERNAL_FUNC void mm_login(NETMBX *mb, char *user, char *pwd, long trial)
204 {
205         EM_DEBUG_FUNC_BEGIN();
206         int account_id;
207         email_account_t *ref_account = NULL;
208         char *username = NULL;
209         char *password = NULL;
210         char *token    = NULL;
211         char *save_ptr = NULL;
212         char *user_info = NULL;
213         char *temp = NULL;
214         char *multi_user_name = NULL;
215
216         if (!mb->user[0])  {
217                 EM_DEBUG_EXCEPTION("invalid account_id...");
218                 goto FINISH_OFF;
219         }
220
221         user_info = EM_SAFE_STRDUP(mb->user);
222
223         token = strtok_r(user_info, TOKEN_FOR_MULTI_USER, &temp);
224         EM_DEBUG_LOG_SEC("Token : [%s], multi_user_name:[%s][%zu]", token, temp, EM_SAFE_STRLEN(temp));
225         account_id = atoi(token);
226         token = NULL;
227
228         if (temp != NULL && EM_SAFE_STRLEN(temp) > 0)
229                 multi_user_name = EM_SAFE_STRDUP(temp);
230
231         ref_account = emcore_get_account_reference(multi_user_name, account_id, true);
232         if (!ref_account)  {
233                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed");
234                 goto FINISH_OFF;
235         }
236
237         if (ref_account->incoming_server_user_name == NULL) {
238                 EM_DEBUG_EXCEPTION("invalid incoming_server_user_name...");
239                 goto FINISH_OFF;
240         }
241         username = EM_SAFE_STRDUP(ref_account->incoming_server_user_name);
242
243         if (ref_account->incoming_server_password == NULL) {
244                 EM_SAFE_FREE(username);
245                 EM_DEBUG_EXCEPTION("Empty password");
246                 goto FINISH_OFF;
247         }
248
249         EM_DEBUG_LOG("incoming_server_authentication_method [%d]", ref_account->incoming_server_authentication_method);
250
251         if (ref_account->incoming_server_authentication_method == EMAIL_AUTHENTICATION_METHOD_XOAUTH2) {
252                 token = strtok_r(ref_account->incoming_server_password, "\001", &save_ptr);
253                 EM_DEBUG_LOG_SEC("token [%s]", token);
254                 password = EM_SAFE_STRDUP(token);
255         } else {
256                 password = EM_SAFE_STRDUP(ref_account->incoming_server_password);
257         }
258
259         if (EM_SAFE_STRLEN(username) > 0 && EM_SAFE_STRLEN(password) > 0) {
260                 EM_SAFE_STRNCPY(user, username, NETMAXUSER - EM_SAFE_STRLEN(user) - 1);
261                 EM_SAFE_STRNCPY(pwd, password, MAILTMPLEN - EM_SAFE_STRLEN(pwd) - 1);
262         } else
263                 EM_DEBUG_EXCEPTION("User Information is NULL || EM_SAFE_STRLEN is 0 ");
264
265 FINISH_OFF:
266
267         if (ref_account) {
268                 emcore_free_account(ref_account);
269                 EM_SAFE_FREE(ref_account);
270         }
271
272         EM_SAFE_FREE(user_info);
273         EM_SAFE_FREE(username);
274         EM_SAFE_FREE(password);
275         EM_SAFE_FREE(multi_user_name);
276
277         EM_DEBUG_FUNC_END();
278 }
279
280
281 INTERNAL_FUNC void mm_dlog(char *string)
282 {
283 #ifdef FEATURE_CORE_DEBUG
284         EM_DEBUG_LOG("IMAP_TOOLKIT_DLOG [%s]", string);
285 #endif
286 }
287
288 INTERNAL_FUNC void mm_log(char *string, long errflg)
289 {
290
291         switch (errflg)  {
292         case NIL:
293                 EM_DEBUG_LOG_SEC("IMAP_TOOLKIT_LOG [%s]", string);
294                 break;
295
296         case WARN:
297                 EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG WARN [%s]", string);
298                 break;
299
300         case PARSE:
301                 EM_DEBUG_LOG("IMAP_TOOLKIT_LOG PARSE [%s]", string);
302                 break;
303
304         case BYE:
305                 EM_DEBUG_LOG("IMAP_TOOLKIT_LOG BYE [%s]", string);
306                 break;
307
308         case TCPDEBUG:
309                 EM_DEBUG_LOG_SEC("IMAP_TOOLKIT_LOG TCPDEBUG [%s]", string);
310                 break;
311
312         case ERROR: {
313                                         email_session_t *session = NULL;
314
315                                         EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%s]", string);
316
317                                         emcore_get_current_session(&session);
318
319                                         if (session) {
320                                                 mm_get_error(string, &session->error);
321                                                 EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%d]", session->error);
322                                                 if (session->error == EMAIL_ERROR_XOAUTH_BAD_REQUEST ||
323                                                                 session->error == EMAIL_ERROR_XOAUTH_INVALID_UNAUTHORIZED) {
324                                                         session->network = session->error;
325                                                 }
326                                         }
327
328                                         break;
329                                 }
330         }
331 }
332
333 INTERNAL_FUNC void mm_searched(MAILSTREAM *stream, unsigned long number)
334 {
335         EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
336         EM_DEBUG_FUNC_END();
337 }
338
339 INTERNAL_FUNC void mm_exists(MAILSTREAM *stream, unsigned long number)
340 {
341         EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
342         EM_DEBUG_FUNC_END();
343 }
344
345 INTERNAL_FUNC void mm_expunged(MAILSTREAM *stream, unsigned long number)
346 {
347         EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
348         EM_DEBUG_FUNC_END();
349 }
350
351 INTERNAL_FUNC void mm_flags(MAILSTREAM *stream, unsigned long number)
352 {
353         EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
354         EM_DEBUG_FUNC_END();
355 }
356
357 INTERNAL_FUNC void mm_notify(MAILSTREAM *stream, char *string, long errflg)
358 {
359         EM_DEBUG_FUNC_BEGIN();
360 #ifdef FEATURE_CORE_DEBUG
361         mm_log(string, errflg);
362 #endif /* FEATURE_CORE_DEBUG */
363         EM_DEBUG_FUNC_END();
364 }
365
366 INTERNAL_FUNC void mm_critical(MAILSTREAM *stream)
367 {
368         EM_DEBUG_FUNC_BEGIN("stream [%p]", stream);
369         EM_DEBUG_FUNC_END();
370 }
371
372 INTERNAL_FUNC void mm_nocritical(MAILSTREAM *stream)
373 {
374         EM_DEBUG_FUNC_BEGIN("stream [%p]", stream);
375         EM_DEBUG_FUNC_END();
376 }
377
378 INTERNAL_FUNC long mm_diskerror(MAILSTREAM *stream, long errcode, long serious)
379 {
380         EM_DEBUG_FUNC_BEGIN("stream [%p] errcode[%d] serious[%d]", stream, errcode, serious);
381 #if UNIXLIKE
382         kill(getpid(), SIGSTOP);
383 #else
384         abort();
385 #endif
386         EM_DEBUG_FUNC_END();
387         return NIL;
388 }
389
390 INTERNAL_FUNC void mm_fatal(char *string)
391 {
392         EM_DEBUG_EXCEPTION("%s", string);
393 }
394
395 INTERNAL_FUNC void mm_get_error(char *string, int *err_code)
396 {
397         if (!string || !err_code)
398                 return ;
399
400         EM_DEBUG_LOG("string [%s]", string);
401
402         if (strstr(string, "login failure") || strstr(string, "Login aborted") || strstr(string, "Can't login"))
403                 *err_code = EMAIL_ERROR_LOGIN_FAILURE;
404         else if (strstr(string, "Scan not valid"))
405                 *err_code = EMAIL_ERROR_SCAN_NOT_SUPPORTED;
406         else if (strstr(string, "Authentication cancelled"))
407                 *err_code = EMAIL_ERROR_AUTHENTICATE;
408         else if (strstr(string, "authuser"))
409                 *err_code = EMAIL_ERROR_AUTH_NOT_SUPPORTED;
410         else if (strstr(string, "negotiate TLS"))
411                 *err_code = EMAIL_ERROR_CANNOT_NEGOTIATE_TLS;
412         else if (strstr(string, "TLS/SSL failure"))
413                 *err_code = EMAIL_ERROR_TLS_SSL_FAILURE;
414         else if (strstr(string, "STARTLS"))
415                 *err_code = EMAIL_ERROR_STARTLS;
416         else if (strstr(string, "TLS unavailable"))
417                 *err_code = EMAIL_ERROR_TLS_NOT_SUPPORTED;
418         else if (strstr(string, "Can't access"))
419                 *err_code = EMAIL_ERROR_IMAP4_APPEND_FAILURE;
420         else if (strstr(string, "Can not authenticate"))
421                 *err_code = EMAIL_ERROR_AUTHENTICATE;
422         else if (strstr(string, "Unexpected IMAP response") || strstr(string, "hello"))
423                 *err_code = EMAIL_ERROR_INVALID_RESPONSE;
424         else if (strstr(string, "NOTIMAP4REV1"))
425                 *err_code = EMAIL_ERROR_COMMAND_NOT_SUPPORTED;
426         else if (strstr(string, "Anonymous"))
427                 *err_code = EMAIL_ERROR_ANNONYM_NOT_SUPPORTED;
428         else if (strstr(string, "connection broken"))
429                 *err_code = EMAIL_ERROR_CONNECTION_BROKEN;
430         else if (strstr(string, "SMTP greeting"))
431                 *err_code = EMAIL_ERROR_NO_RESPONSE;
432         else if (strstr(string, "ESMTP failure"))
433                 *err_code = EMAIL_ERROR_SMTP_SEND_FAILURE;
434         else if (strstr(string, "socket") || strstr(string, "Socket"))
435                 *err_code = EMAIL_ERROR_SOCKET_FAILURE;
436         else if (strstr(string, "connect to") || strstr(string, "Connection failed"))
437                 *err_code = EMAIL_ERROR_CONNECTION_FAILURE;
438         else if (strstr(string, "Certificate failure"))
439                 *err_code = EMAIL_ERROR_CERTIFICATE_FAILURE;
440         else if (strstr(string, "No such host"))
441                 *err_code = EMAIL_ERROR_NO_SUCH_HOST;
442         else if (strstr(string, "host") || strstr(string, "Host"))
443                 *err_code = EMAIL_ERROR_INVALID_SERVER;
444         else if (strstr(string, "SELECT failed"))
445                 *err_code = EMAIL_ERROR_MAILBOX_NOT_FOUND;
446         else if (strstr(string, "15 minute"))
447                 *err_code = EMAIL_ERROR_LOGIN_ALLOWED_EVERY_15_MINS;
448         else if (strstr(string, "\"status\":\"400"))
449                 *err_code = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
450         else if (strstr(string, "\"status\":\"401"))
451                 *err_code = EMAIL_ERROR_XOAUTH_INVALID_UNAUTHORIZED;
452         else if (strstr(string, "ALREADYEXISTS"))
453                 *err_code = EMAIL_ERROR_ALREADY_EXISTS;
454         else
455                 *err_code = EMAIL_ERROR_UNKNOWN;
456 }
457
458 #ifdef __FEATURE_SUPPORT_IMAP_ID__
459 INTERNAL_FUNC void mm_imap_id(char **id_string)
460 {
461         EM_DEBUG_FUNC_BEGIN("id_string [%p]", id_string);
462
463         /*
464            char *result_string = NULL;
465            char *tag_string = "ID (\"os\" \"" IMAP_ID_OS "\" \"os-version\" \"" IMAP_ID_OS_VERSION "\" \"vendor\" \"" IMAP_ID_VENDOR "\" \"device\" \"" IMAP_ID_DEVICE_NAME "\" \"AGUID\" \"" IMAP_ID_AGUID "\" \"ACLID\" \"" IMAP_ID_ACLID "\"";
466            int   tag_length = 0;
467            */
468
469         if (id_string == NULL) {
470                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
471                 goto FINISH_OFF;
472         }
473
474         *id_string = NULL;
475
476         /*
477            tag_length = EM_SAFE_STRLEN(tag_string);
478            result_string = EM_SAFE_STRDUP(tag_string);
479
480            if (result_string == NULL) {
481            EM_DEBUG_EXCEPTION("malloc failed");
482            goto FINISH_OFF;
483            }
484
485          *id_string = result_string;
486          */
487 FINISH_OFF:
488         return ;
489 }
490 #endif /* __FEATURE_SUPPORT_IMAP_ID__ */
491 /* EOF */