297e3e62c79bde53c068fd0253586fae62a8c177
[platform/core/account/fido-client.git] / server / fido_server.c
1 /*
2  * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <signal.h>
21 #include <glib.h>
22 #if !GLIB_CHECK_VERSION (2, 31, 0)
23 #include <glib/gmacros.h>
24 #endif
25
26 #include "fido_privilege_checker.h"
27 #include "fido_asm_plugin_manager.h"
28 #include "fido_internal_types.h"
29 #include "fido_json_handler.h"
30 #include "fido_keys.h"
31 #include "fido_app_id_handler.h"
32 #include "fido_uaf_policy_checker.h"
33 #include "fido_selection_ui_adaptor.h"
34 #include "fido_logs.h"
35 #include "fido_uaf_types.h"
36 #include "fido-stub.h"
37
38 #define _FIDO_SERVICE_DBUS_PATH       "/org/tizen/fido"
39 static guint owner_id = 0;
40 //GDBusObjectManagerServer *fido_dbus_mgr = NULL;
41 static Fido* fido_dbus_obj = NULL;
42
43 //TODO : current assumption is, ASM will handle multiple request queueing
44
45 typedef struct _dbus_info{
46         Fido *dbus_obj;
47         GDBusMethodInvocation *invocation;
48 }_dbus_info_t;
49
50 typedef struct _discover_cb {
51         //fido_authenticator_cb cb;
52         void *user_data;
53         _dbus_info_t *dbus_info;
54 } discover_cb_t;
55
56 typedef struct _fido_discover_asm_cb_data {
57         _fido_discover_asm_cb cb;
58         void *user_data;
59 }_fido_discover_asm_cb_data_t;
60
61 typedef enum {
62         _PROCESS_TYPE_MIN = 0,
63         _PROCESS_TYPE_AUTH,
64         _PROCESS_TYPE_REG,
65         _PROCESS_TYPE_DEREG,
66         _PROCESS_TYPE_CHECK_POLICY,
67         _PROCESS_TYPE_MAX
68 } _process_type_t;
69
70 typedef struct _process_cb_data {
71         _process_type_t type;
72         _message_t *uaf_req;
73         void *asm_in;/* ASM input data, type varies depending on operation name */
74         _dbus_info_t *dbus_info;
75 } _process_cb_data_t;
76
77 static void __process_dereg_queue(_dereg_q_t *dereg_q);
78
79 static char**
80 __create_empty_json_2d_array(void)
81 {
82         char **asm_resp_json_arr = calloc(1, sizeof(int));
83
84         char *empty_asm_resp = calloc(1, 128);
85         snprintf(empty_asm_resp, 127, "%s", _EMPTY_JSON_STRING);
86         asm_resp_json_arr[0] = empty_asm_resp;
87
88         return asm_resp_json_arr;
89 }
90
91 static void
92 __free_2d_string_array(char **arr, int row_count)
93 {
94         RET_IF_FAIL_VOID(arr != NULL);
95
96         int i = 0;
97         for (; i < row_count; i++)
98                 SAFE_DELETE(arr[i]);
99
100         SAFE_DELETE(arr);
101 }
102
103 static char*
104 __dup_string(const char *source)
105 {
106         if (source != NULL)
107                 return strdup(source);
108
109         return NULL;
110 }
111
112 static void
113 __free_asm_discover_response_list_item(gpointer data)
114 {
115         RET_IF_FAIL_VOID(data != NULL);
116
117         _free_asm_discover_response((_asm_discover_response_t*)data);
118 }
119
120 static void
121 __send_discover_response(Fido *object, GDBusMethodInvocation *invocation, int err, char **asm_resp_2d_arr, int asm_resp_len)
122 {
123         if (asm_resp_2d_arr == NULL
124                         || asm_resp_len <= 0) {
125
126                 char **empty_arr = __create_empty_json_2d_array();
127                 fido_complete_fido_uaf_discover(object, invocation, err,
128                                                                                 (const gchar * const*)empty_arr, 0);
129
130                 __free_2d_string_array(empty_arr, 1);
131                 return;
132         }
133
134         fido_complete_fido_uaf_discover(object, invocation, err,
135                                                                         (const gchar * const*)asm_resp_2d_arr, asm_resp_len);
136
137         __free_2d_string_array(asm_resp_2d_arr, asm_resp_len);
138 }
139
140 void
141 _asm_get_info_cb(GList *asm_resp_list, void *user_data)
142 {
143         _INFO("_asm_get_info_cb");
144
145         _dbus_info_t *dbus_info = (_dbus_info_t *)user_data;
146         if (dbus_info != NULL) {
147
148                 if (asm_resp_list != NULL) {
149
150                         int str_list_len = g_list_length(asm_resp_list);
151                         char **asm_resp_json_arr = calloc(str_list_len, sizeof(int));
152                         int data_len = 0;
153                         int i = 0;
154
155                         GList *asm_resp_list_iter = g_list_first(asm_resp_list);
156                         while (asm_resp_list_iter != NULL) {
157                                 _asm_discover_response_t *disc_resp = (_asm_discover_response_t*)(asm_resp_list_iter->data);
158
159                                 if (disc_resp->asm_response_json != NULL) {
160                                         asm_resp_json_arr[i++] = strdup(disc_resp->asm_response_json);
161                                         data_len++;
162                                 }
163                                 asm_resp_list_iter = g_list_next(asm_resp_list_iter);
164                         }
165
166                    __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NONE,
167                                                                                    asm_resp_json_arr, data_len);
168                 }
169                 else
170                    __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NOT_SUPPORTED,
171                                                                                    NULL, 0);
172         }
173
174         if (asm_resp_list != NULL)
175                 g_list_free_full(asm_resp_list, __free_asm_discover_response_list_item);
176 }
177
178 static void
179 _send_process_response(_process_cb_data_t *cb_data, int tz_err_code, char *uaf_response_json)
180 {
181         _INFO("_send_process_response");
182
183         /*TODO*/
184         _dbus_info_t *dbus_info = (_dbus_info_t *)(cb_data->dbus_info);
185         if (dbus_info != NULL)
186         {
187                 if (cb_data->type == _PROCESS_TYPE_CHECK_POLICY) {
188                         _INFO("before fido_complete_fido_uaf_check_policy");
189                         fido_complete_fido_uaf_check_policy(dbus_info->dbus_obj, dbus_info->invocation, tz_err_code);
190                         goto CATCH;
191                 }
192
193                 _INFO("before fido_complete_fido_uaf_process_operation");
194
195                 if (uaf_response_json != NULL)
196                         fido_complete_fido_uaf_process_operation(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NONE,
197                                                                                            uaf_response_json);
198                 else
199                         fido_complete_fido_uaf_process_operation(dbus_info->dbus_obj, dbus_info->invocation, tz_err_code, _EMPTY_JSON_STRING);
200         }
201
202 CATCH:
203         SAFE_DELETE(uaf_response_json);
204         _free_message(cb_data->uaf_req);
205
206         SAFE_DELETE(cb_data->dbus_info);
207
208         if (cb_data->type == _PROCESS_TYPE_AUTH)
209                 _free_fido_asm_auth_in((_fido_asm_auth_in_t*)(cb_data->asm_in));
210         else if (cb_data->type == _PROCESS_TYPE_REG)
211                 _free_fido_asm_reg_in((_fido_asm_reg_in_t*)(cb_data->asm_in));
212         else if (cb_data->type == _PROCESS_TYPE_DEREG)
213                 _free_fido_asm_dereg_in((_fido_asm_dereg_in_t*)(cb_data->asm_in));
214         else
215                 SAFE_DELETE(cb_data->asm_in);
216
217         SAFE_DELETE(cb_data);
218 }
219
220 void
221 _discover_response_intermediate_cb(GList *asm_response_list, void *user_data)
222 {
223         _INFO("_discover_response_intermediate_cb");
224
225         _fido_discover_asm_cb_data_t *cb_data = (_fido_discover_asm_cb_data_t *)user_data;
226
227         int error = FIDO_ERROR_NONE;
228         GList *asm_auth_list = NULL;
229
230         if (asm_response_list == NULL)
231                 _ERR("Discover response failed");
232         else {
233                 asm_auth_list = _uaf_parser_parse_asm_response_discover(asm_response_list, &error);
234         }
235
236         (cb_data->cb)(error, 0, asm_auth_list, cb_data->user_data);
237
238         if (asm_response_list != NULL)
239                 g_list_free_full(asm_response_list, __free_asm_discover_response_list_item);
240 }
241
242 static int
243 __fido_uaf_discover_internal(_fido_discover_asm_cb callback, void *user_data)
244 {
245         _INFO("__fido_uaf_discover_internal");
246
247         _fido_discover_asm_cb_data_t *cb_data_inter_mediate = (_fido_discover_asm_cb_data_t *) calloc(1, sizeof(_fido_discover_asm_cb_data_t));
248         cb_data_inter_mediate->cb = callback;
249         cb_data_inter_mediate->user_data = user_data;
250
251         return _asm_plugin_mgr_discover_all(_discover_response_intermediate_cb, cb_data_inter_mediate);
252 }
253
254 static void
255 _asm_response_auth_process(int error_code, const char *asm_response_json, void *user_data)
256 {
257         _INFO("_asm_response_auth_process");
258
259         if (user_data == NULL)
260                 _ERR("user_data is NULL");
261
262         _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data;
263         if (cb_data == NULL) {
264                 _ERR("_process_cb_data_t not found");
265                 return;
266         }
267
268         _INFO("error_code = [%d]", error_code);
269
270         if (error_code != 0) {
271                 _ERR("ASM response contains error code [%d]", error_code);
272                 _send_process_response((_process_cb_data_t *)user_data, error_code, NULL);
273                 return;
274         }
275
276         _asm_out_t *asm_out = NULL;
277
278         _INFO("before _uaf_parser_parse_asm_response_auth");
279
280         int parser_err = 0;
281         asm_out = _uaf_parser_parse_asm_response_auth(asm_response_json, &parser_err);
282         if (parser_err != 0 || asm_out == NULL) {
283                 _ERR("_uaf_parser_parse_asm_response_auth failed");
284
285                 int uaf_err_code = _convert_asm_status_code_to_uaf_error(parser_err);
286                 if (uaf_err_code == FIDO_ERROR_NONE)
287                         _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
288                 else
289                         _send_process_response(cb_data, uaf_err_code, NULL);
290
291                 _free_asm_out(asm_out);
292                 asm_out = NULL;
293
294                 return;
295         }
296
297         _asm_auth_out_t *asm_auth_out = (_asm_auth_out_t*)(asm_out->response_data);
298
299         _fido_asm_auth_in_t *asm_auth_in = (_fido_asm_auth_in_t *) cb_data->asm_in;
300
301         _message_t *uaf_message = cb_data->uaf_req;
302
303         _op_header_t *header = uaf_message->header;
304
305         char *uaf_response_json = NULL;
306
307
308         /* TODO : Add logic to accumulate multiple auth response and form the assertion_list*/
309         GList *assertion_list = NULL;
310
311         _auth_reg_assertion_t *asst_data = (_auth_reg_assertion_t*)calloc(1, sizeof(_auth_reg_assertion_t));
312
313         _INFO("before assertion");
314         asst_data->assertion = strdup(asm_auth_out->assertion);
315
316         _INFO("before assertion_schm");
317         asst_data->assertion_schm = strdup(asm_auth_out->assertion_scheme);
318
319         assertion_list = g_list_append(assertion_list, asst_data);
320
321         assertion_list = g_list_first(assertion_list);
322
323
324         _INFO("before _uaf_composer_compose_uaf_process_response_auth");
325         parser_err = _uaf_composer_compose_uaf_process_response_auth(header, asm_auth_in->final_challenge,
326                                                                                                    assertion_list, &uaf_response_json);
327
328         g_list_free_full(assertion_list, _free_auth_reg_assertion_list_item);
329
330         _free_asm_out(asm_out);
331         asm_out = NULL;
332
333         if (parser_err != 0) {
334                 _ERR("_uaf_composer_compose_uaf_process_response_auth failed");
335                 _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_INVALID_PARAMETER, NULL);
336                 return;
337         }
338
339         _send_process_response(cb_data, FIDO_ERROR_NONE, uaf_response_json);
340 }
341
342 static void
343 _asm_response_reg_process(int error_code, const char *asm_response_json, void *user_data)
344 {
345         _INFO("_asm_response_reg_process");
346
347         _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data;
348         if (cb_data == NULL)
349                 return;
350
351         if (error_code != 0) {
352                 _ERR("ASM response contains error code [%d]", error_code);
353
354                 _send_process_response((_process_cb_data_t *)user_data, error_code, NULL);
355
356                 return;
357         }
358
359         _asm_out_t *asm_out = NULL;
360         int parser_err = 0;
361         asm_out = _uaf_parser_parse_asm_response_reg(asm_response_json, &parser_err);
362         if (parser_err != 0 || asm_out == NULL) {
363                 _ERR("_uaf_parser_parse_asm_response_reg failed");
364
365                 int uaf_err_code = _convert_asm_status_code_to_uaf_error(parser_err);
366                 if (uaf_err_code == FIDO_ERROR_NONE)
367                         _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
368                 else
369                         _send_process_response((_process_cb_data_t *)user_data, uaf_err_code, NULL);
370
371                 _free_asm_out(asm_out);
372
373                 return;
374         }
375
376         _asm_reg_out_t *asm_reg_out = (_asm_reg_out_t*)(asm_out->response_data);
377
378         _fido_asm_reg_in_t *asm_reg_in = (_fido_asm_reg_in_t *)(cb_data->asm_in);
379
380         _message_t *uaf_req = cb_data->uaf_req;
381         _op_header_t *header = uaf_req->header;
382
383         char *uaf_response_json = NULL;
384
385         /* TODO : Add logic to accumulate multiple auth response and form the assertion_list*/
386         _auth_reg_assertion_t *ass_data = (_auth_reg_assertion_t*) calloc(1, sizeof(_auth_reg_assertion_t));
387         ass_data->assertion = __dup_string(asm_reg_out->assertion);
388         ass_data->assertion_schm = __dup_string(asm_reg_out->assertion_schm);
389
390
391         _free_asm_out(asm_out);
392         asm_out = NULL;
393
394         GList *ass_list = NULL;
395         ass_list = g_list_append(ass_list, ass_data);
396
397         parser_err = _uaf_composer_compose_uaf_process_response_reg(header, asm_reg_in->final_challenge,
398                                                                                                    ass_list, &uaf_response_json);
399
400         g_list_free_full(ass_list, _free_auth_reg_assertion_list_item);
401
402         if (parser_err != 0) {
403                 _ERR("_uaf_composer_compose_uaf_process_response_reg failed");
404                 _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_INVALID_PARAMETER, NULL);
405                 return;
406         }
407
408         _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_NONE, uaf_response_json);
409 }
410
411 static void
412 __handle_reg(_process_cb_data_t *cb_data, _matched_auth_data_t *matched_auth)
413 {
414         _INFO("");
415
416         _message_t *uaf_req = (_message_t *)(cb_data->uaf_req);
417
418         _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data);
419
420         _fido_asm_reg_in_t *reg_in = (_fido_asm_reg_in_t*) calloc(1, sizeof(_fido_asm_reg_in_t));
421
422         /*If no app-id mentioned in UAF request*/
423         if (cb_data->uaf_req->header->app_id == NULL) {
424                 if (cb_data->uaf_req->facet_id == NULL) {
425                         _ERR("Failed to get app id");
426                         _send_process_response(cb_data, FIDO_ERROR_UNTRUSTED_FACET_ID, NULL);
427                         _free_fido_asm_reg_in(reg_in);
428                         return;
429                 }
430                 /* app id*/
431                 cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id);
432                 reg_in->app_id = strdup(cb_data->uaf_req->header->app_id);
433         }
434         else {
435                 /* app id*/
436                 reg_in->app_id = strdup(cb_data->uaf_req->header->app_id);
437         }
438
439         /* user name */
440         if (uaf_reg_req->user_name != NULL)
441                 reg_in->user_name = strdup(uaf_reg_req->user_name);
442
443         _INFO("");
444
445         char *fc_json = _uaf_composer_compose_final_challenge(reg_in->app_id, uaf_reg_req->challenge,
446                                                                                                                   uaf_req->facet_id, cb_data->uaf_req->channel_binding);
447
448         if (fc_json == NULL) {
449                 _ERR("Failed to compose final challenge");
450                 _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
451                 _free_fido_asm_reg_in(reg_in);
452                 return;
453         }
454
455         _INFO("");
456         /* Final challenge */
457         reg_in->final_challenge = fc_json;
458
459         int auth_idx_int = -1;
460         sscanf(matched_auth->auth_index, "%d", &auth_idx_int);
461
462         reg_in->attestation_type = matched_auth->att_type;
463
464         _version_t *version = (_version_t *)calloc(1, sizeof(_version_t));
465         version->major = _VERSION_MAJOR;
466         version->minor = _VERSION_MINOR;
467
468         char *asm_req_json = NULL;
469
470         cb_data->asm_in = reg_in;
471
472         _INFO("");
473         int ret = _uaf_composer_compose_asm_reg_request(version, auth_idx_int, reg_in, &asm_req_json);
474         if (ret == 0 && asm_req_json != NULL)
475                 _asm_ipc_send(matched_auth->asm_id,
476                                           asm_req_json, _asm_response_reg_process, cb_data);
477         else
478                 _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
479
480         SAFE_DELETE(asm_req_json);
481         SAFE_DELETE(version);
482
483 }
484
485 static GList *
486 __copy_convert_uaf_trans_list(GList *uaf_tr_list)
487 {
488         RET_IF_FAIL(uaf_tr_list != NULL, NULL);
489
490         GList *asm_tr_list = NULL;
491
492         GList *uaf_tr_list_iter = g_list_first(uaf_tr_list);
493         while (uaf_tr_list_iter != NULL) {
494
495                 _auth_transaction_t *uaf_tr = (_auth_transaction_t*)(uaf_tr_list_iter->data);
496
497                 _fido_asm_transaction_t *asm_tr = calloc(1, sizeof(_fido_asm_transaction_t));
498
499                 asm_tr->content = __dup_string(uaf_tr->content);
500                 asm_tr->content_type = __dup_string(uaf_tr->content_type);
501                 if (uaf_tr->display_charac != NULL) {
502                         asm_tr->display_charac = calloc(1, sizeof(_fido_asm_display_png_characteristics_descriptor_t));
503
504                         asm_tr->display_charac->bit_depth = uaf_tr->display_charac->bit_depth;
505                         asm_tr->display_charac->color_type = uaf_tr->display_charac->color_type;
506                         asm_tr->display_charac->compression = uaf_tr->display_charac->compression;
507                         asm_tr->display_charac->filter = uaf_tr->display_charac->filter;
508                         asm_tr->display_charac->height = uaf_tr->display_charac->height;
509                         asm_tr->display_charac->interlace = uaf_tr->display_charac->interlace;
510                         asm_tr->display_charac->width = uaf_tr->display_charac->width;
511
512                         if (uaf_tr->display_charac->plte != NULL) {
513
514                                 GList *uaf_plte_iter = g_list_first(uaf_tr->display_charac->plte);
515                                 while (uaf_plte_iter != NULL) {
516                                         fido_rgb_pallette_entry_s *uaf_plte_entry = (fido_rgb_pallette_entry_s*)(uaf_plte_iter->data);
517
518                                         fido_rgb_pallette_entry_s *asm_plte_entry = calloc(1, sizeof(fido_rgb_pallette_entry_s));
519                                         asm_plte_entry->r = uaf_plte_entry->r;
520                                         asm_plte_entry->g = uaf_plte_entry->g;
521                                         asm_plte_entry->b = uaf_plte_entry->b;
522
523                                         asm_tr->display_charac->plte = g_list_append(asm_tr->display_charac->plte, asm_plte_entry);
524
525                                         uaf_plte_iter = uaf_plte_iter->next;
526                                 }
527                         }
528                 }
529
530                 asm_tr_list = g_list_append(asm_tr_list, asm_tr);
531
532                 uaf_tr_list_iter = uaf_tr_list_iter->next;
533         }
534
535         if (asm_tr_list != NULL) {
536                 asm_tr_list = g_list_first(asm_tr_list);
537                 _INFO("Trans list = [%d]", g_list_length(asm_tr_list));
538         }
539         return asm_tr_list;
540 }
541
542 static GList*
543 __copy_string_list(GList *src)
544 {
545         _INFO("");
546
547         RET_IF_FAIL(src != NULL, NULL);
548
549         GList *dest = NULL;
550
551         GList *iter = g_list_first(src);
552         while (iter != NULL) {
553                 char *str = (char*)(iter->data);
554                 dest = g_list_append(dest, strdup(str));
555
556                 iter = iter->next;
557                 _INFO("");
558         }
559
560         _INFO("");
561         return dest;
562 }
563
564 static void
565 __handle_auth(_process_cb_data_t *cb_data, _matched_auth_data_t *matched_auth)
566 {
567         _INFO("__handle_auth");
568
569         _auth_request_t *uaf_auth_req = (_auth_request_t*)(cb_data->uaf_req->data);
570
571         _fido_asm_auth_in_t *auth_asm_in = (_fido_asm_auth_in_t*)calloc(1, sizeof(_fido_asm_auth_in_t));
572
573         if (cb_data->uaf_req->header->app_id == NULL) {
574
575                 if (cb_data->uaf_req->facet_id == NULL) {
576                         _ERR("Failed to get app id");
577                         _send_process_response(cb_data, FIDO_ERROR_PERMISSION_DENIED, NULL);
578                         _free_fido_asm_auth_in(auth_asm_in);
579                         return;
580                 }
581                 cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id);
582                 auth_asm_in->app_id = strdup(cb_data->uaf_req->facet_id);
583         }
584         else {
585                 auth_asm_in->app_id = strdup(cb_data->uaf_req->header->app_id);
586         }
587
588         char *fc_json = _uaf_composer_compose_final_challenge(cb_data->uaf_req->header->app_id,
589                                                                                                                   uaf_auth_req->challenge, cb_data->uaf_req->facet_id,
590                                                                                                                   cb_data->uaf_req->channel_binding);
591         if (fc_json == NULL) {
592                 _ERR("Failed to compose final challenge");
593                 _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
594
595                 _free_fido_asm_auth_in(auth_asm_in);
596                 return;
597         }
598
599         /*keyIDs*/
600         auth_asm_in->key_ids = __copy_string_list(matched_auth->key_ids);
601
602         /* Final challenge */
603         auth_asm_in->final_challenge = fc_json;
604
605         /*Transaction*/
606         auth_asm_in->trans_list = __copy_convert_uaf_trans_list(uaf_auth_req->transaction_list);
607
608
609         cb_data->asm_in = auth_asm_in;
610
611         char *asm_req_json = NULL;
612         _version_t *version = (_version_t *)calloc(1, sizeof(_version_t));
613         version->major = _VERSION_MAJOR;
614         version->minor = _VERSION_MINOR;
615
616         int auth_idx_int = -1;
617         sscanf(matched_auth->auth_index, "%d", &auth_idx_int);
618         if (auth_idx_int == -1) {
619                 _ERR("ASM in data missing");
620                 _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
621
622                 _free_fido_asm_auth_in(auth_asm_in);
623                 SAFE_DELETE(version);
624
625                 return;
626         }
627
628         int ret = _uaf_composer_compose_asm_auth_request(version, auth_idx_int, auth_asm_in, &asm_req_json);
629         if (ret == 0 && asm_req_json != NULL) {
630                 _asm_ipc_send(matched_auth->asm_id,
631                                           asm_req_json, _asm_response_auth_process, cb_data);
632         }
633         else {
634                 _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL);
635         }
636
637         SAFE_DELETE(version);
638         SAFE_DELETE(asm_req_json);
639 }
640
641 static void
642 _ui_response_callback(int error_code, _ui_auth_data_t *selected_auth_data, void *user_data)
643 {
644         if (selected_auth_data == NULL) {
645                         _ERR("User did not select any Authenticator");
646                         _send_process_response((_process_cb_data_t *)user_data, error_code, NULL);
647                         free(selected_auth_data);
648                         return;
649         }
650
651         _INFO("User selected [%s] authenticator index", selected_auth_data->auth_index);
652
653         _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data;
654
655
656         _matched_auth_data_t *match_data = (_matched_auth_data_t*)calloc(1, sizeof(_matched_auth_data_t));
657         match_data->att_type = selected_auth_data->att_type;
658         match_data->auth_index = selected_auth_data->auth_index;
659         match_data->asm_id = strdup(selected_auth_data->asm_id);
660
661         if (cb_data->type == _PROCESS_TYPE_REG)
662                 __handle_reg(cb_data, match_data);
663
664         if (cb_data->type == _PROCESS_TYPE_AUTH)
665                 __handle_auth(cb_data, match_data);
666
667         _free_matched_auth_data(match_data);
668
669 }
670
671 static void
672 _asm_response_dereg_process(int error_code, const char *asm_response_json, void *user_data)
673 {
674         _dereg_q_t *dereg_q = (_dereg_q_t*)(user_data);
675         _process_cb_data_t *cb_data = (_process_cb_data_t*)(dereg_q->cb_data);
676
677         if (cb_data == NULL)
678                 return;
679
680         /*Process next dereg*/
681         GQueue *q = (GQueue*) (dereg_q->dereg_asm_in_q);
682         if (g_queue_is_empty(q) == FALSE)
683                 __process_dereg_queue(user_data);
684         else {
685                 /*ASM does not return success/faliure for dereg*/
686                 _INFO("Ignoring ASM's response for dereg");
687                 _send_process_response((_process_cb_data_t *)cb_data, FIDO_ERROR_NONE, NULL);
688
689                 _INFO("Deleting dereg_asm_in_q");
690                 /*Elements were deleted during pop*/
691                 g_queue_free(dereg_q->dereg_asm_in_q);
692                 dereg_q->dereg_asm_in_q = NULL;
693                 _INFO("After Deleting dereg_asm_in_q");
694         }
695
696 }
697
698 static void
699 __process_dereg_queue(_dereg_q_t *dereg_q)
700 {
701         _INFO("__process_dereg_queue");
702
703         GQueue *q = dereg_q->dereg_asm_in_q;
704         if (q == NULL)
705                 return;
706
707         if (g_queue_is_empty(q) == true) {
708                 _INFO("Deleting dereg_asm_in_q");
709                 g_queue_free(dereg_q->dereg_asm_in_q);
710                 dereg_q->dereg_asm_in_q = NULL;
711                 _INFO("After Deleting dereg_asm_in_q");
712                 return;
713         }
714
715         _process_cb_data_t *cb_data = (_process_cb_data_t*)(dereg_q->cb_data);
716         _message_t *uaf_message = cb_data->uaf_req;
717
718         _matched_auth_dereg_t *dereg_data = (_matched_auth_dereg_t*)(g_queue_pop_head(q));
719
720         char *asm_req_json = NULL;
721
722         int auth_index_int = _INVALID_INT;
723         sscanf(dereg_data->auth_index, "%d", &auth_index_int);
724
725         _INFO("Auth index for dereg req = [%d]", auth_index_int);
726
727         int ret = _uaf_composer_compose_asm_dereg_request(uaf_message->header->version, auth_index_int,
728                                                                                                           dereg_data, &asm_req_json);
729
730         /*TODO : ASM does not return anything for dereg, so do not wait for response, send back
731         * success always.
732         */
733         if (ret == 0 && asm_req_json != NULL) {
734                 _asm_ipc_send(dereg_data->asm_id,
735                                           asm_req_json, _asm_response_dereg_process, dereg_q);
736         }
737         else {
738                 _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL);
739         }
740
741         _free_matched_auth_dereg(dereg_data);
742         SAFE_DELETE(asm_req_json);
743
744 }
745
746 static GList*
747 __get_keyid_list_from_app_reg(GList *app_reg_list)
748 {
749         _INFO("__get_keyid_list_from_app_reg");
750
751         RET_IF_FAIL(app_reg_list != NULL, NULL);
752
753         GList *key_id_list = NULL;
754
755         GList *app_reg_list_iter = g_list_first(app_reg_list);
756         while (app_reg_list_iter != NULL) {
757
758                 _asm_app_reg_t *app_reg = (_asm_app_reg_t*)(app_reg_list_iter->data);
759                 if (app_reg != NULL) {
760
761                         if (app_reg->key_id_list != NULL) {
762                                 GList *key_id_list_iter = g_list_first(app_reg->key_id_list);
763                                 while (key_id_list_iter != NULL) {
764                                         char *key_id = (char*)(key_id_list_iter->data);
765                                         if (key_id != NULL) {
766                                                 key_id_list = g_list_append(key_id_list, strdup(key_id));
767                                                 _INFO("[%s]", key_id);
768                                         }
769
770                                         key_id_list_iter = key_id_list_iter->next;
771                                 }
772                         }
773                 }
774
775                 app_reg_list_iter = app_reg_list_iter->next;
776         }
777
778         return key_id_list;
779 }
780
781 static GList *
782 __get_auth_list_with_keyids(GList *available_authenticators)
783 {
784         _INFO("__get_auth_list_with_keyids");
785
786         GList *available_authenticators_full = NULL;
787
788         GList *avl_auth_iter = g_list_first(available_authenticators);
789         while (avl_auth_iter != NULL) {
790
791                 fido_authenticator_s *asm_auth = (fido_authenticator_s*)(avl_auth_iter->data);
792                 if (asm_auth != NULL) {
793                         char *get_reg_json = _uaf_composer_compose_get_registrations_request(asm_auth->auth_index);
794                         char *get_reg_resp = _asm_ipc_send_sync(asm_auth->asm_id, get_reg_json);
795
796                         if (get_reg_resp != NULL)
797                                 _INFO("_asm_ipc_send_sync = [%s]", get_reg_resp);
798
799                         _asm_get_reg_out_t *get_reg_out = _uaf_parser_parser_asm_get_reg_response(get_reg_resp);
800                         if (get_reg_out != NULL) {
801                                 asm_auth->key_ids = __get_keyid_list_from_app_reg(get_reg_out->app_reg_list);
802                                 asm_auth->key_ids = g_list_first(asm_auth->key_ids);
803                                 _INFO(" asm_auth->key_ids count = [%d]",  g_list_length(asm_auth->key_ids));
804                         }
805                         available_authenticators_full = g_list_append(available_authenticators_full, asm_auth);
806
807                         SAFE_DELETE(get_reg_json);
808                         SAFE_DELETE(get_reg_resp);
809                         _free_asm_get_reg_out(get_reg_out);
810
811                 }
812                 avl_auth_iter = avl_auth_iter->next;
813         }
814
815         return available_authenticators_full;
816 }
817
818 static void
819 __free_matched_dereg_auth_data_list_item(gpointer data)
820 {
821         RET_IF_FAIL_VOID(data != NULL);
822
823         _free_matched_auth_dereg((_matched_auth_dereg_t*)data);
824 }
825
826 static void
827 _discover_response_cb_for_process(int tz_error_code, int error_code, GList *available_authenticators, void *user_data)
828 {
829         _INFO("_discover_response_cb_for_process [%p]", user_data);
830
831         _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data;
832
833         if (tz_error_code != FIDO_ERROR_NONE) {
834                 _ERR("Failed to get available authenticator info [%d]", tz_error_code);
835                 _send_process_response(cb_data, FIDO_ERROR_NOT_SUPPORTED, NULL);
836                 return;
837         }
838
839         if (available_authenticators == NULL) {
840                 _ERR("No supported authenticators found");
841                 _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
842                 return;
843         }
844
845         _INFO("cb_data->type = [%d]", cb_data->type);
846
847         GList *available_authenticators_full = g_list_first(available_authenticators);
848
849         if (cb_data->type == _PROCESS_TYPE_CHECK_POLICY) {
850
851                 _INFO("_PROCESS_TYPE_CHECK_POLICY");
852
853                 if (cb_data->uaf_req->header->operation != NULL)
854                         _INFO("operation = [%s]", cb_data->uaf_req->header->operation);
855                 else
856                         _ERR("operation = [NULL]");
857
858                 if ((strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0)
859                                          || ((strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0))) {
860
861                         _policy_t *policy = NULL;
862
863                         if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0) {
864                                 _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data);
865                                 policy = uaf_reg_req->policy;
866                                  _INFO("_PROCESS_TYPE_CHECK_POLICY for reg");
867                         }
868                         else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0) {
869                                 _auth_request_t *uaf_auth_req = (_auth_request_t *)(cb_data->uaf_req->data);
870                                 policy = uaf_auth_req->policy;
871                                 _INFO("_PROCESS_TYPE_CHECK_POLICY for auth");
872                         }
873
874                         if (policy->is_keyid_present == true) {
875                                 /*Available authenticators' keyIDs can be fetched via GetRegistrations ASM op*/
876                                 _INFO("Need to call GetRegistrations to match policy");
877                                 GList *avl_auth_list_full_temp = __get_auth_list_with_keyids(available_authenticators);
878                                 if (avl_auth_list_full_temp != NULL) {
879                                         g_list_free(available_authenticators_full);
880
881                                         available_authenticators_full = g_list_first(avl_auth_list_full_temp);
882                                 }
883
884                         }
885                         GList *allowed_auth_list = _policy_checker_get_matched_auth_list(policy, available_authenticators_full);
886                         g_list_free_full(available_authenticators_full, _free_asm_auth_list);
887
888                         if ((allowed_auth_list != NULL) && g_list_length(allowed_auth_list) > 0) {
889
890                                 _send_process_response(cb_data, FIDO_ERROR_NONE, NULL);
891                         }
892                         else {
893                                 _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
894                         }
895
896                         if (allowed_auth_list != NULL)
897                                 g_list_free_full(allowed_auth_list, _free_matched_auth_data);
898
899                 }
900                 else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_DE_REG) == 0) {
901
902                         _dereg_request_t *dereg_req = (_dereg_request_t*)(cb_data->uaf_req->data);
903
904                         /* _matched_auth_dereg_t list*/
905                         if (cb_data->uaf_req->header->app_id == NULL)
906                                 cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id);
907
908                         GList *matched_auth_list = _policy_checker_get_matched_auth_list_dereg(cb_data->uaf_req->header->app_id, dereg_req->auth_info_list,
909                                                                                                                                                                    available_authenticators_full);
910                         g_list_free_full(available_authenticators_full, _free_asm_auth_list);
911
912                         if ((matched_auth_list != NULL) && g_list_length(matched_auth_list) > 0) {
913
914                                 _send_process_response(cb_data, FIDO_ERROR_NONE, NULL);
915                         }
916                         else {
917                                 _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
918                         }
919
920                         if (matched_auth_list != NULL)
921                                 g_list_free_full(matched_auth_list, __free_matched_dereg_auth_data_list_item);
922
923                 }
924
925                 return;
926         }
927         if (cb_data->type == _PROCESS_TYPE_DEREG) {
928
929
930                 _dereg_request_t *dereg_req = (_dereg_request_t*)(cb_data->uaf_req->data);
931
932                 if (cb_data->uaf_req->header->app_id == NULL)
933                         cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id);
934
935                 /* _matched_auth_dereg_t list*/
936                 GList *matched_auth_list = _policy_checker_get_matched_auth_list_dereg(cb_data->uaf_req->header->app_id, dereg_req->auth_info_list,
937                                                                                                                                                            available_authenticators_full);
938
939                 g_list_free_full(available_authenticators_full, _free_asm_auth_list);
940
941                 if (matched_auth_list == NULL){
942                         _ERR("No supported authenticators found");
943                         _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
944                         return;
945                 }
946
947                 _dereg_q_t *dereg_q = (_dereg_q_t*) calloc(1, sizeof(_dereg_q_t));
948
949                 GList *matched_auth_list_iter = g_list_first(matched_auth_list);
950                 while (matched_auth_list_iter != NULL) {
951                         _matched_auth_dereg_t *dereg_auth_matched = (_matched_auth_dereg_t*) (matched_auth_list_iter->data);
952
953                         if (dereg_auth_matched != NULL) {
954                                 GQueue *q = dereg_q->dereg_asm_in_q;
955
956                                 if (q == NULL)
957                                         dereg_q->dereg_asm_in_q = g_queue_new();
958
959                                 g_queue_push_head(dereg_q->dereg_asm_in_q, dereg_auth_matched);
960                         }
961                         matched_auth_list_iter = matched_auth_list_iter->next;
962                 }
963
964                 /*The elements will be deleted while freeing dereg_q->dereg_asm_in_q*/
965                 g_list_free(matched_auth_list);
966
967                 dereg_q->cb_data = cb_data;
968
969                 __process_dereg_queue(dereg_q);
970
971                 return;
972         }
973
974         _policy_t *policy = NULL;
975
976         if (cb_data->type == _PROCESS_TYPE_REG) {
977                 _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data);
978                 policy = uaf_reg_req->policy;
979         }
980         else if (cb_data->type == _PROCESS_TYPE_AUTH) {
981                 _auth_request_t *uaf_auth_req = (_auth_request_t *)(cb_data->uaf_req->data);
982                 policy = uaf_auth_req->policy;
983         }
984         else {
985                 _send_process_response(cb_data, FIDO_ERROR_UNKNOWN, NULL);
986                 return;
987         }
988
989         if (policy->is_keyid_present == true) {
990                 /*Available authenticators' keyIDs can be fetched via GetRegistrations ASM op*/
991                 _INFO("Need to call GetRegistrations to match policy");
992                 GList *avl_auth_list_full_temp = __get_auth_list_with_keyids(available_authenticators);
993                 if (avl_auth_list_full_temp != NULL) {
994                         g_list_free(available_authenticators_full);
995                         available_authenticators_full = g_list_first(avl_auth_list_full_temp);
996                 }
997
998         }
999
1000         GList *allowed_auth_list = _policy_checker_get_matched_auth_list(policy, available_authenticators_full);
1001         g_list_free_full(available_authenticators_full, _free_asm_auth_list);
1002
1003         if (allowed_auth_list == NULL){
1004                 _ERR("No supported authenticators found");
1005                 _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL);
1006
1007                 return;
1008         }
1009
1010         _INFO("");
1011         allowed_auth_list = g_list_first(allowed_auth_list);
1012
1013         if (g_list_length(allowed_auth_list) > 1) {
1014                 _INFO("");
1015
1016                 GList *ui_data_list = NULL;
1017
1018                 GList *allowed_auth_list_iter = allowed_auth_list;
1019                 while (allowed_auth_list_iter != NULL) {
1020                         _matched_auth_data_t *match_data = (_matched_auth_data_t *)(allowed_auth_list_iter->data);
1021
1022                         if (match_data != NULL) {
1023
1024                                 _ui_auth_data_t *ui_data = (_ui_auth_data_t*) calloc(1, sizeof(_ui_auth_data_t));
1025                                 if (match_data->asm_id != NULL)
1026                                         ui_data->asm_id = strdup(match_data->asm_id);
1027                                 else
1028                                         _ERR("No ASM id found to send to UI!!");
1029
1030                                 ui_data->auth_index = strdup(match_data->auth_index);
1031                                 ui_data->att_type = match_data->att_type;
1032
1033                                 ui_data->label = strdup(match_data->label);
1034
1035                                 ui_data_list = g_list_append(ui_data_list, ui_data);
1036
1037                                 allowed_auth_list_iter = allowed_auth_list_iter->next;
1038                         }
1039                 }
1040
1041                 int ret = _auth_ui_selector_send(ui_data_list, _ui_response_callback, cb_data);
1042                 if (ret != 0) {
1043                         _ERR("Failed to invoke selector UI");
1044                         _send_process_response(cb_data, FIDO_ERROR_NOT_SUPPORTED, NULL);
1045                         if (allowed_auth_list != NULL)
1046                                 g_list_free_full(allowed_auth_list, _free_matched_auth_data);
1047                         return;
1048                 }
1049         }
1050         else {
1051                 _INFO("");
1052                 GList *allowed_auth_list_iter = allowed_auth_list;
1053                 _matched_auth_data_t *match_data = (_matched_auth_data_t *)(allowed_auth_list_iter->data);
1054
1055                 if (cb_data->type == _PROCESS_TYPE_REG)
1056                         __handle_reg(cb_data, match_data);
1057
1058                 else if (cb_data->type == _PROCESS_TYPE_AUTH)
1059                         __handle_auth(cb_data, match_data);
1060
1061         }
1062         if (allowed_auth_list != NULL)
1063                 g_list_free_full(allowed_auth_list, _free_matched_auth_data);
1064
1065 }
1066
1067 static int
1068 _handle_process_message(_process_cb_data_t *cb_data)
1069 {
1070         return __fido_uaf_discover_internal(_discover_response_cb_for_process, cb_data);
1071 }
1072
1073 static void
1074 __facet_id_cb(int err, const char *facet_id, void *user_data)
1075 {
1076         _INFO("__facet_id_cb");
1077         if (facet_id != NULL)
1078                 _INFO("[%s]", facet_id);
1079
1080         _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data;
1081
1082         if (err != FIDO_ERROR_NONE || facet_id == NULL) {
1083                 _send_process_response(cb_data, err, NULL);
1084                 return;
1085         }
1086
1087         cb_data->uaf_req->facet_id = strdup(facet_id);
1088
1089         int error_code = FIDO_ERROR_NONE;
1090
1091         if (cb_data->type != _PROCESS_TYPE_CHECK_POLICY) {
1092
1093                 /**
1094                  * 1. Extract embedded policy to find the suitable authenticator(s)
1095                  * 2. Show UI to let user select one, if (1) gives multiple result.
1096                  * 3. Compose ASMRequest in json format
1097                  * 4. Send the same to asm
1098                  * 5. Send the ASMResponse to application.
1099                  */
1100
1101                 if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0)
1102                         cb_data->type = _PROCESS_TYPE_REG;
1103
1104                 else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0)
1105                         cb_data->type = _PROCESS_TYPE_AUTH;
1106
1107                 else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_DE_REG) == 0)
1108                         cb_data->type = _PROCESS_TYPE_DEREG;
1109
1110                 else {
1111                          _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL);
1112                          return;
1113                 }
1114         }
1115
1116         error_code = _handle_process_message(cb_data);
1117
1118         if (error_code != FIDO_ERROR_NONE) {
1119                 _send_process_response(cb_data, error_code, NULL);
1120         }
1121 }
1122
1123 gboolean
1124 _dbus_on_fido_init(Fido *object, GDBusMethodInvocation *invocation)
1125 {
1126         fido_complete_fido_uaf_init(object, invocation, FIDO_ERROR_NONE);
1127
1128         return true;
1129 }
1130
1131 gboolean
1132 _dbus_on_fido_deinit(Fido *object, GDBusMethodInvocation *invocation)
1133 {
1134         if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) {
1135                 fido_complete_fido_uaf_deinit(object, invocation, FIDO_ERROR_PERMISSION_DENIED);
1136         }
1137         else {
1138                 //_auth_ui_selector_deinit();
1139                 fido_complete_fido_uaf_deinit(object, invocation, FIDO_ERROR_NONE);
1140         }
1141
1142         return true;
1143 }
1144
1145 gboolean
1146 _dbus_on_fido_discover(Fido *object, GDBusMethodInvocation *invocation)
1147 {
1148         _INFO("_dbus_on_fido_discover");
1149         if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) {
1150
1151                 __send_discover_response(object, invocation, FIDO_ERROR_PERMISSION_DENIED,
1152                                                                                 NULL, 0);
1153                 return true;
1154         }
1155
1156         _dbus_info_t *dbus_info = (_dbus_info_t *)calloc(1, sizeof(_dbus_info_t));
1157         dbus_info->dbus_obj = object;
1158         dbus_info->invocation = invocation;
1159
1160         int ret = _asm_plugin_mgr_discover_all(_asm_get_info_cb, dbus_info);
1161         if (ret != FIDO_ERROR_NONE) {
1162
1163                 _ERR("_asm_ipc_send failed = [%d]", ret);
1164                 __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NOT_SUPPORTED,
1165                                                                                 NULL, 0);
1166
1167                 SAFE_DELETE(dbus_info);
1168
1169         }
1170
1171         return true;
1172 }
1173
1174 gboolean
1175 _dbus_handle_process_or_check_policy(Fido *object, GDBusMethodInvocation *invocation, 
1176                                                                         const gchar *uaf_request_json, const gchar *channel_binding,
1177                                                                          _process_type_t type)
1178 {
1179
1180         _INFO("_dbus_handle_process_or_check_policy");
1181
1182         _process_cb_data_t *cb_data = (_process_cb_data_t*) calloc(1, sizeof(_process_cb_data_t));
1183         _dbus_info_t *dbus_info = (_dbus_info_t *)calloc(1, sizeof(_dbus_info_t));
1184         dbus_info->dbus_obj = object;
1185         dbus_info->invocation = invocation;
1186         cb_data->dbus_info = dbus_info;
1187         cb_data->type = type;
1188
1189         if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) {
1190                 _send_process_response(cb_data, FIDO_ERROR_PERMISSION_DENIED, NULL);
1191                 return true;
1192         }
1193
1194         if (uaf_request_json == NULL) {
1195                 _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
1196                 return true;
1197         }
1198
1199         _INFO("%s", uaf_request_json);
1200
1201         _message_t *uaf_message = _uaf_parser_parse_message(uaf_request_json, channel_binding);
1202         if (uaf_message == NULL) {
1203                 _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL);
1204                 return true;
1205         }
1206
1207
1208         cb_data->uaf_req = uaf_message;
1209
1210
1211         int ret = _verify_and_get_facet_id(uaf_message->header->app_id, invocation, __facet_id_cb, cb_data);
1212         if (ret != FIDO_ERROR_NONE) {
1213                 _send_process_response(cb_data, FIDO_ERROR_UNTRUSTED_FACET_ID, NULL);
1214                 return true;
1215         }
1216
1217         return true;
1218 }
1219
1220 gboolean
1221 _dbus_on_fido_uaf_is_supported(Fido *object, GDBusMethodInvocation *invocation,
1222                                                            const gchar *uaf_request_json)
1223 {
1224         _INFO("_dbus_on_fido_uaf_is_supported");
1225
1226         return _dbus_handle_process_or_check_policy(object, invocation, uaf_request_json, NULL,
1227                                                                                                 _PROCESS_TYPE_CHECK_POLICY);
1228 }
1229
1230 gboolean
1231 _dbus_on_fido_process_operation(Fido *object, GDBusMethodInvocation *invocation,
1232                                                                         const gchar *uaf_request_json, const gchar* channel_binding_json)
1233 {
1234         _INFO("_dbus_on_fido_process_operation");
1235
1236         return _dbus_handle_process_or_check_policy(object, invocation, uaf_request_json,
1237                                                                                                 channel_binding_json, _PROCESS_TYPE_MIN);
1238 }
1239
1240 /*gboolean
1241 _dbus_on_fido_uaf_notify_result(Fido *object, GDBusMethodInvocation *invocation, const gchar *arg_cookie, gint arg_respose_code,
1242                                                                 const gchar *uaf_response_json)
1243 {
1244         fido_complete_fido_uaf_notify_result(object, invocation, 0, 0);
1245         return true;
1246 }*/
1247
1248 static void
1249 on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data)
1250 {
1251                 dlog_print(DLOG_INFO, "FIDO", "on_bus_acquired");
1252
1253                 _INFO("on_bus_acquired [%s]", name);
1254
1255                 GDBusInterfaceSkeleton* interface = NULL;
1256                 fido_dbus_obj = fido_skeleton_new();
1257                 if (fido_dbus_obj == NULL) {
1258                         _ERR("fido_dbus_obj NULL!!");
1259                         return;
1260                 }
1261
1262                 dlog_print(DLOG_INFO, "FIDO", "G_DBUS_INTERFACE_SKELETON");
1263
1264                 interface = G_DBUS_INTERFACE_SKELETON(fido_dbus_obj);
1265                 if (!g_dbus_interface_skeleton_export(interface, connection, _FIDO_SERVICE_DBUS_PATH, NULL)) {
1266                         _ERR("export failed!!");
1267                         return;
1268                 }
1269
1270                 dlog_print(DLOG_INFO, "FIDO", "g_signal_connect");
1271
1272                 _INFO("connecting fido signals start");
1273
1274                 g_signal_connect(fido_dbus_obj, "handle_fido_uaf_init",
1275                                                 G_CALLBACK(_dbus_on_fido_init), NULL);
1276
1277                 g_signal_connect(fido_dbus_obj, "handle_fido_uaf_deinit",
1278                                                 G_CALLBACK(_dbus_on_fido_deinit), NULL);
1279
1280                 g_signal_connect(fido_dbus_obj, "handle_fido_uaf_discover",
1281                                                 G_CALLBACK(_dbus_on_fido_discover), NULL);
1282
1283                 g_signal_connect(fido_dbus_obj, "handle_fido_uaf_check_policy",
1284                         G_CALLBACK(_dbus_on_fido_uaf_is_supported), NULL);
1285
1286                 g_signal_connect(fido_dbus_obj, "handle_fido_uaf_process_operation",
1287                                                 G_CALLBACK(_dbus_on_fido_process_operation), NULL);
1288
1289 //        g_signal_connect(fido_dbus_obj, "handle_fido_uaf_notify_result",
1290 //                        G_CALLBACK(_dbus_on_fido_uaf_notify_result), NULL);
1291
1292                 g_signal_connect(fido_dbus_obj, "handle_ui_response",
1293                                                 G_CALLBACK(_auth_ui_selector_on_ui_response), NULL);
1294
1295                 if (_asm_plugin_mgr_init() != FIDO_ERROR_NONE) {
1296                         _ERR("Falied to init ASM plugin manager");
1297                         dlog_print(DLOG_INFO, "FIDO", "_asm_plugin_mgr_init failed");
1298                         exit(1);
1299                 }
1300
1301
1302 }
1303
1304 static void
1305 on_name_acquired (GDBusConnection *connection,
1306                                                 const gchar     *name,
1307                                                 gpointer         user_data)
1308 {
1309                 _INFO("on_name_acquired");
1310
1311 }
1312
1313 static void
1314 on_name_lost (GDBusConnection *connection,
1315                                                 const gchar     *name,
1316                                                 gpointer         user_data)
1317 {
1318                 _INFO("on_name_lost");
1319                 _asm_plugin_mgr_destroy();
1320                 exit (1);
1321 }
1322
1323 static bool
1324 __initialize_dbus(void)
1325 {
1326         _INFO("__initialize_dbus Enter");
1327
1328         owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
1329                                                          _FIDO_DBUS_NAME,
1330                                                          G_BUS_NAME_OWNER_FLAGS_NONE,
1331                                                          on_bus_acquired,
1332                                                          on_name_acquired,
1333                                                          on_name_lost,
1334                                                          NULL,
1335                                                          NULL);
1336
1337         _INFO("owner_id=[%d]", owner_id);
1338
1339         if(owner_id == 0) {
1340                         _INFO("gdbus own failed!!");
1341                         return false;
1342         }
1343
1344         _INFO("g_bus_own_name SUCCESS");
1345         return true;
1346 }
1347
1348 static void
1349 __initialize(void)
1350 {
1351 #if !GLIB_CHECK_VERSION(2,35,0)
1352         g_type_init();
1353 #endif
1354
1355         if (__initialize_dbus() == false) {
1356                 _ERR("DBUS Initialization Failed");
1357                 exit(1);
1358         }
1359 }
1360
1361 int
1362 main(void)
1363 {
1364         GMainLoop *mainloop = NULL;
1365
1366         dlog_print(DLOG_INFO, "FIDO", "start");
1367
1368         _INFO("Starting FIDO SVC");
1369
1370         mainloop = g_main_loop_new(NULL, FALSE);
1371
1372         __initialize();
1373
1374         g_main_loop_run(mainloop);
1375
1376         _INFO("Ending FIDO SVC");
1377         return 0;
1378 }