Add a function to find all devices
[platform/core/connectivity/stc-manager.git] / src / stc-manager-gdbus.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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 #include "stc-manager-gdbus.h"
18 #include "stc-manager.h"
19 #include "stc-statistics.h"
20 #include "stc-restriction.h"
21 #include "stc-firewall.h"
22 #include "stc-pcap.h"
23 #include "stc-manager-util.h"
24 #include "stc-manager-plugin-appstatus.h"
25 #include "stc-manager-plugin-procfs.h"
26 #include "stc-manager-plugin-monitor.h"
27 #include "stc-manager-plugin-firewall.h"
28 #include "helper-iptables.h"
29
30 #define MANAGER_DBUS_ERROR_NAME "net.stc.manager.Error.Failed"
31
32 #define STC_MANAGER_DBUS_REPLY_ERROR(invocation, err_num) \
33         g_dbus_method_invocation_return_dbus_error((invocation), \
34                                                    MANAGER_DBUS_ERROR_NAME, \
35                                                    stc_err_strs[-(err_num)])
36
37 static const gchar *stc_err_strs[] = {
38         "ERROR_NONE",
39         "FAIL",
40         "DB_FAILED",
41         "OUT_OF_MEMORY",
42         "INVALID_PARAMETER",
43         "NO_DATA",
44         "ALREADY_DATA",
45         "UNINITIALIZED",
46         "PERMISSION_DENIED",
47         "NOTIMPL"
48 };
49
50 static gboolean __stc_manager_gdbus_statistics_init(stc_s *stc)
51 {
52         __STC_LOG_FUNC_ENTER__;
53         gboolean ret = TRUE;
54         gchar *s = NULL;
55
56         StcObjectSkeleton *object = NULL;
57         StcStatistics *statistics = NULL;
58         s = g_strdup_printf(STC_DBUS_SERVICE_STATISTICS_PATH);
59
60         /* Add interface to default object path */
61         object = stc_object_skeleton_new(s);
62         g_free(s);
63
64         /* Make the newly created object export the interface
65          * net.stc.statistics (note
66          * that @object takes its own reference to @statistics).
67          */
68
69         statistics = stc_statistics_skeleton_new();
70         stc_object_skeleton_set_statistics(object, statistics);
71         g_object_unref(statistics);
72
73         /* Register for method callbacks as signal callbacks */
74
75         g_signal_connect(statistics, "handle-init",
76                          G_CALLBACK(handle_statistics_init),
77                          stc);
78
79         g_signal_connect(statistics, "handle-get",
80                          G_CALLBACK(handle_statistics_get),
81                          stc);
82
83         g_signal_connect(statistics, "handle-get-all",
84                          G_CALLBACK(handle_statistics_get_all),
85                          stc);
86
87         g_signal_connect(statistics, "handle-reset",
88                          G_CALLBACK(handle_statistics_reset),
89                          stc);
90
91         /* Export the object (@manager takes its own reference to @object) */
92         g_dbus_object_manager_server_export(stc->obj_mgr,
93                                             G_DBUS_OBJECT_SKELETON(object));
94         g_object_unref(object);
95
96         stc->statistics_obj = (gpointer)statistics;
97
98         __STC_LOG_FUNC_EXIT__;
99         return ret;
100 }
101
102 static gboolean __stc_manager_gdbus_restriction_init(stc_s *stc)
103 {
104         __STC_LOG_FUNC_ENTER__;
105         gboolean ret = TRUE;
106         gchar *s = NULL;
107
108         StcObjectSkeleton *object = NULL;
109         StcRestriction *restriction = NULL;
110         s = g_strdup_printf(STC_DBUS_SERVICE_RESTRICTION_PATH);
111
112         /* Add interface to default object path */
113         object = stc_object_skeleton_new(s);
114         g_free(s);
115
116         /* Make the newly created object export the interface
117          * net.stc.restriction (note
118          * that @object takes its own reference to @restriction).
119          */
120
121         restriction = stc_restriction_skeleton_new();
122         stc_object_skeleton_set_restriction(object, restriction);
123         g_object_unref(restriction);
124
125         /* Register for method callbacks as signal callbacks */
126
127         g_signal_connect(restriction, "handle-set",
128                          G_CALLBACK(handle_restriction_set), stc);
129
130         g_signal_connect(restriction, "handle-get",
131                          G_CALLBACK(handle_restriction_get), stc);
132
133         g_signal_connect(restriction, "handle-get-all",
134                          G_CALLBACK(handle_restriction_get_all), stc);
135
136         g_signal_connect(restriction, "handle-get-type",
137                          G_CALLBACK(handle_restriction_get_type),
138                          stc);
139
140         g_signal_connect(restriction, "handle-unset",
141                          G_CALLBACK(handle_restriction_unset), stc);
142
143         /* Export the object (@manager takes its own reference to @object) */
144         g_dbus_object_manager_server_export(stc->obj_mgr,
145                                             G_DBUS_OBJECT_SKELETON(object));
146         g_object_unref(object);
147
148         stc->restriction_obj = (gpointer)restriction;
149
150         __STC_LOG_FUNC_EXIT__;
151         return ret;
152 }
153
154 static gboolean __stc_manager_gdbus_firewall_init(stc_s *stc)
155 {
156         __STC_LOG_FUNC_ENTER__;
157         gboolean ret = TRUE;
158         gchar *s = NULL;
159
160         StcObjectSkeleton *object = NULL;
161         StcFirewall *firewall = NULL;
162         s = g_strdup_printf(STC_DBUS_SERVICE_FIREWALL_PATH);
163
164         /* Add interface to default object path */
165         object = stc_object_skeleton_new(s);
166         g_free(s);
167
168         firewall = stc_firewall_skeleton_new();
169         stc_object_skeleton_set_firewall(object, firewall);
170         g_object_unref(firewall);
171
172         /* Register for method callbacks as signal callbacks */
173
174         g_signal_connect(firewall, "handle-lock",
175                          G_CALLBACK(handle_firewall_lock),
176                          stc);
177
178         g_signal_connect(firewall, "handle-unlock",
179                          G_CALLBACK(handle_firewall_unlock),
180                          stc);
181
182         g_signal_connect(firewall, "handle-get-lock",
183                          G_CALLBACK(handle_firewall_get_lock),
184                          stc);
185
186         g_signal_connect(firewall, "handle-add-chain",
187                          G_CALLBACK(handle_firewall_add_chain),
188                          stc);
189
190         g_signal_connect(firewall, "handle-remove-chain",
191                          G_CALLBACK(handle_firewall_remove_chain),
192                          stc);
193
194         g_signal_connect(firewall, "handle-flush-chain",
195                          G_CALLBACK(handle_firewall_flush_chain),
196                          stc);
197
198         g_signal_connect(firewall, "handle-get-all-chain",
199                          G_CALLBACK(handle_firewall_get_all_chain),
200                          stc);
201
202         g_signal_connect(firewall, "handle-set-chain",
203                          G_CALLBACK(handle_firewall_set_chain),
204                          stc);
205
206         g_signal_connect(firewall, "handle-unset-chain",
207                          G_CALLBACK(handle_firewall_unset_chain),
208                          stc);
209
210         g_signal_connect(firewall, "handle-add-rule",
211                          G_CALLBACK(handle_firewall_add_rule),
212                          stc);
213
214         g_signal_connect(firewall, "handle-remove-rule",
215                          G_CALLBACK(handle_firewall_remove_rule),
216                          stc);
217
218         g_signal_connect(firewall, "handle-update-rule",
219                          G_CALLBACK(handle_firewall_update_rule),
220                          stc);
221
222         g_signal_connect(firewall, "handle-get-all-rule",
223                          G_CALLBACK(handle_firewall_get_all_rule),
224                          stc);
225
226         /* Export the object (@manager takes its own reference to @object) */
227         g_dbus_object_manager_server_export(stc->obj_mgr,
228                                             G_DBUS_OBJECT_SKELETON(object));
229         g_object_unref(object);
230
231         stc->firewall_obj = (gpointer)firewall;
232
233         __STC_LOG_FUNC_EXIT__;
234         return ret;
235 }
236
237 static gboolean __stc_manager_gdbus_pcap_init(stc_s *stc)
238 {
239         __STC_LOG_FUNC_ENTER__;
240         gboolean ret = TRUE;
241         gchar *s = NULL;
242
243         StcObjectSkeleton *object = NULL;
244         StcPcap *pcap = NULL;
245         s = g_strdup_printf(STC_DBUS_SERVICE_PCAP_PATH);
246
247         /* Add interface to default object path */
248         object = stc_object_skeleton_new(s);
249         g_free(s);
250
251         pcap = stc_pcap_skeleton_new();
252         stc_object_skeleton_set_pcap(object, pcap);
253         g_object_unref(pcap);
254
255         /* Register for method callbacks as signal callbacks */
256
257         g_signal_connect(pcap, "handle-start",
258                          G_CALLBACK(handle_pcap_start),
259                          stc);
260
261         g_signal_connect(pcap, "handle-stop",
262                          G_CALLBACK(handle_pcap_stop),
263                          stc);
264
265         g_signal_connect(pcap, "handle-get-all",
266                          G_CALLBACK(handle_pcap_get_all),
267                          stc);
268
269         g_signal_connect(pcap, "handle-find-all-devs",
270                          G_CALLBACK(handle_pcap_find_all_devs),
271                          stc);
272
273         /* Export the object (@manager takes its own reference to @object) */
274         g_dbus_object_manager_server_export(stc->obj_mgr,
275                                             G_DBUS_OBJECT_SKELETON(object));
276         g_object_unref(object);
277
278         stc->pcap_obj = (gpointer)pcap;
279
280         __STC_LOG_FUNC_EXIT__;
281         return ret;
282 }
283
284 static gboolean __stc_manager_gdbus_manager_init(stc_s *stc)
285 {
286         __STC_LOG_FUNC_ENTER__;
287         gboolean ret = TRUE;
288         gchar *s = NULL;
289
290         StcObjectSkeleton *object = NULL;
291         StcManager *manager = NULL;
292         s = g_strdup_printf(STC_DBUS_SERVICE_MANAGER_PATH);
293
294         object = stc_object_skeleton_new(s);
295         g_free(s);
296
297         manager = stc_manager_skeleton_new();
298         stc_object_skeleton_set_manager(object, manager);
299         g_object_unref(manager);
300
301         g_signal_connect(manager, "handle-stop",
302                          G_CALLBACK(handle_manager_stop), stc);
303
304         g_signal_connect(manager, "handle-commit-iptables",
305                          G_CALLBACK(handle_manager_commit_iptables), stc);
306
307         g_signal_connect(manager, "handle-commit-ip6tables",
308                          G_CALLBACK(handle_manager_commit_ip6tables), stc);
309
310         g_dbus_object_manager_server_export(stc->obj_mgr,
311                                             G_DBUS_OBJECT_SKELETON(object));
312         g_object_unref(object);
313
314         stc->manager_obj = (gpointer)manager;
315
316         __STC_LOG_FUNC_EXIT__;
317         return ret;
318 }
319
320
321 static void __stc_manager_gdbus_on_bus_acquired(GDBusConnection *connection,
322                                                 const gchar *name,
323                                                 gpointer user_data)
324 {
325         __STC_LOG_FUNC_ENTER__;
326         stc_s* stc = (stc_s*)user_data;
327
328         stc->obj_mgr = g_dbus_object_manager_server_new("/net/stc");
329
330         STC_LOGD("path : %s", name);
331
332         stc->connection = connection;
333
334         if (__stc_manager_gdbus_statistics_init(stc) == FALSE) {
335                 STC_LOGE("Can not signal connect to statistics"); //LCOV_EXCL_LINE
336                 /* Deinitialize and quit manager */
337         }
338
339         if (__stc_manager_gdbus_restriction_init(stc) == FALSE) {
340                 STC_LOGE("Cannot signal connect to restriction"); //LCOV_EXCL_LINE
341                 /* Deinitialize and quit manager */
342         }
343
344         if (__stc_manager_gdbus_firewall_init(stc) == FALSE) {
345                 STC_LOGE("Cannot signal connect to firewall"); //LCOV_EXCL_LINE
346                 /* Deinitialize and quit manager */
347         }
348
349         if (__stc_manager_gdbus_pcap_init(stc) == FALSE) {
350                 STC_LOGE("Cannot signal connect to pcap"); //LCOV_EXCL_LINE
351                 /* Deinitialize and quit manager */
352         }
353
354         if (__stc_manager_gdbus_manager_init(stc) == FALSE) {
355                 STC_LOGE("Cannot signal connect to manager"); //LCOV_EXCL_LINE
356                 /* Deinitialize and quit manager */
357         }
358
359         g_dbus_object_manager_server_set_connection(stc->obj_mgr,
360                                                     stc->connection);
361
362         iptables_init();
363         stc_plugin_firewall_update();
364         stc_plugin_monitor_init_connection(stc);
365
366         stc_plugin_appstatus_register_state_changed_cb(stc,
367                         stc_plugin_procfs_app_status_changed, NULL);
368
369         __STC_LOG_FUNC_EXIT__;
370 }
371
372 static void __stc_manager_gdbus_on_name_acquired(GDBusConnection *connection,
373                                                  const gchar *name,
374                                                  gpointer user_data)
375 {
376         STC_LOGD("name : %s", name);
377 }
378
379 //LCOV_EXCL_START
380 static void __stc_manager_gdbus_on_name_lost(GDBusConnection *connection,
381                                              const gchar *name,
382                                              gpointer user_data)
383 {
384         STC_LOGD("name : %s", name);
385 }
386 //LCOV_EXCL_STOP
387
388 void stc_manager_gdbus_init(gpointer stc_data)
389 {
390         __STC_LOG_FUNC_ENTER__;
391         stc_s *stc = (stc_s *)stc_data;
392
393         stc->gdbus_owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
394                                              STC_DBUS_SERVICE,
395                                              G_BUS_NAME_OWNER_FLAGS_NONE,
396                                              __stc_manager_gdbus_on_bus_acquired,
397                                              __stc_manager_gdbus_on_name_acquired,
398                                              __stc_manager_gdbus_on_name_lost,
399                                              stc,
400                                              NULL);
401
402         __STC_LOG_FUNC_EXIT__;
403 }
404
405 void stc_manager_gdbus_deinit(gpointer stc_data)
406 {
407         __STC_LOG_FUNC_ENTER__;
408         stc_s *stc = (stc_s *)stc_data;
409
410         stc_plugin_appstatus_deregister_state_changed_cb(stc);
411         stc_plugin_monitor_deinit_connection(stc);
412
413         g_bus_unown_name(stc->gdbus_owner_id);
414
415         stc->statistics_obj = NULL;
416         stc->restriction_obj = NULL;
417         stc->firewall_obj = NULL;
418         stc->pcap_obj = NULL;
419         stc->manager_obj = NULL;
420         __STC_LOG_FUNC_EXIT__;
421 }
422
423 API GVariant *stc_manager_gdbus_call_sync(GDBusConnection *connection,
424                                       const char *dest, const char *path,
425                                       const char *interface_name,
426                                       const char *method, GVariant *params)
427 {
428         GError *error = NULL;
429         GVariant *reply = NULL;
430
431         if (connection == NULL) {
432                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
433                 return reply; //LCOV_EXCL_LINE
434         }
435
436         reply = g_dbus_connection_call_sync(connection,
437                                             dest,
438                                             path,
439                                             interface_name,
440                                             method,
441                                             params,
442                                             NULL,
443                                             G_DBUS_CALL_FLAGS_NONE,
444                                             (5 * 1000),  /* 5 seconds timeout */
445                                             NULL,
446                                             &error);
447
448         if (reply == NULL) {
449                 if (error != NULL) {
450                         STC_LOGE("g_dbus_connection_call_sync() failed" //LCOV_EXCL_LINE
451                                  " error [%d: %s]", error->code, error->message);
452                         g_error_free(error); //LCOV_EXCL_LINE
453                 } else {
454                         STC_LOGE("g_dbus_connection_call_sync() failed"); //LCOV_EXCL_LINE
455                 }
456
457                 return NULL;
458         }
459
460         return reply;
461 }
462
463 API guint stc_manager_gdbus_subscribe_signal(GDBusConnection *connection,
464                                          const gchar *sender,
465                                          const gchar *interface_name,
466                                          const gchar *member,
467                                          const gchar *object_path,
468                                          const gchar *arg0,
469                                          GDBusSignalFlags flags,
470                                          GDBusSignalCallback callback,
471                                          gpointer user_data,
472                                          GDestroyNotify user_data_free_func)
473 {
474         if (connection == NULL) {
475                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
476                 return 0; //LCOV_EXCL_LINE
477         }
478
479         return g_dbus_connection_signal_subscribe(connection,
480                                                   sender,
481                                                   interface_name,
482                                                   member,
483                                                   object_path,
484                                                   NULL,
485                                                   G_DBUS_SIGNAL_FLAGS_NONE,
486                                                   callback,
487                                                   user_data,
488                                                   user_data_free_func);
489 }
490
491 API void stc_manager_gdbus_unsubscribe_signal(GDBusConnection *connection,
492                                           guint subscription_id)
493 {
494         if (connection == NULL) {
495                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
496                 return; //LCOV_EXCL_LINE
497         }
498
499         g_dbus_connection_signal_unsubscribe(connection, subscription_id);
500 }
501
502 API void stc_manager_gdbus_dict_foreach(GVariantIter *iter, dbus_dict_cb cb,
503                                     void *user_data)
504 {
505         __STC_LOG_FUNC_ENTER__;
506
507         gchar *key = NULL;
508         GVariant *value = NULL;
509
510         if (!cb) {
511                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
512                 return; //LCOV_EXCL_LINE
513         }
514
515         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
516                 /* DEBUG_GDBUS_KEY_VALUE(key, value); */
517                 if (key)
518                         cb(key, value, user_data);
519         }
520
521         __STC_LOG_FUNC_EXIT__;
522 }
523
524 API gboolean stc_manager_dbus_emit_signal(GDBusConnection *connection,
525                                       const gchar *object_path,
526                                       const gchar *interface_name,
527                                       const gchar *signal_name,
528                                       GVariant *parameters)
529 {
530         gboolean rv = FALSE;
531         GError *error = NULL;
532
533         if (connection == NULL) {
534                 STC_LOGE("GDBusconnection is NULL"); //LCOV_EXCL_LINE
535                 return 0;
536         }
537
538         DEBUG_GDBUS_VARIANT("Signal params: ", parameters);
539
540         rv = g_dbus_connection_emit_signal(connection,
541                                            NULL,
542                                            object_path,
543                                            interface_name,
544                                            signal_name,
545                                            parameters,
546                                            &error);
547         if (rv != TRUE) {
548                 STC_LOGE("Failed to emit signal [%s] interface [%s] Error [%s]", //LCOV_EXCL_LINE
549                          signal_name, interface_name, error->message);
550                 g_error_free(error); //LCOV_EXCL_LINE
551         } else {
552                 STC_LOGD("[%s] signal sent on [%s] interface", signal_name,
553                          interface_name);
554         }
555
556         return rv;
557 }
558
559 gboolean handle_manager_stop(StcManager *object,
560                                GDBusMethodInvocation *invocation)
561 {
562         __STC_LOG_FUNC_ENTER__;
563         GVariant *return_parameters = NULL;
564
565         STC_LOGI("stc manager stop");
566
567         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
568
569         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
570         STC_DBUS_REPLY(invocation, return_parameters);
571
572         stc_stop_manager();
573
574         __STC_LOG_FUNC_EXIT__;
575         return TRUE;
576 }
577
578 gboolean handle_manager_commit_iptables(StcManager *object,
579                                         GDBusMethodInvocation *invocation,
580                                         const gchar *option,
581                                         void *user_data)
582 {
583         __STC_LOG_FUNC_ENTER__;
584         GVariant *return_parameters = NULL;
585         int ret = STC_ERROR_NONE;
586         int err_num = 0;
587         char *err_str = NULL;
588         char cmd[STC_CMD_SIZE] = { 0, };
589
590         if (option == NULL) {
591                 STC_MANAGER_DBUS_REPLY_ERROR(invocation,
592                                                  STC_ERROR_INVALID_PARAMETER);
593                 __STC_LOG_FUNC_EXIT__;
594                 return TRUE;
595         }
596
597         STC_LOGD("[%s]", option);
598         g_snprintf(cmd, STC_CMD_SIZE, "%s %s", STC_IPTABLES, option);
599
600         ret = stc_commit_iptables(cmd, &err_num, &err_str);
601
602         return_parameters = g_variant_new("(iis)", ret, err_num, err_str);
603
604         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
605         STC_DBUS_REPLY(invocation, return_parameters);
606
607         __STC_LOG_FUNC_EXIT__;
608         return TRUE;
609 }
610
611 gboolean handle_manager_commit_ip6tables(StcManager *object,
612                                         GDBusMethodInvocation *invocation,
613                                         const gchar *option,
614                                         void *user_data)
615 {
616         __STC_LOG_FUNC_ENTER__;
617         GVariant *return_parameters = NULL;
618         int ret = STC_ERROR_NONE;
619         int err_num = 0;
620         char *err_str = NULL;
621         char cmd[STC_CMD_SIZE] = { 0, };
622
623         if (option == NULL) {
624                 STC_MANAGER_DBUS_REPLY_ERROR(invocation,
625                                                  STC_ERROR_INVALID_PARAMETER);
626                 __STC_LOG_FUNC_EXIT__;
627                 return TRUE;
628         }
629
630         STC_LOGD("[%s]", option);
631         g_snprintf(cmd, STC_CMD_SIZE, "%s %s", STC_IP6TABLES, option);
632
633         ret = stc_commit_iptables(cmd, &err_num, &err_str);
634
635         return_parameters = g_variant_new("(iis)", ret, err_num, err_str);
636
637         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
638         STC_DBUS_REPLY(invocation, return_parameters);
639
640         __STC_LOG_FUNC_EXIT__;
641         return TRUE;
642 }