[NetworkManager-fortisslvpn] service: split out property validation into a shared file
- From: Lubomir Rintel <lkundrak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [NetworkManager-fortisslvpn] service: split out property validation into a shared file
- Date: Wed, 20 Mar 2019 12:17:47 +0000 (UTC)
commit b52c59a430ae4bd8de01510ccd8284ca766046f3
Author: Lubomir Rintel <lkundrak v3 sk>
Date: Wed Mar 20 13:04:09 2019 +0100
service: split out property validation into a shared file
We'd prefer to eventually use this to validate the connection in the
editor too.
Makefile.am | 4 +-
shared/nm-fortissl-properties.c | 236 ++++++++++++++++++++++++++++++++++++++++
shared/nm-fortissl-properties.h | 32 ++++++
src/nm-fortisslvpn-service.c | 218 +------------------------------------
4 files changed, 274 insertions(+), 216 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 4d638ab..689c7c0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -82,7 +82,9 @@ src_nm_fortisslvpn_service_SOURCES = \
shared/nm-utils/nm-shared-utils.c \
src/nm-ppp-status.h \
src/nm-fortisslvpn-service.h \
- src/nm-fortisslvpn-service.c
+ src/nm-fortisslvpn-service.c \
+ shared/nm-fortissl-properties.c \
+ shared/nm-fortissl-properties.h
src_nm_fortisslvpn_service_CPPFLAGS = $(src_cppflags)
src_nm_fortisslvpn_service_LDADD = \
src/libnm-fortisslvpn-pppd-service-dbus.la \
diff --git a/shared/nm-fortissl-properties.c b/shared/nm-fortissl-properties.c
new file mode 100644
index 0000000..23a8870
--- /dev/null
+++ b/shared/nm-fortissl-properties.c
@@ -0,0 +1,236 @@
+/*
+ * Lubomir Rintel <lkundrak v3 sk>
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2014 Red Hat, Inc.
+ * (C) Copyright 2015,2017,2019 Lubomir Rintel
+ */
+
+#include "nm-default.h"
+#include "nm-fortissl-properties.h"
+
+#include <sys/stat.h>
+#include <ctype.h>
+
+typedef struct {
+ const char *name;
+ GType type;
+ bool required:1;
+} ValidProperty;
+
+static const ValidProperty valid_properties[] = {
+ { NM_FORTISSLVPN_KEY_GATEWAY, G_TYPE_STRING, TRUE },
+ { NM_FORTISSLVPN_KEY_USER, G_TYPE_STRING, TRUE },
+ { NM_FORTISSLVPN_KEY_CA, G_TYPE_STRING, FALSE },
+ { NM_FORTISSLVPN_KEY_TRUSTED_CERT, G_TYPE_STRING, FALSE },
+ { NM_FORTISSLVPN_KEY_CERT, G_TYPE_STRING, FALSE },
+ { NM_FORTISSLVPN_KEY_KEY, G_TYPE_STRING, FALSE },
+ { NM_FORTISSLVPN_KEY_PASSWORD"-flags", G_TYPE_UINT, FALSE },
+ { NM_FORTISSLVPN_KEY_OTP"-flags", G_TYPE_UINT, FALSE },
+ { NULL }
+};
+
+static const ValidProperty valid_secrets[] = {
+ { NM_FORTISSLVPN_KEY_PASSWORD, G_TYPE_STRING, TRUE },
+ { NM_FORTISSLVPN_KEY_OTP, G_TYPE_STRING, TRUE },
+ { NULL }
+};
+
+static gboolean
+validate_gateway (const char *gateway)
+{
+ if (!gateway || !strlen (gateway) || !isalnum (*gateway))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* This is a bit half-assed. We should check that the user doesn't
+ * abuse this to access files he ordinarily shouldn't, but we can't do
+ * any better than this for we don't have any information about the
+ * identity of the user that activates the connection.
+ * We should probably get the certificate inline or something. */
+static gboolean
+validate_ca (const char *ca)
+{
+ struct stat ca_stat;
+
+ /* Tolerate only absolute paths */
+ if (!ca || !strlen (ca) || *ca != '/')
+ return FALSE;
+
+ if (stat (ca, &ca_stat) == -1)
+ return FALSE;
+
+ /* Allow only ordinary files */
+ if (!(ca_stat.st_mode & S_IFREG))
+ return FALSE;
+
+ /* Allow only world-readable files */
+ if ((ca_stat.st_mode & 0444) != 0444)
+ return FALSE;
+
+ return TRUE;
+}
+
+typedef struct ValidateInfo {
+ const ValidProperty *table;
+ GError **error;
+ gboolean have_items;
+} ValidateInfo;
+
+static void
+validate_one_property (const char *key, const char *value, gpointer user_data)
+{
+ ValidateInfo *info = (ValidateInfo *) user_data;
+ int i;
+
+ if (*(info->error))
+ return;
+
+ info->have_items = TRUE;
+
+ /* 'name' is the setting name; always allowed but unused */
+ if (!strcmp (key, NM_SETTING_NAME))
+ return;
+
+ for (i = 0; info->table[i].name; i++) {
+ ValidProperty prop = info->table[i];
+
+ if (strcmp (prop.name, key))
+ continue;
+
+ switch (prop.type) {
+ case G_TYPE_STRING:
+ if ( !strcmp (prop.name, NM_FORTISSLVPN_KEY_GATEWAY)
+ && !validate_gateway (value)) {
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("invalid gateway “%s”"),
+ value);
+ return;
+ } else if ( !strcmp (prop.name, NM_FORTISSLVPN_KEY_CA)
+ && !validate_ca (value)) {
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("invalid certificate authority “%s”"),
+ value);
+ return;
+ }
+ return; /* valid */
+ case G_TYPE_UINT:
+ errno = 0;
+ (void) strtol (value, NULL, 10);
+ if (errno == 0)
+ return; /* valid */
+
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("invalid integer property “%s”"),
+ key);
+ break;
+ case G_TYPE_BOOLEAN:
+ if (!strcmp (value, "yes") || !strcmp (value, "no"))
+ return; /* valid */
+
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("invalid boolean property “%s” (not yes or no)"),
+ key);
+ break;
+ default:
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("unhandled property “%s” type %s"),
+ key, g_type_name (prop.type));
+ break;
+ }
+ }
+
+ /* Did not find the property from valid_properties or the type did not match */
+ if (!info->table[i].name) {
+ g_set_error (info->error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("property “%s” invalid or not supported"),
+ key);
+ }
+}
+
+gboolean
+nm_fortisslvpn_properties_validate (NMSettingVpn *s_vpn, GError **error)
+{
+ ValidateInfo info = { &valid_properties[0], error, FALSE };
+ int i;
+
+ nm_setting_vpn_foreach_data_item (s_vpn, validate_one_property, &info);
+ if (!info.have_items) {
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ "%s",
+ _("No VPN configuration options."));
+ return FALSE;
+ }
+
+ if (*error)
+ return FALSE;
+
+ /* Ensure required properties exist */
+ for (i = 0; valid_properties[i].name; i++) {
+ ValidProperty prop = valid_properties[i];
+ const char *value;
+
+ if (!prop.required)
+ continue;
+
+ value = nm_setting_vpn_get_data_item (s_vpn, prop.name);
+ if (!value || !strlen (value)) {
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("Missing required option “%s”."),
+ prop.name);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+nm_fortisslvpn_properties_validate_secrets (NMSettingVpn *s_vpn, GError **error)
+{
+ ValidateInfo info = { &valid_secrets[0], error, FALSE };
+
+ nm_setting_vpn_foreach_secret (s_vpn, validate_one_property, &info);
+ if (!info.have_items) {
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ "%s",
+ _("No VPN secrets!"));
+ return FALSE;
+ }
+
+ return *error ? FALSE : TRUE;
+}
diff --git a/shared/nm-fortissl-properties.h b/shared/nm-fortissl-properties.h
new file mode 100644
index 0000000..8c24d3d
--- /dev/null
+++ b/shared/nm-fortissl-properties.h
@@ -0,0 +1,32 @@
+/*
+ * Lubomir Rintel <lkundrak v3 sk>
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2014 Red Hat, Inc.
+ * (C) Copyright 2015,2017,2019 Lubomir Rintel
+ */
+
+#ifndef __NM_FORTISSLVPN_PROPERTIES_H__
+#define __NM_FORTISSLVPN_PROPERTIES_H__
+
+#include "nm-default.h"
+
+gboolean nm_fortisslvpn_properties_validate (NMSettingVpn *s_vpn, GError **error);
+
+gboolean nm_fortisslvpn_properties_validate_secrets (NMSettingVpn *s_vpn, GError **error);
+
+#endif /* __NM_FORTISSLVPN_PROPERTIES_H__ */
diff --git a/src/nm-fortisslvpn-service.c b/src/nm-fortisslvpn-service.c
index 2caa7e8..ed182bb 100644
--- a/src/nm-fortisslvpn-service.c
+++ b/src/nm-fortisslvpn-service.c
@@ -39,6 +39,7 @@
#include <glib/gstdio.h>
+#include "nm-fortissl-properties.h"
#include "nm-ppp-status.h"
#include "nm-fortisslvpn-pppd-service-dbus.h"
#include "nm-utils/nm-shared-utils.h"
@@ -86,34 +87,6 @@ typedef struct {
#define NM_FORTISSLVPN_WAIT_PPPD 10000 /* 10 seconds */
#define FORTISSLVPN_SERVICE_SECRET_TRIES "fortisslvpn-service-secret-tries"
-typedef struct {
- const char *name;
- GType type;
- bool required:1;
-} ValidProperty;
-
-/*****************************************************************************/
-
-static const ValidProperty valid_properties[] = {
- { NM_FORTISSLVPN_KEY_GATEWAY, G_TYPE_STRING, TRUE },
- { NM_FORTISSLVPN_KEY_USER, G_TYPE_STRING, TRUE },
- { NM_FORTISSLVPN_KEY_CA, G_TYPE_STRING, FALSE },
- { NM_FORTISSLVPN_KEY_TRUSTED_CERT, G_TYPE_STRING, FALSE },
- { NM_FORTISSLVPN_KEY_CERT, G_TYPE_STRING, FALSE },
- { NM_FORTISSLVPN_KEY_KEY, G_TYPE_STRING, FALSE },
- { NM_FORTISSLVPN_KEY_PASSWORD"-flags", G_TYPE_UINT, FALSE },
- { NM_FORTISSLVPN_KEY_OTP"-flags", G_TYPE_UINT, FALSE },
- { NULL }
-};
-
-static const ValidProperty valid_secrets[] = {
- { NM_FORTISSLVPN_KEY_PASSWORD, G_TYPE_STRING, TRUE },
- { NM_FORTISSLVPN_KEY_OTP, G_TYPE_STRING, TRUE },
- { NULL }
-};
-
-/*****************************************************************************/
-
#define _NMLOG(level, ...) \
G_STMT_START { \
if (gl.log_level >= (level)) { \
@@ -136,191 +109,6 @@ _LOGD_enabled (void)
/*****************************************************************************/
-static gboolean
-validate_gateway (const char *gateway)
-{
- if (!gateway || !strlen (gateway) || !isalnum (*gateway))
- return FALSE;
-
- return TRUE;
-}
-
-/* This is a bit half-assed. We should check that the user doesn't
- * abuse this to access files he ordinarily shouldn't, but we can't do
- * any better than this for we don't have any information about the
- * identity of the user that activates the connection.
- * We should probably get the certificate inline or something. */
-static gboolean
-validate_ca (const char *ca)
-{
- struct stat ca_stat;
-
- /* Tolerate only absolute paths */
- if (!ca || !strlen (ca) || *ca != '/')
- return FALSE;
-
- if (stat (ca, &ca_stat) == -1)
- return FALSE;
-
- /* Allow only ordinary files */
- if (!(ca_stat.st_mode & S_IFREG))
- return FALSE;
-
- /* Allow only world-readable files */
- if ((ca_stat.st_mode & 0444) != 0444)
- return FALSE;
-
- return TRUE;
-}
-
-typedef struct ValidateInfo {
- const ValidProperty *table;
- GError **error;
- gboolean have_items;
-} ValidateInfo;
-
-static void
-validate_one_property (const char *key, const char *value, gpointer user_data)
-{
- ValidateInfo *info = (ValidateInfo *) user_data;
- int i;
-
- if (*(info->error))
- return;
-
- info->have_items = TRUE;
-
- /* 'name' is the setting name; always allowed but unused */
- if (!strcmp (key, NM_SETTING_NAME))
- return;
-
- for (i = 0; info->table[i].name; i++) {
- ValidProperty prop = info->table[i];
-
- if (strcmp (prop.name, key))
- continue;
-
- switch (prop.type) {
- case G_TYPE_STRING:
- if ( !strcmp (prop.name, NM_FORTISSLVPN_KEY_GATEWAY)
- && !validate_gateway (value)) {
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("invalid gateway “%s”"),
- value);
- return;
- } else if ( !strcmp (prop.name, NM_FORTISSLVPN_KEY_CA)
- && !validate_ca (value)) {
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("invalid certificate authority “%s”"),
- value);
- return;
- }
- return; /* valid */
- case G_TYPE_UINT:
- errno = 0;
- (void) strtol (value, NULL, 10);
- if (errno == 0)
- return; /* valid */
-
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("invalid integer property “%s”"),
- key);
- break;
- case G_TYPE_BOOLEAN:
- if (!strcmp (value, "yes") || !strcmp (value, "no"))
- return; /* valid */
-
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("invalid boolean property “%s” (not yes or no)"),
- key);
- break;
- default:
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("unhandled property “%s” type %s"),
- key, g_type_name (prop.type));
- break;
- }
- }
-
- /* Did not find the property from valid_properties or the type did not match */
- if (!info->table[i].name) {
- g_set_error (info->error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("property “%s” invalid or not supported"),
- key);
- }
-}
-
-static gboolean
-validate_properties (NMSettingVpn *s_vpn, GError **error)
-{
- ValidateInfo info = { &valid_properties[0], error, FALSE };
- int i;
-
- nm_setting_vpn_foreach_data_item (s_vpn, validate_one_property, &info);
- if (!info.have_items) {
- g_set_error (error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- "%s",
- _("No VPN configuration options."));
- return FALSE;
- }
-
- if (*error)
- return FALSE;
-
- /* Ensure required properties exist */
- for (i = 0; valid_properties[i].name; i++) {
- ValidProperty prop = valid_properties[i];
- const char *value;
-
- if (!prop.required)
- continue;
-
- value = nm_setting_vpn_get_data_item (s_vpn, prop.name);
- if (!value || !strlen (value)) {
- g_set_error (error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- _("Missing required option “%s”."),
- prop.name);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_secrets (NMSettingVpn *s_vpn, GError **error)
-{
- ValidateInfo info = { &valid_secrets[0], error, FALSE };
-
- nm_setting_vpn_foreach_secret (s_vpn, validate_one_property, &info);
- if (!info.have_items) {
- g_set_error (error,
- NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
- "%s",
- _("No VPN secrets!"));
- return FALSE;
- }
-
- return *error ? FALSE : TRUE;
-}
-
static gboolean
ensure_killed (gpointer data)
{
@@ -586,10 +374,10 @@ real_connect (NMVpnServicePlugin *plugin, NMConnection *connection, GError **err
s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
g_assert (s_vpn);
- if (!validate_properties (s_vpn, error))
+ if (!nm_fortisslvpn_properties_validate (s_vpn, error))
return FALSE;
- if (!validate_secrets (s_vpn, error))
+ if (!nm_fortisslvpn_properties_validate_secrets (s_vpn, error))
return FALSE;
if (!get_credentials (s_vpn, &username, &password, &otp, error))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]