Tizen 2.0 Release
[platform/core/messaging/email-service.git] / email-daemon / email-daemon-emn.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 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <stdarg.h>     /*  Needed for the definition of va_list */
28 #include <glib.h>
29
30 #include "email-daemon.h"
31 #include "email-daemon-emn.h"
32
33 /* --------------------------------------------------------------------------------*/
34 /* ----- WBXML Parsing (2007.06.09) -----------------------------------------------*/
35 /* --------------------------------------------------------------------------------*/
36 #ifdef USE_OMA_EMN
37
38 #include <wbxml.h>
39 #include <wbxml_errors.h>
40 #include "email-debug-log.h"
41 #include <vconf.h>
42
43 typedef struct
44 {
45         int account_id;
46         email_emn_noti_cb callback;
47         void* user_data;
48 } email_emn_noti_pack_t;
49
50
51 /* Parse the Email address to Get the user Name for the account [deepam.p@samsung.com] */
52 static char* _get_username(char *account_username)
53 {
54         EM_IF_NULL_RETURN_VALUE(account_username, NULL);
55
56         int index = 0;
57         char **token_list = NULL;
58         char *username = NULL, *name = NULL;
59
60         username = g_strdup(account_username);
61         token_list = g_strsplit_set(username, "@", -1);
62
63         if (username) {
64                 g_free(username);
65         }
66
67         if (token_list[index] != NULL)
68     {
69                 name = g_strdup(token_list[index]);
70                 g_strfreev(token_list); /*  MUST BE. */
71                 EM_DEBUG_LOG("ACCOUNT USER NAME [%s] \n", name);
72                 return name;
73         }
74         else
75                 return NULL;
76 }
77
78 static void _cb_parser_start_document(void* ctx, WB_LONG charset, const WBXMLLangEntry* lang)
79 {
80     EM_DEBUG_LOG("_cb_parser_start_document\n");
81     EM_DEBUG_LOG("Parsing Document:\n\tRoot Element: %s\n\tPublic ID: %s\n\tDTD: %s\n",
82                  lang->publicID->xmlRootElt,
83                  lang->publicID->xmlPublicID,
84                  lang->publicID->xmlDTD);
85 }
86
87 static void _cb_parser_end_document(void* ctx)
88 {
89     EM_DEBUG_LOG("_cb_parser_end_document\n");
90 }
91
92 static void _cb_parser_start_element(void* ctx, WBXMLTag* element, WBXMLAttribute** atts, WB_BOOL empty)
93 {
94     WB_UTINY* p, **pp = ctx;
95     WB_ULONG j = 0, len = 0;
96     EM_DEBUG_LOG("parse_clb_start_element\n");
97
98     if (strcasecmp((char *)wbxml_tag_get_xml_name(element), "emn") != 0)
99     {
100         EM_DEBUG_LOG("not email notification\n");
101         return ;
102     }
103
104     if (atts == NULL)
105     {
106         EM_DEBUG_LOG("no emn attributes\n");
107         return ;
108     }
109
110     len = EM_SAFE_STRLEN((char *)wbxml_tag_get_xml_name(element)) + 1;
111     while (atts[j] != NULL)
112     {
113         len += (EM_SAFE_STRLEN((char *)wbxml_attribute_get_xml_name(atts[j])) + EM_SAFE_STRLEN((char *)wbxml_attribute_get_xml_value(atts[j])) + 7);
114         j++;
115     }
116     len += 3;
117
118     if (!(p = malloc(sizeof(WB_UTINY) * len + 1)))
119     {
120         return ;
121     }
122
123     EM_DEBUG_LOG("<%s", (char *)wbxml_tag_get_xml_name(element));
124     sprintf((char *)p, "<%s", (char *)wbxml_tag_get_xml_name(element));
125
126     j = 0;
127     while (atts[j] != NULL)
128     {
129         EM_DEBUG_LOG(" %s=\"%s\"", (char *)wbxml_attribute_get_xml_name(atts[j]), (char *)wbxml_attribute_get_xml_value(atts[j]));
130         strcat((char *)p, " ");
131         strcat((char *)p, (char *)wbxml_attribute_get_xml_name(atts[j]));
132         strcat((char *)p, "=");
133         strcat((char *)p, "\"");
134         strcat((char *)p, (char *)wbxml_attribute_get_xml_value(atts[j]));
135         strcat((char *)p, "\"");
136         j++;
137     }
138
139     if (empty)
140     {
141         EM_DEBUG_LOG("/>\n");
142         strcat((char *)p, "/>");
143     }
144     else
145     {
146         EM_DEBUG_LOG(">\n");
147         strcat((char *)p, ">");
148     }
149
150     *pp = p;
151 }
152
153 static void _cb_parser_end_element(void* ctx, WBXMLTag* element, WB_BOOL empty)
154 {
155     EM_DEBUG_LOG("parse_clb_end_element\n");
156 }
157
158 static void _cb_parser_characters(void* ctx, WB_UTINY* ch, WB_ULONG start, WB_ULONG length)
159 {
160     EM_DEBUG_LOG("_cb_parser_characters\n");
161 }
162
163 static int _get_addr_from_element(unsigned char* elm,
164                                                 int* type,
165                                                 unsigned char** incoming_server_user_name,
166                                                 unsigned char** host_addr,
167                                                 unsigned char** mbox_name,
168                                                 unsigned char** auth_type)
169 {
170     unsigned char*      p;
171     unsigned char*      s;
172     unsigned char*      user = NULL;
173     unsigned char*      host = NULL;
174     unsigned char*      mailbox = NULL;
175     unsigned char*      auth = NULL;
176     
177      EM_DEBUG_FUNC_BEGIN();
178          
179     if (!(p = (unsigned char*)strstr((char *)elm, "mailbox")))  /*  add acetrack.20080331.K8.4043 */
180     {
181         EM_DEBUG_EXCEPTION("invalid notification data\n");
182         return 0;
183     }
184
185     p += 9;
186     s = (unsigned char*)strchr((char *)p, '\"');
187     /*  2007-05-08 by acetrack */
188     if (s)
189       *s = '\0';
190         
191     switch (p[0])
192     {
193     case 'm':/*  mailat (RFC2234) */
194         *type = 1;
195         p += 7;
196         if (!(s = (unsigned char*)strchr((char *)p, '@'))) return 0;
197         *s = '\0';
198         user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
199         s++;
200         host = (unsigned char*)EM_SAFE_STRDUP((char *)s);
201           mailbox = NULL;
202         auth = NULL;
203         break;
204
205     case 'p':/*  pop3 (RFC2384) */
206         *type = 2;
207         p += 6;
208         if ((s = (unsigned char*)strchr((char *)p, ';')))
209         {
210             *s = '\0';
211             if (EM_SAFE_STRLEN((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
212             p = s + 1;
213         }
214         if ((s = (unsigned char*)strchr((char *)p, '@')))
215         {
216             *s = '\0';
217             if (user || *(p - 3) == '/')
218             {
219                 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
220             }
221             else
222                 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
223             p = s + 1;
224         }
225         if ((s = (unsigned char*)strchr((char *)p, ':')))
226         {
227             *s = '\0';
228             s++;
229             EM_DEBUG_LOG("PORT:%s\n", s);
230         }
231         host = (unsigned char*)EM_SAFE_STRDUP((char *)p);
232         mailbox = NULL;
233         break;
234
235     case 'i':/*  imap (RFC2192) */
236         *type = 3;
237         p += 7;
238         if ((s = (unsigned char*)strchr((char *)p, ';')))
239         {
240             *s = '\0';
241             if (EM_SAFE_STRLEN((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
242             p = s + 1;
243         }
244         if ((s = (unsigned char*)strchr((char *)p, '@')))
245         {
246             *s = '\0';
247             if (user || *(p - 3) == '/')
248             {
249                 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
250             }
251             else
252                 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
253             p = s + 1;
254         }
255
256         if ((s = (unsigned char *)strchr((char *)p, '/'))) * s = '\0';
257         host = (unsigned char *)EM_SAFE_STRDUP((char *)p);
258         p = s + 1;
259
260         if ((s = (unsigned char*)strchr((char *)p, '?'))) * s = '\0';
261         else if ((s = (unsigned char*)strchr((char *)p, ';'))) * s = '\0';
262         else s = p + EM_SAFE_STRLEN((char *)p);
263         if (*(s - 1) == '/') *(s - 1) = '\0';
264
265         if (EM_SAFE_STRLEN((char *)p)) mailbox =(unsigned char*) EM_SAFE_STRDUP((char *)p);
266         break;
267
268     case 'h': /*  not supported */
269         EM_DEBUG_LOG("Http URI is not yet supported\n");
270         return 0;
271         
272     default:
273         return 0;
274     }
275
276     *incoming_server_user_name = user;
277     *host_addr = host;
278     *mbox_name = mailbox;
279     *auth_type = auth;
280
281     return 1;
282 }
283
284 static int _get_time_from_element(unsigned char* elm,
285                           unsigned char** time_stamp)
286 {
287     EM_DEBUG_FUNC_BEGIN();
288
289     unsigned char* p, *s, *stamp = NULL;
290     if (!(p = (unsigned char*)strstr((char *)elm, "timestamp")))
291     {
292         EM_DEBUG_EXCEPTION("invalid notification data\n");
293         return 0;
294     }
295
296     p += 11;
297     s = (unsigned char*)strchr((char *)p, '\"');
298     /*  2007-05-08 by acetrack */
299     if (s)
300         *s = '\0';
301
302     stamp = malloc(15);
303     if (!stamp) /*  added acetrack.20080331.K8.4045 */
304     {
305         EM_DEBUG_EXCEPTION("malloc failed");
306         return 0;
307     }
308     memcpy(stamp, p, 4);
309     memcpy(stamp + 4, p + 5, 2);
310     memcpy(stamp + 6, p + 8, 2);
311     memcpy(stamp + 8, p + 11, 2);
312     memcpy(stamp + 10, p + 14, 2);
313     memcpy(stamp + 12, p + 17, 2);
314     stamp[14] = '\0';
315
316     *time_stamp = stamp;
317
318     return 1;
319 }
320
321 /*  <emn mailbox="mailat:user@wapforum.org" timestamp="2002-04-16T06:40:00Z"/> */
322 static int _get_data_from_element(unsigned char* elm,
323                           int* type,
324                           unsigned char** incoming_server_user_name,
325                           unsigned char** host_addr,
326                           unsigned char** mbox_name,
327                           unsigned char** auth_type,
328                           unsigned char** time_stamp)
329 {
330
331     EM_DEBUG_FUNC_BEGIN();
332     if (!_get_time_from_element(elm, time_stamp))
333     {
334         return 0;
335         }
336
337     /*  must call get_addr_from_element after calling _get_time_from_element */
338     if (!_get_addr_from_element(elm, type, incoming_server_user_name, host_addr, mbox_name, auth_type))
339     {
340             EM_SAFE_FREE*time_stamp)    /*  added acetrack.20080331.K8.4046 */
341             return 0;
342     }
343
344     return 1;
345 }
346
347
348
349 /* description
350  *    get account from OMA EMN data
351  * arguments
352  *    wbxml_b64 : BASE64 encoded data
353  *    account_id: id of account to be retrieved from EMN data
354  *    mailbox   : if mail-box information exists in EMN data, mailbox holds the name of mailbox.
355  *    err_code  : hold error code
356  * return
357  *    succeed : 1
358  *    fail : 0
359  */
360 static int _get_emn_account(unsigned char* wbxml_b64, email_account_t* account, char** mailbox, int* err_code)
361 {
362         EM_DEBUG_LOG("_get_emn_account Enter");
363     WBXMLContentHandler parse_handler = {
364                                             (WBXMLStartDocumentHandler) _cb_parser_start_document,
365                                             (WBXMLEndDocumentHandler) _cb_parser_end_document,
366                                             (WBXMLStartElementHandler) _cb_parser_start_element,
367                                             (WBXMLEndElementHandler) _cb_parser_end_element,
368                                             (WBXMLCharactersHandler) _cb_parser_characters,
369                                             NULL
370                                         };
371
372     WBXMLParser*        wbxml_parser = NULL;
373     WB_UTINY*           wbxml = NULL;
374     WB_UTINY*           elm = NULL;
375     WB_ULONG            wbxml_len = 0;
376     WB_ULONG            err_idx = 0;
377     WBXMLError          ret = WBXML_OK;
378     email_account_t*    accounts = NULL;
379     unsigned char*      incoming_server_user_name = NULL;
380     unsigned char*      host_addr = NULL;
381     unsigned char*      mbox_name = NULL;
382     unsigned char*      auth_type = NULL;
383     unsigned char*      time_stamp = NULL;
384     int                         type = 0;
385     int                         i = 0;
386     int                         count = 0;
387     int                         retr = false;
388     int                         err = EMAIL_ERROR_NONE;
389
390     EM_DEBUG_LOG("");
391
392     if (!wbxml_b64 || !account)
393     {
394          EM_DEBUG_EXCEPTION(">>>> Invalid Parameter >>>> \n");
395         err = EMAIL_ERROR_INVALID_PARAM;
396         goto FINISH_OFF;
397     }
398
399     wbxml = g_base64_decode((const char*)wbxml_b64, (unsigned int*)&wbxml_len);
400     EM_DEBUG_LOG("wbxml = %p\n", wbxml);
401     EM_DEBUG_LOG("wbxml_len = %d\n", wbxml_len);
402
403     /*  create wbxml parser */
404     if (!(wbxml_parser = wbxml_parser_create()))
405     {
406         err = EMAIL_ERROR_OUT_OF_MEMORY;                
407         goto FINISH_OFF;
408     }
409
410     /*  initialize wbxml parser */
411     wbxml_parser_set_user_data(wbxml_parser, (void*)&elm);
412     wbxml_parser_set_content_handler(wbxml_parser, &parse_handler);
413
414     /*  parsing wbxml */
415     if ((ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len)) != WBXML_OK)
416     {
417         err_idx = wbxml_parser_get_current_byte_index(wbxml_parser);
418         EM_DEBUG_LOG("Parsing failed at %u - Token %x - %s", err_idx, wbxml[err_idx], wbxml_errors_string(ret));
419                 
420         err = EMAIL_ERROR_XML_PARSER_FAILURE;           
421         goto FINISH_OFF;
422     }
423     else
424     {
425         EM_DEBUG_LOG("Parsing OK !\n");
426     }
427
428     /*  destroy parser */
429     wbxml_parser_destroy(wbxml_parser);
430     wbxml_parser = NULL;
431
432     /*  free buffer */
433     wbxml_free(wbxml);
434     wbxml = NULL;
435
436     if (!elm)
437     {
438         EM_DEBUG_EXCEPTION("invalid elements\n");
439                 
440         err = EMAIL_ERROR_XML_PARSER_FAILURE;           
441         goto FINISH_OFF;
442     }
443
444     EM_DEBUG_LOG("elements = [%s]\n", elm);
445     _get_data_from_element(elm, &type, &incoming_server_user_name, &host_addr, &mbox_name, &auth_type, &time_stamp);
446
447     EM_SAFE_FREE(elm);
448
449     EM_DEBUG_LOG("user_type = [%d]\n", type);
450     EM_DEBUG_LOG("incoming_server_user_name = [%s]\n", (char *)incoming_server_user_name ? (char*)incoming_server_user_name : "NIL");
451     EM_DEBUG_LOG("host_addr = [%s]\n", (char *)host_addr ? (char*)host_addr : "NIL");
452     EM_DEBUG_LOG("mbox_name = [%s]\n", (char *)mbox_name ? (char*)mbox_name : "NIL");
453     EM_DEBUG_LOG("auth_type = [%s]\n", (char *)auth_type ? (char*)auth_type : "NIL");
454     EM_DEBUG_LOG("time_stamp= [%s]\n", (char *)time_stamp? (char*)time_stamp: "NIL");
455
456      if (!emdaemon_get_account_list(&accounts, &count, &err))
457     {
458         EM_DEBUG_EXCEPTION("   emdaemon_get_account_list error");
459         err = EMAIL_ERROR_DB_FAILURE;
460         goto FINISH_OFF;
461     }
462         
463     for (i = 0; i < count; i++)
464     {
465         /* sowmya.kr, 201009, Fix for EMN */
466         char* temp_account_name = NULL;
467                 char *s = NULL;
468             /*  EM_DEBUG_LOG(">>>> Account Information UserName [ %s ] Email Addr [ %s], Account ID [ %d] >>> \n",accounts[i].incoming_server_user_name,accounts[i].user_email_address, accounts[i].account_id); */
469                 temp_account_name =(char*) EM_SAFE_STRDUP((char *)accounts[i].incoming_server_user_name);
470
471                 if ((s = (char*)strchr((char *)temp_account_name, '@')))  {
472                         *s = '\0';
473                         EM_SAFE_FREE(accounts[i].incoming_server_user_name);                    
474                         accounts[i].incoming_server_user_name  = (char*)EM_SAFE_STRDUP((char *)temp_account_name);                      
475                 }
476                 EM_SAFE_FREE(temp_account_name);
477                 if (incoming_server_user_name)  {       
478                         if (strcmp(accounts[i].incoming_server_user_name, (char *)incoming_server_user_name) == 0 &&
479                                 strstr(accounts[i].user_email_address, (char *)host_addr)) {
480                                 EM_DEBUG_LOG(">>>> Account Match >>> \n");
481                                 if ((type == 1) ||
482                                         (type == 2 && accounts[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3) ||
483                                         (type == 3 && accounts[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)) {
484                                         accounts[i].flag2 = type;
485                                         EM_DEBUG_LOG("found target account id[%d] name[%s]", accounts[i].account_id, accounts[i].incoming_server_user_name);
486                                         break;
487                                 }
488                         }
489                 }
490         }
491
492         if (i >= count) {
493                 EM_DEBUG_EXCEPTION("no account was found");
494                 err = EMAIL_ERROR_ACCOUNT_NOT_FOUND;
495                 goto FINISH_OFF;
496         }
497         if (account) {
498                 account->account_id = accounts[i].account_id;
499                 account->flag2 = accounts[i].flag2;
500         }
501     
502     if (mailbox)
503     {
504         *mailbox = mbox_name ? (char *)mbox_name : NULL;
505         mbox_name = NULL;
506     }
507     emdaemon_free_account(&accounts, count, NULL);
508     accounts = NULL;
509
510     retr = true;
511
512 FINISH_OFF:
513     if (wbxml) wbxml_free(wbxml);
514     if (wbxml_parser) wbxml_parser_destroy(wbxml_parser);
515     EM_SAFE_FREE(elm);
516     if (accounts) emdaemon_free_account(&accounts, count, NULL);
517     EM_SAFE_FREE(incoming_server_user_name);
518     EM_SAFE_FREE(mbox_name);
519     EM_SAFE_FREE(auth_type);
520     EM_SAFE_FREE(time_stamp);
521     if (err_code) *err_code = err;
522     return retr;
523 }
524
525 INTERNAL_FUNC int emdaemon_handle_emn_notification(unsigned char* wbxml_b64, email_emn_noti_cb callback, int* err_code)
526 {
527         EM_DEBUG_FUNC_BEGIN("wbxml_b64[%p], callback[%p], err_code[%p]", wbxml_b64, callback, err_code);
528         
529         int ret = false;
530         int err = EMAIL_ERROR_NONE;;
531         char* mailbox_name = NULL;
532         email_mailbox_t mailbox = { 0 };
533         email_account_t account = { 0 };
534         email_emn_noti_pack_t* pack = NULL;
535         char* pmailbox = NULL;
536         
537         if (!wbxml_b64) {
538                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
539                 err = EMAIL_ERROR_INVALID_PARAM;
540                 goto FINISH_OFF;
541         }
542         
543         pack = (email_emn_noti_pack_t*)em_malloc(sizeof(email_emn_noti_pack_t));
544         if (!pack) {
545                 EM_DEBUG_EXCEPTION("em_malloc failed");
546                 err = EMAIL_ERROR_OUT_OF_MEMORY;
547                 goto FINISH_OFF;
548         }
549         
550         if (!_get_emn_account(wbxml_b64, &account, &mailbox_name, &err)) {
551                 EM_DEBUG_EXCEPTION("_get_emn_account failed [%d]", err);
552                 goto FINISH_OFF;
553         }
554
555         mailbox.account_id = account.account_id;
556
557         if (!emstorage_get_mailbox_name_by_mailbox_type(mailbox.account_id,EMAIL_MAILBOX_TYPE_INBOX,&pmailbox, false, &err))  {
558                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed [%d", err);               
559
560                 goto FINISH_OFF;
561         }
562
563         if ((account.incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) && (account.flag2 == 3))  {
564
565                 if (!mailbox_name || strncmp(pmailbox, mailbox_name, EM_SAFE_STRLEN(pmailbox)) != 0)  {
566                         EM_DEBUG_EXCEPTION("invalid inbox name [%p]", mailbox_name);
567                         err = EMAIL_ERROR_INVALID_MAILBOX;
568                         goto FINISH_OFF;
569                 }
570         }
571         
572         /* sync header with mail server */
573         mailbox.mailbox_name = mailbox_tbl->mailbox_name;
574         
575         if (!emdaemon_sync_header(mailbox.account_id, mailbox.mailbox_id, NULL, &err))  {
576                 EM_DEBUG_EXCEPTION("emdaemon_sync_header falied [%d]", err);
577                 goto FINISH_OFF;
578         }
579         
580         ret = true;
581         
582 FINISH_OFF:
583         if (ret == false) 
584                 EM_SAFE_FREE(pack);
585
586         EM_SAFE_FREE(pmailbox);
587
588         if (err_code != NULL)
589                 *err_code = err;
590         
591         return ret;
592 }
593
594 int emdaemon_initialize_emn(void)
595 {
596         EM_DEBUG_FUNC_BEGIN();
597
598         /* TODO : Write codes for subscribing OMA-EMN notification */
599
600         EM_DEBUG_FUNC_END();
601         return 0;
602 }
603
604 int emdaemon_finalize_emn(gboolean bExtDest)
605 {
606         EM_DEBUG_FUNC_BEGIN();
607         EM_DEBUG_FUNC_END();
608         return 0;
609 }
610
611 #endif /*  USE_OMA_EMN */
612
613 /* EOF */