Name: stc-iptables
Summary: STC(Smart Traffic Control) iptables
-Version: 0.0.22
+Version: 0.0.23
Release: 0
Group: Network & Connectivity/Other
License: GPL-2.0 and Apache-2.0
%make_install
+mkdir -p %{buildroot}/%{_localstatedir}/lib/stc
+
#Systemd iptables service file
mkdir -p %{buildroot}%{_libdir}/systemd/system/
cp resources/systemd/stc-iptables.service %{buildroot}%{_libdir}/systemd/system/stc-iptables.service
%attr(644,root,root) %{_libdir}/systemd/system/stc-iptables.service
%attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/stc-iptables.service
+%attr(755,network_fw,network_fw) /%{_localstatedir}/lib/stc
+
#DBus DAC
%attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/stc-iptables.conf
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "helper-config.h"
+#include "helper-log.h"
+
+static GKeyFile *__load_config_file(const char *path)
+{
+ GKeyFile *keyfile = NULL;
+ GError *error = NULL;
+
+ STC_LOGD("Load config [%s]", path);
+
+ keyfile = g_key_file_new();
+ if (!g_key_file_load_from_file(keyfile, path, 0, &error)) {
+ STC_LOGD("Failed to load [%s] : %s", path, error->message);
+ g_clear_error(&error);
+ g_key_file_free(keyfile);
+ keyfile = NULL;
+ }
+
+ return keyfile;
+}
+
+static int __save_config_file(GKeyFile *keyfile, char *path)
+{
+ gchar *data = NULL;
+ gsize length = 0;
+ GError *error = NULL;
+ int ret = 0;
+ FILE *fp = NULL;
+
+ data = g_key_file_to_data(keyfile, &length, NULL);
+ if (!g_file_set_contents(path, data, length, &error)) {
+ STC_LOGD("Failed to save [%s] : %s", path, error->message);
+ g_error_free(error);
+ ret = -EIO;
+ }
+
+ fp = fopen(path, "a+");
+ if (fp) {
+ fflush(fp);
+ fsync(fp->_fileno);
+ fclose(fp);
+ STC_LOGD("Sync the file to disk");
+ }
+
+ g_free(data);
+ return ret;
+}
+
+int helper_config_get_int(char *key)
+{
+ char path[256];
+ GKeyFile *keyfile;
+ gint value;
+
+ snprintf(path, sizeof(path), "%s/%s", INFO_DIR, INFO_CONFIG);
+
+ keyfile = __load_config_file(path);
+ if (!keyfile)
+ return 0;
+
+ value = g_key_file_get_integer(keyfile, path, key, NULL);
+ g_key_file_free(keyfile);
+
+ return value;
+}
+
+void helper_config_init(void)
+{
+ char path[256];
+ GKeyFile *keyfile;
+
+ snprintf(path, sizeof(path), "%s/%s", INFO_DIR, INFO_CONFIG);
+
+ keyfile = __load_config_file(path);
+ if (!keyfile)
+ keyfile = g_key_file_new();
+
+ g_key_file_set_integer(keyfile, path, INFO_LOGMODE, 0);
+ __save_config_file(keyfile, path);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __STC_HELPER_CONFIG_H__
+#define __STC_HELPER_CONFIG_H__
+
+#define INFO_DIR "/var/lib/stc"
+#define INFO_CONFIG "iptables.config"
+#define INFO_LOGMODE "logmode"
+
+int helper_config_get_int(char *key);
+void helper_config_init(void);
+
+#endif /* __STC_HELPER_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "helper-inotify.h"
+#include "helper-log.h"
+
+typedef struct {
+ GIOChannel *channel;
+ uint watch;
+ int wd;
+
+ inotify_event_cb cb;
+} helper_inotify_s;
+
+static GHashTable *g_inotify_hash;
+
+static void __inotify_destroy(gpointer user_data)
+{
+ int fd;
+ helper_inotify_s *inotify = user_data;
+
+ if (!inotify->channel)
+ return;
+
+ if (inotify->watch > 0)
+ g_source_remove(inotify->watch);
+
+ if (inotify->wd > 0) {
+ fd = g_io_channel_unix_get_fd(inotify->channel);
+ inotify_rm_watch(fd, inotify->wd);
+ }
+
+ g_io_channel_unref(inotify->channel);
+}
+
+static gboolean __inotify_data(GIOChannel *channel,
+ GIOCondition cond, gpointer user_data)
+{
+ helper_inotify_s *inotify = user_data;
+ char buffer[256];
+ char *next_event;
+ gsize bytes_read;
+ GIOStatus status;
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ inotify->watch = 0;
+ return false;
+ }
+
+ status = g_io_channel_read_chars(channel, buffer,
+ sizeof(buffer), &bytes_read, NULL);
+ switch (status) {
+ case G_IO_STATUS_NORMAL:
+ break;
+ case G_IO_STATUS_AGAIN:
+ return true;
+ default:
+ STC_LOGE("Failed to read from inotify channel");
+ inotify->watch = 0;
+ return false;
+ }
+
+ next_event = buffer;
+
+ while (bytes_read > 0) {
+ struct inotify_event *event;
+ gchar *ident;
+ gsize len;
+
+ event = (struct inotify_event *)next_event;
+ if (event->len)
+ ident = next_event + sizeof(struct inotify_event);
+ else
+ ident = NULL;
+
+ len = sizeof(struct inotify_event) + event->len;
+ if (len > bytes_read)
+ break;
+
+ next_event += len;
+ bytes_read -= len;
+
+ (inotify->cb)(event, ident);
+ }
+
+ return true;
+}
+
+static int __inotify_create_watch(const char *path, helper_inotify_s *inotify)
+{
+ int fd;
+
+ fd = inotify_init();
+ if (fd < 0)
+ return -EIO;
+
+ inotify->wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE | IN_DELETE);
+ if (inotify->wd < 0) {
+ STC_LOGE("Failed to create watch [%s]", path);
+ close(fd);
+ return -EIO;
+ }
+
+ inotify->channel = g_io_channel_unix_new(fd);
+ if (!inotify->channel) {
+ STC_LOGE("Failed to create channel");
+ inotify_rm_watch(fd, inotify->wd);
+ inotify->wd = 0;
+
+ close(fd);
+ return -EIO;
+ }
+
+ g_io_channel_set_close_on_unref(inotify->channel, TRUE);
+ g_io_channel_set_encoding(inotify->channel, NULL, NULL);
+ g_io_channel_set_buffered(inotify->channel, FALSE);
+
+ inotify->watch = g_io_add_watch(inotify->channel,
+ G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
+ __inotify_data, inotify);
+
+ return 0;
+}
+
+int helper_inotify_register(const char *path, inotify_event_cb cb)
+{
+ helper_inotify_s *inotify;
+ int err;
+
+ if (!cb)
+ return -EINVAL;
+
+ inotify = g_hash_table_lookup(g_inotify_hash, path);
+ if (inotify)
+ goto update;
+
+ inotify = g_try_new0(helper_inotify_s, 1);
+ if (!inotify)
+ return -ENOMEM;
+
+ inotify->wd = -1;
+ err = __inotify_create_watch(path, inotify);
+ if (err < 0) {
+ g_free(inotify);
+ return err;
+ }
+
+ g_hash_table_replace(g_inotify_hash, g_strdup(path), inotify);
+
+update:
+ inotify->cb = cb;
+ return 0;
+}
+
+void helper_inotify_deregister(const char *path)
+{
+ helper_inotify_s *inotify;
+
+ inotify = g_hash_table_lookup(g_inotify_hash, path);
+ if (!inotify)
+ return;
+
+ g_hash_table_remove(g_inotify_hash, path);
+}
+
+int helper_inotify_init(void)
+{
+ g_inotify_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, g_free, __inotify_destroy);
+ return 0;
+}
+
+void helper_inotify_deinit(void)
+{
+ g_hash_table_destroy(g_inotify_hash);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __STC_HELPER_INOTIFY_H__
+#define __STC_HELPER_INOTIFY_H__
+
+#include <sys/inotify.h>
+
+struct inotify_event;
+typedef void (* inotify_event_cb) (struct inotify_event *event, const char *ident);
+
+int helper_inotify_register(const char *path, inotify_event_cb cb);
+void helper_inotify_deregister(const char *path);
+int helper_inotify_init(void);
+void helper_inotify_deinit(void);
+
+#endif /* __STC_HELPER_INOTIFY_H__ */
#define MAX_LOG_SIZE 1 * 1024 * 1024
#define MAX_LOG_COUNT 1
-static FILE *log_file = NULL;
+static FILE *g_log_file = NULL;
+static int g_log_mode = 0;
//LCOV_EXCL_START
static void __stc_iptables_log_update_file_revision(int rev)
strftime(strtime, size, "%m/%d %H:%M:%S", local_ptm);
}
+void helper_log_set_mode(int mode)
+{
+ g_log_mode = mode;
+}
+
void helper_log(const char *format, ...)
{
va_list ap;
char str[256];
char strtime[40];
- if (log_file == NULL)
- log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+ if (g_log_mode == 0)
+ return;
+
+ if (g_log_file == NULL)
+ g_log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
- if (log_file == NULL)
+ if (g_log_file == NULL)
return;
va_start(ap, format);
- if (fstat(fileno(log_file), &buf) == 0)
+ if (fstat(fileno(g_log_file), &buf) == 0)
log_size = buf.st_size;
if (log_size >= MAX_LOG_SIZE) {
//LCOV_EXCL_START
- fclose(log_file);
- log_file = NULL;
+ fclose(g_log_file);
+ g_log_file = NULL;
__stc_iptables_log_make_backup();
- log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+ g_log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
- if (log_file == NULL) {
+ if (g_log_file == NULL) {
va_end(ap);
return;
}
__stc_iptables_log_get_local_time(strtime, sizeof(strtime));
if (vsnprintf(str, sizeof(str), format, ap) > 0)
- fprintf(log_file, "%s %s", strtime, str);
+ fprintf(g_log_file, "%s %s", strtime, str);
va_end(ap);
}
void helper_log_cleanup(void)
{
- if (log_file == NULL)
+ if (g_log_file == NULL)
return;
- fclose(log_file);
- log_file = NULL;
+ fclose(g_log_file);
+ g_log_file = NULL;
}
#ifndef __STC_HELPER_LOG_H__
#define __STC_HELPER_LOG_H__
+void helper_log_set_mode(int mode);
void helper_log(const char *format, ...);
void helper_log_cleanup(void);
*/
#include <stdlib.h>
+#include <string.h>
#include "stc-iptables.h"
#include "stc-iptables-util.h"
#include "stc-iptables-gdbus.h"
#include "helper-log.h"
+#include "helper-inotify.h"
+#include "helper-config.h"
static stc_iptables_s *g_stc_iptables = NULL;
+static gboolean __validate_ident(const char *ident)
+{
+ unsigned int i;
+ int len;
+
+ if (!ident)
+ return FALSE;
+
+ len = strlen(ident);
+ for (i = 0; i < len; ++i)
+ if (!g_ascii_isprint(ident[i]))
+ return FALSE;
+
+ return TRUE;
+}
+
static void __stc_iptables_deinit(void)
{
__LOG_FUNC_ENTER__;
return g_stc_iptables;
}
+static void __stc_inotify_handler(struct inotify_event *event,
+ const char *ident)
+{
+ if (!ident)
+ return;
+
+ if (!__validate_ident(ident)) {
+ STC_LOGE("Invalid ident [%s]", ident);
+ return;
+ }
+
+ if (!g_strcmp0(ident, INFO_CONFIG)) {
+ int mode = helper_config_get_int(INFO_LOGMODE);
+ helper_log_set_mode(mode);
+ }
+}
+
gint32 main(gint32 argc, gchar *argv[])
{
GMainLoop *main_loop = NULL;
g_type_init();
#endif
+ helper_config_init();
+
+ helper_inotify_init();
+ helper_inotify_register(INFO_DIR, __stc_inotify_handler);
+
/* Crate the GLIB main loop */
main_loop = g_main_loop_new(NULL, FALSE);
if (main_loop)
g_main_loop_unref(main_loop);
+ helper_inotify_deregister(INFO_DIR);
+ helper_inotify_deinit();
+
return ret;
}