Removed exclude restriction method
[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_dbus_object_manager_server_export(stc->obj_mgr,
259                                             G_DBUS_OBJECT_SKELETON(object));
260         g_object_unref(object);
261
262         stc->manager_obj = (gpointer)manager;
263
264         __STC_LOG_FUNC_EXIT__;
265         return ret;
266 }
267
268
269 static void __stc_manager_gdbus_on_bus_acquired(GDBusConnection *connection,
270                                                 const gchar *name,
271                                                 gpointer user_data)
272 {
273         __STC_LOG_FUNC_ENTER__;
274         stc_s* stc = (stc_s*)user_data;
275
276         stc->obj_mgr = g_dbus_object_manager_server_new("/net/stc");
277
278         STC_LOGD("path : %s", name);
279
280         stc->connection = connection;
281
282         if (__stc_manager_gdbus_statistics_init(stc) == FALSE) {
283                 STC_LOGE("Can not signal connect to statistics"); //LCOV_EXCL_LINE
284                 /* Deinitialize and quit manager */
285         }
286
287         if (__stc_manager_gdbus_restriction_init(stc) == FALSE) {
288                 STC_LOGE("Cannot signal connect to restriction"); //LCOV_EXCL_LINE
289                 /* Deinitialize and quit manager */
290         }
291
292         if (__stc_manager_gdbus_firewall_init(stc) == FALSE) {
293                 STC_LOGE("Cannot signal connect to firewall"); //LCOV_EXCL_LINE
294                 /* Deinitialize and quit manager */
295         }
296
297         if (__stc_manager_gdbus_manager_init(stc) == FALSE) {
298                 STC_LOGE("Cannot signal connect to manager"); //LCOV_EXCL_LINE
299                 /* Deinitialize and quit manager */
300         }
301
302         g_dbus_object_manager_server_set_connection(stc->obj_mgr,
303                                                     stc->connection);
304
305         iptables_init();
306         stc_default_connection_monitor_init(stc);
307
308         stc_plugin_appstatus_register_state_changed_cb(stc,
309                         stc_plugin_procfs_app_status_changed, NULL);
310
311         __STC_LOG_FUNC_EXIT__;
312 }
313
314 static void __stc_manager_gdbus_on_name_acquired(GDBusConnection *connection,
315                                                  const gchar *name,
316                                                  gpointer user_data)
317 {
318         STC_LOGD("name : %s", name);
319 }
320
321 //LCOV_EXCL_START
322 static void __stc_manager_gdbus_on_name_lost(GDBusConnection *connection,
323                                              const gchar *name,
324                                              gpointer user_data)
325 {
326         STC_LOGD("name : %s", name);
327 }
328 //LCOV_EXCL_STOP
329
330 void stc_manager_gdbus_init(gpointer stc_data)
331 {
332         __STC_LOG_FUNC_ENTER__;
333         stc_s *stc = (stc_s *)stc_data;
334
335         stc->gdbus_owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
336                                              STC_DBUS_SERVICE,
337                                              G_BUS_NAME_OWNER_FLAGS_NONE,
338                                              __stc_manager_gdbus_on_bus_acquired,
339                                              __stc_manager_gdbus_on_name_acquired,
340                                              __stc_manager_gdbus_on_name_lost,
341                                              stc,
342                                              NULL);
343
344         __STC_LOG_FUNC_EXIT__;
345 }
346
347 void stc_manager_gdbus_deinit(gpointer stc_data)
348 {
349         __STC_LOG_FUNC_ENTER__;
350         stc_s *stc = (stc_s *)stc_data;
351
352         stc_plugin_appstatus_deregister_state_changed_cb(stc);
353         stc_default_connection_monitor_deinit(stc);
354
355         g_bus_unown_name(stc->gdbus_owner_id);
356
357         stc->statistics_obj = NULL;
358         stc->restriction_obj = NULL;
359         stc->firewall_obj = NULL;
360         stc->manager_obj = NULL;
361         __STC_LOG_FUNC_EXIT__;
362 }
363
364 GVariant *stc_manager_gdbus_call_sync(GDBusConnection *connection,
365                                       const char *dest, const char *path,
366                                       const char *interface_name,
367                                       const char *method, GVariant *params)
368 {
369         GError *error = NULL;
370         GVariant *reply = NULL;
371
372         if (connection == NULL) {
373                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
374                 return reply; //LCOV_EXCL_LINE
375         }
376
377         reply = g_dbus_connection_call_sync(connection,
378                                             dest,
379                                             path,
380                                             interface_name,
381                                             method,
382                                             params,
383                                             NULL,
384                                             G_DBUS_CALL_FLAGS_NONE,
385                                             (5 * 1000),  /* 5 seconds timeout */
386                                             NULL,
387                                             &error);
388
389         if (reply == NULL) {
390                 if (error != NULL) {
391                         STC_LOGE("g_dbus_connection_call_sync() failed" //LCOV_EXCL_LINE
392                                  "error [%d: %s]", error->code, error->message);
393                         g_error_free(error); //LCOV_EXCL_LINE
394                 } else {
395                         STC_LOGE("g_dbus_connection_call_sync() failed"); //LCOV_EXCL_LINE
396                 }
397
398                 return NULL;
399         }
400
401         return reply;
402 }
403
404 guint stc_manager_gdbus_subscribe_signal(GDBusConnection *connection,
405                                          const gchar *sender,
406                                          const gchar *interface_name,
407                                          const gchar *member,
408                                          const gchar *object_path,
409                                          const gchar *arg0,
410                                          GDBusSignalFlags flags,
411                                          GDBusSignalCallback callback,
412                                          gpointer user_data,
413                                          GDestroyNotify user_data_free_func)
414 {
415         if (connection == NULL) {
416                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
417                 return 0; //LCOV_EXCL_LINE
418         }
419
420         return g_dbus_connection_signal_subscribe(connection,
421                                                   sender,
422                                                   interface_name,
423                                                   member,
424                                                   object_path,
425                                                   NULL,
426                                                   G_DBUS_SIGNAL_FLAGS_NONE,
427                                                   callback,
428                                                   user_data,
429                                                   user_data_free_func);
430 }
431
432 void stc_manager_gdbus_unsubscribe_signal(GDBusConnection *connection,
433                                           guint subscription_id)
434 {
435         if (connection == NULL) {
436                 STC_LOGE("Failed to get GDBusconnection"); //LCOV_EXCL_LINE
437                 return; //LCOV_EXCL_LINE
438         }
439
440         g_dbus_connection_signal_unsubscribe(connection, subscription_id);
441 }
442
443 void stc_manager_gdbus_dict_foreach(GVariantIter *iter, dbus_dict_cb cb,
444                                     void *user_data)
445 {
446         __STC_LOG_FUNC_ENTER__;
447
448         gchar *key = NULL;
449         GVariant *value = NULL;
450
451         if (!cb) {
452                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
453                 return; //LCOV_EXCL_LINE
454         }
455
456         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
457                 DEBUG_GDBUS_KEY_VALUE(key, value);
458                 if (key && cb)
459                         cb(key, value, user_data);
460         }
461
462         __STC_LOG_FUNC_EXIT__;
463 }
464
465 gboolean stc_manager_dbus_emit_signal(GDBusConnection *connection,
466                                       const gchar *object_path,
467                                       const gchar *interface_name,
468                                       const gchar *signal_name,
469                                       GVariant *parameters)
470 {
471         gboolean rv = FALSE;
472         GError *error = NULL;
473
474         if (connection == NULL) {
475                 STC_LOGE("GDBusconnection is NULL"); //LCOV_EXCL_LINE
476                 return 0;
477         }
478
479         DEBUG_GDBUS_VARIANT("Signal params: ", parameters);
480
481         rv = g_dbus_connection_emit_signal(connection,
482                                            NULL,
483                                            object_path,
484                                            interface_name,
485                                            signal_name,
486                                            parameters,
487                                            &error);
488         if (rv != TRUE) {
489                 STC_LOGE("Failed to emit signal [%s] interface [%s] Error [%s]", //LCOV_EXCL_LINE
490                          signal_name, interface_name, error->message);
491                 g_error_free(error); //LCOV_EXCL_LINE
492         } else {
493                 STC_LOGD("[%s] signal sent on [%s] interface", signal_name,
494                          interface_name);
495         }
496
497         return rv;
498 }
499
500 gboolean handle_manager_stop(StcManager *object,
501                                GDBusMethodInvocation *invocation)
502 {
503         __STC_LOG_FUNC_ENTER__;
504         GVariant *return_parameters = NULL;
505
506         STC_LOGI("stc manager stop");
507
508         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
509
510         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
511         STC_DBUS_REPLY(invocation, return_parameters);
512
513         stc_stop_manager();
514
515         __STC_LOG_FUNC_EXIT__;
516         return TRUE;
517 }
518
519 gboolean handle_manager_commit_iptables(StcManager *object,
520                                         GDBusMethodInvocation *invocation,
521                                         const gchar *option,
522                                         void *user_data)
523 {
524         __STC_LOG_FUNC_ENTER__;
525         GVariant *return_parameters = NULL;
526         int ret = STC_ERROR_NONE;
527         int err_num = 0;
528         char *err_str = NULL;
529         char cmd[STC_CMD_SIZE] = { 0, };
530
531         if (option == NULL) {
532                 STC_MANAGER_DBUS_REPLY_ERROR(invocation,
533                                                  STC_ERROR_INVALID_PARAMETER);
534                 __STC_LOG_FUNC_EXIT__;
535                 return TRUE;
536         }
537
538         STC_LOGD("[%s]", option);
539         g_snprintf(cmd, STC_CMD_SIZE, "%s %s", STC_IPTABLES, option);
540
541         ret = stc_commit_iptables(cmd, &err_num, &err_str);
542
543         return_parameters = g_variant_new("(iis)", ret, err_num, err_str);
544
545         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
546         STC_DBUS_REPLY(invocation, return_parameters);
547
548         __STC_LOG_FUNC_EXIT__;
549         return TRUE;
550 }