Use random generated BT UUID for Roaming Authentictor
[platform/core/account/fido-asm.git] / bt_roaming_agent / src / bt_server.c
1
2 #include <bluetooth.h>
3 #include "bt_server.h"
4
5 #include "AsmHelper.h"
6 #include "BTRoamingKeys.h"
7 #include "fido-client-ipc-stub.h"
8
9 #include <system_info.h>
10 #include <system_settings.h>
11 #include <net_connection.h>
12 #include <bluetooth.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #define RA_BT_SERVICE_UUID "8F5E6268-CFCD-4474-AFA2-0FEBFED72D73"
17 #define RA_LEN_DELIM ':'
18 #define RA_LEN_DELIM_STR ":"
19 #define DELIM_LEN 2
20 #define D_LEN_MAX_LEN 12
21
22 /*Proper error*/
23 #define ERR_RESP "ZXJyb3I"
24
25 typedef struct _bt_server {
26         char *client_addr;
27         bool is_authorized;
28         int server_socket_fd;
29         int client_socket_fd;
30         char *client_req;
31         int client_req_len;
32         int expected_len;
33         int rem_len;
34         int active_timer_id;
35 } bt_server_t;
36
37 typedef struct _bt_timer_info {
38         int timer_id;
39         bt_server_t *caller;
40 } bt_timer_info_t;
41
42 static bt_server_t *server = NULL;
43
44 static bt_server_t*
45 __create_server_handle(void)
46 {
47         bt_server_t *s = (bt_server_t*)calloc(1, sizeof(bt_server_t));
48         s->client_addr = NULL;
49         s->is_authorized = false;
50         s->server_socket_fd = -1;
51         s->client_socket_fd = -1;
52         s->client_req_len = 0;
53         s->client_req = NULL;
54         s->expected_len = 0;
55         s->rem_len = 0;
56         s->active_timer_id = 0;
57
58         return s;
59 }
60
61
62 static void
63 __destroy_server_handle(bt_server_t *s)
64 {
65         RET_IF_FAIL_VOID(s != NULL);
66
67         SAFE_DELETE(s->client_addr);
68         SAFE_DELETE(s->client_req);
69         s->client_req_len = 0;
70         SAFE_DELETE(s);
71 }
72
73 static Fidoasm*
74 __asm_get_dbus_proxy(void)
75 {
76 #if !GLIB_CHECK_VERSION(2, 35, 0)
77         g_type_init();
78 #endif
79
80         GDBusConnection *connection = NULL;
81         GError *error = NULL;
82
83         connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
84
85         /* Create the object */
86         Fidoasm *dbus_proxy = fidoasm_proxy_new_sync(connection,
87                                                 G_DBUS_PROXY_FLAGS_NONE,
88                                                                                                  "org.tizen.fidoasm",
89                                                                                                  "/org/tizen/fidoasm",
90                                                 NULL,
91                                                 &error);
92
93         if (error != NULL)
94                 _ERR("bluetooth bluetooth fidoasm_proxy_new_sync failed %s", error->message);
95
96         return dbus_proxy;
97 }
98
99
100 static void
101 __sock_state_changed_cb(int result, bt_socket_connection_state_e connection_state,
102                                                 bt_socket_connection_s *connection, void *user_data)
103 {
104         if (result != BT_ERROR_NONE) {
105                 _ERR("bluetooth [%d]", result);
106                 return;
107         }
108
109         if (connection_state == BT_SOCKET_CONNECTED) {
110                 _INFO("bluetooth Connected = [%s][%s][%d]", connection->remote_address, connection->service_uuid,
111                           connection->local_role);
112
113                 /*Allows only one*/
114                 SAFE_DELETE(server->client_addr);
115                 server->client_addr = _SAFE_DUP(connection->remote_address);
116                 return;
117         }
118
119         if (connection_state == BT_SOCKET_DISCONNECTED) {
120                 _INFO("bluetooth DisConnected = [%s][%s][%d]", connection->remote_address, connection->service_uuid,
121                           connection->local_role);
122                 return;
123         }
124 }
125
126 static int
127 __bt_send_data(int sock_fd, char *data)
128 {
129         if (data == NULL) {
130                 data = strdup(ERR_RESP);
131                 _ERR("bluetooth Failed returned from ASM");
132         }
133
134         int d_len = strlen(data);
135         int full_data_max_len = d_len + DELIM_LEN + D_LEN_MAX_LEN;
136         char *full_data = (char*)(calloc(full_data_max_len, sizeof(char)));
137
138         snprintf(full_data, full_data_max_len, "%d%s%s", d_len, RA_LEN_DELIM_STR, data);
139
140         int full_data_len = strlen(full_data);
141         _INFO("Sending data of len=[%d]", full_data_len);
142
143         int ret = bt_socket_send_data(sock_fd, full_data, full_data_len);
144         _INFO("bt_socket_send_data=[%d]", ret);
145
146         SAFE_DELETE(data);
147         SAFE_DELETE(full_data);
148
149         return 0;
150 }
151
152 static void
153 __receive_finished(bt_server_t *server)
154 {
155         if (server->client_req == NULL) {
156                 _ERR("bluetooth No request");
157                 return;
158         }
159
160         if (server->expected_len == 0) {
161                 _INFO("Ignoring timeout, since data received fully before timeout");
162                 return;
163         }
164
165         server->expected_len = 0;
166         server->rem_len = 0;
167
168         _INFO("bluetooth Total pack length = [%d]", server->client_req_len);
169
170         /*Call ASM dbus and receive the response*/
171         Fidoasm *asm_proxy = __asm_get_dbus_proxy();
172         if (asm_proxy == NULL) {
173                 _ERR("bluetooth bluetooth Failed to get ASM proxy");
174
175                 server->active_timer_id = 0;
176                 __bt_send_data(server->client_socket_fd, NULL);
177                 return;
178         }
179
180         /*const char *tlvReqB64 = server->client_req;*/
181         char *tlvReqB64 = (char*)calloc(server->client_req_len + 1, sizeof(char));
182         memcpy(tlvReqB64, server->client_req, server->client_req_len);
183
184         char *tlvRespB64 = NULL;
185         GError *gErr = NULL;
186         int tz_err = 0;
187         fidoasm_call_ra_request_sync(asm_proxy, tlvReqB64,
188                                                                   &tz_err, &tlvRespB64, NULL, &gErr);
189         if (tlvRespB64 == NULL) {
190
191                 server->active_timer_id = 0;
192                 __bt_send_data(server->client_socket_fd, NULL);
193                 return;
194         }
195
196         int ret = -1;
197         if (server->is_authorized == false) {
198                 ret = bt_device_set_authorization(server->client_addr, BT_DEVICE_AUTHORIZED);
199                 _INFO("bluetooth bt_device_set_authorization= [%d]", ret);
200         }
201
202         _INFO("%s", tlvRespB64);
203         int respLen = strlen(tlvRespB64);
204         _INFO("%d", respLen);
205         ret = __bt_send_data(server->client_socket_fd, tlvRespB64);
206
207         server->active_timer_id = 0;
208
209         /*TODO free client_req?*/
210         server->client_req = NULL;
211         server->client_req_len = 0;
212         server->client_socket_fd = -1;
213
214         return;
215 }
216
217 static void
218 __timer_expired(gpointer data)
219 {
220         _INFO("bluetooth __timer_expired");
221
222         bt_timer_info_t *bt_timer_info = (bt_timer_info_t*)data;
223         if (bt_timer_info == NULL)
224                 return;
225
226         bt_server_t *server = (bt_server_t*)bt_timer_info->caller;
227         if (server == NULL)
228                 return;
229
230         _INFO("timeout id=[%d], active id =[%d]", bt_timer_info->timer_id, server->active_timer_id);
231
232         if (bt_timer_info->timer_id != server->active_timer_id) {
233                 _INFO("timeout ignored");
234                 bt_timer_info->caller = NULL;
235                 free(bt_timer_info);
236                 return;
237         }
238
239         if (server->client_req == NULL) {
240                 _ERR("bluetooth No request");
241                 return;
242         }
243
244         if (server->expected_len == 0) {
245                 _INFO("Ignoring timeout, since data received fully before timeout");
246                 return;
247         }
248
249         server->expected_len = 0;
250         server->rem_len = 0;
251         server->active_timer_id = 0;
252         bt_timer_info->caller = NULL;
253         free(bt_timer_info);
254
255         /*TODO free client_req?*/
256         server->client_req = NULL;
257         server->client_req_len = 0;
258         server->client_socket_fd = -1;
259
260         return;
261 }
262
263 static gboolean
264 __discoverTimeOutCb(gpointer user_data)
265 {
266         _INFO("bluetooth bluetooth discoverTimeOutCb");
267
268         return G_SOURCE_REMOVE;
269 }
270
271 static void
272 __bt_sock_data_received_cb(bt_socket_received_data_s* data, void* user_data)
273 {
274         if (data == NULL) {
275                 _ERR("bluetooth No received data!");
276                 return;
277         }
278
279         _INFO("bluetooth Socket fd: %d", data->socket_fd);
280         _INFO("bluetooth Data: %s", data->data);
281         _INFO("bluetooth Size: %d", data->data_size);
282
283         char *pack = NULL;
284         int fullPackLen = 0;
285         int cur_pack_len = 0;
286         //bt_server_t *server = (bt_server_t*)user_data;
287         server->client_socket_fd = data->socket_fd;
288         /*Packets may arrive segmented, so use timer to get long data*/
289         if (server->client_req == NULL) {
290
291                 int recv_d_len = data->data_size;
292                 if (recv_d_len <= 0) {
293                         _ERR("Empty data frame");
294                         __bt_send_data(server->client_socket_fd, NULL);
295                         return;
296                 }
297
298                 int i = 0;
299
300                 while (1) {
301
302                         if (data->data[i] == RA_LEN_DELIM)
303                                 break;
304                         if ((i == data->data_size) || (data->data[i] == '\0')) {
305                                 i = 0;
306                                 break;
307                         }
308                         i++;
309                 }
310
311                 if (i <= 0) {
312                         _ERR("Missing :");
313                         __bt_send_data(server->client_socket_fd, NULL);
314                         return;
315                 }
316
317                 int d_first_frame_len = data->data_size - (i + 1);
318                 if (d_first_frame_len <= 0) {
319                         _ERR("Empty data frame following :");
320                         __bt_send_data(server->client_socket_fd, NULL);
321                         return;
322                 }
323
324                 char *d_len_str = (char*)calloc(12, sizeof(char));
325                 memcpy(d_len_str, data->data, i);
326                 /*snprintf(d_len_str, i, "%s", data->data);*/
327                 d_len_str[i] = '\0';
328                 _INFO("[%s]", d_len_str);
329
330                 int d_len = 0;
331                 sscanf(d_len_str, "%d", &d_len);
332
333                 _INFO("Data Len frame=[%d]", d_len);
334                 SAFE_DELETE(d_len_str);
335
336                 server->expected_len = d_len;
337
338                 pack = (char*)calloc(d_first_frame_len + 1, sizeof(char));
339                 char *data_pack = data->data;
340                 data_pack += i + 1;
341                 memcpy(pack, data_pack, d_first_frame_len);
342
343                 server->rem_len = server->expected_len - d_first_frame_len;
344                 cur_pack_len = d_first_frame_len;
345
346                 if (server->rem_len > 0) {
347                         _INFO("Need framing");
348                         bt_timer_info_t *bt_timer_info = (bt_timer_info_t*)calloc(1, sizeof(bt_timer_info_t));
349                         bt_timer_info->caller = server;
350                         if (server->active_timer_id > 1000)
351                                 server->active_timer_id = 0;
352                         else
353                                 server->active_timer_id++;
354
355                         bt_timer_info->timer_id = server->active_timer_id;
356
357                         _INFO("bluetooth bluetooth [%d] sec timeout starting", 6);
358                         g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 6, __discoverTimeOutCb, bt_timer_info,
359                                                                         __timer_expired);
360                 }
361
362         } else {
363
364                 pack = (char*)calloc(data->data_size, sizeof(char));
365                 memcpy(pack, data->data, data->data_size);
366
367                 server->rem_len = server->rem_len - data->data_size;
368                 cur_pack_len = data->data_size;
369         }
370
371         if (server->client_req != NULL)
372                 fullPackLen = cur_pack_len + server->client_req_len;
373         else
374                 fullPackLen = cur_pack_len;
375
376         char *fullPackNew = (char*)calloc(fullPackLen, sizeof(char));
377
378         if (server->client_req != NULL)
379                 memcpy(fullPackNew, server->client_req, server->client_req_len);
380
381         memcpy(fullPackNew + server->client_req_len, pack, cur_pack_len);
382
383         server->client_req_len = fullPackLen;
384         if (server->client_req != NULL)
385                 free(server->client_req);
386         server->client_req = fullPackNew;
387
388         free(pack);
389
390         if (server->rem_len <= 0) {
391                 _INFO("Received all");
392                 __receive_finished(server);
393         }
394 }
395
396 static void
397 __bt_authorization_changed_cb(bt_device_authorization_e authorization,
398                                                           char *remote_address, void *user_data)
399 {
400         _INFO("bluetooth Authorization changed=[%d][%s]", authorization, remote_address);
401         if (authorization == BT_DEVICE_AUTHORIZED)
402                 server->is_authorized = true;
403         else
404                 server->is_authorized = false;
405 }
406
407 /*
408  * Bonding is not performed via framework, user needs to pair manually, to ensure
409  * security.
410 */
411 static int
412 __start_rfcomm(bt_server_t *server_loc)
413 {
414         _INFO("");
415         static bool is_started = false;
416         if (is_started == false) {
417
418                 _INFO("bluetooth ");
419                 int sock_fd_temp = -1;
420                 int ret = bt_socket_create_rfcomm(RA_BT_SERVICE_UUID, &sock_fd_temp);
421                 if (ret != BT_ERROR_NONE) {
422                         _ERR("bluetooth bt_socket_create_rfcomm() failed.");
423                         return -1;
424                 }
425
426                 _INFO("bluetooth socket fd = [%d]", sock_fd_temp);
427                 server->server_socket_fd = sock_fd_temp;
428
429                 _INFO("bluetooth before bt_socket_set_connection_state_changed_cb");
430                 ret = bt_socket_set_connection_state_changed_cb(__sock_state_changed_cb,
431                                                                                                                 server);
432                 if (ret != BT_ERROR_NONE) {
433                         _ERR("bluetooth [bt_socket_listen_and_accept_rfcomm] failed.");
434                         return -1;
435                 }
436
437                 _INFO("bluetooth before bt_socket_listen_and_accept_rfcomm");
438                 ret = bt_socket_listen_and_accept_rfcomm(server->server_socket_fd, 1);
439                 if (ret != BT_ERROR_NONE) {
440                         _ERR("[bt_socket_listen_and_accept_rfcomm] failed.");
441                         return -1;
442                 }
443
444                 _INFO("bluetooth before bt_socket_set_data_received_cb");
445                 ret = bt_socket_set_data_received_cb(__bt_sock_data_received_cb, server);
446                 if (ret != BT_ERROR_NONE) {
447                         _ERR("[bt_socket_set_data_received_cb] failed.");
448                         return -1;
449                 }
450
451                  ret = bt_device_set_authorization_changed_cb(__bt_authorization_changed_cb, server);
452                 _INFO("bluetooth %d", ret);
453                 is_started = true;
454         }
455
456         _INFO("bluetooth ");
457         return 0;
458 }
459
460 static void
461 adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void* user_data)
462 {
463         _INFO("bluetooth %d", result);
464         _INFO("bluetooth %d", adapter_state);
465         if (adapter_state == BT_ADAPTER_ENABLED) {
466                 __start_rfcomm(user_data);
467         }
468 }
469
470 int
471 bt_server_start(void)
472 {
473         int ret = bt_initialize();
474         if (ret != BT_ERROR_NONE) {
475                 _ERR("bluetooth bt_socket_create_rfcomm() failed.");
476                 return -1;
477         }
478
479         server = __create_server_handle();
480
481         ret = bt_adapter_set_state_changed_cb(adapter_state_changed_cb, NULL);
482
483         bt_adapter_state_e adapter_state = BT_ADAPTER_ENABLED;
484
485         ret = bt_adapter_get_state(&adapter_state);
486         if (ret != BT_ERROR_NONE) {
487                 _ERR("bluetooth bt_socket_create_rfcomm() failed.");
488                 return -1;
489         }
490
491         _INFO("bluetooth %d", adapter_state);
492
493         if (adapter_state == BT_ADAPTER_ENABLED) {
494                 return __start_rfcomm(server);
495         }
496         return 0;
497 }
498
499 int
500 bt_server_stop(void)
501 {
502         _INFO("bluetooth ");
503         bt_socket_destroy_rfcomm(server->server_socket_fd);
504         __destroy_server_handle(server);
505         server = NULL;
506         int ret = bt_deinitialize();
507         _INFO("bt_deinitialize=[%d]", ret);
508         return 0;
509 }