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