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