summaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2010-11-30 22:35:00 +0100
committerDavid Sommerseth <dazo@users.sourceforge.net>2010-11-30 22:35:00 +0100
commitd04d1d78c04b60a406bc5a24c004264f43af520f (patch)
tree2abef984326a8ddb48e1378914beadda75865d0e /plugin
parent525d75316848f79208101e48a54e21396464c98b (diff)
downloadeurephia-d04d1d78c04b60a406bc5a24c004264f43af520f.tar.gz
eurephia-d04d1d78c04b60a406bc5a24c004264f43af520f.tar.xz
eurephia-d04d1d78c04b60a406bc5a24c004264f43af520f.zip
Implemented detection of OpenVPN tunnel device type
This will later be used to be able to support OpenVPN in tun mode as well as the now only supported tap mode. It will first try to detect the tunnel type based on the 'dev_type' environment variable if available. If not, it will try to figure it out based on the device name. If this fails, it is possible to force the eurephia to a specific device type by setting the openvpn_devtype config variable. Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
Diffstat (limited to 'plugin')
-rw-r--r--plugin/environment.h23
-rw-r--r--plugin/eurephia-auth.c90
2 files changed, 111 insertions, 2 deletions
diff --git a/plugin/environment.h b/plugin/environment.h
index dbefe25..12b0d0b 100644
--- a/plugin/environment.h
+++ b/plugin/environment.h
@@ -49,6 +49,29 @@
*/
char *get_env(eurephiaCTX *ctx, int logmasking, size_t len, const char *envp[], const char *fmt, ... );
+#define MAXLEN_DEVNAME 64 /**< Maximum allowed length of the device name of the tunnel device */
+/**
+ * Macro for retrieving the OpenVPN tunnel device name (openvpn --dev option)
+ *
+ * @param ctx eurephiaCTX
+ * @param env Char array pointer to the environment table where the value resides
+ *
+ * @return Returns a pointer to a new memory region with the value. This region must be freed after use.
+ * @see get_env()
+ */
+#define GETENV_DEVNAME(ctx, env) get_env(ctx, 0, MAXLEN_DEVNAME, env, "dev");
+
+#define MAXLEN_DEVTYPE 8 /**< Maximum allowed length of the device type of the tunnel device */
+/**
+ * Macro for retrieving the OpenVPN tunnel device type (openvpn --dev-type option)
+ *
+ * @param ctx eurephiaCTX
+ * @param env Char array pointer to the environment table where the value resides
+ *
+ * @return Returns a pointer to a new memory region with the value. This region must be freed after use.
+ * @see get_env()
+ */
+#define GETENV_DEVTYPE(ctx, env) get_env(ctx, 0, MAXLEN_DEVTYPE, env, "dev_type");
#define MAXLEN_TLSID 2048 /**< Maximum allowed length of the TLS ID string*/
/**
diff --git a/plugin/eurephia-auth.c b/plugin/eurephia-auth.c
index 03bf674..71969e5 100644
--- a/plugin/eurephia-auth.c
+++ b/plugin/eurephia-auth.c
@@ -40,6 +40,7 @@
#include <eurephiadb.h>
#include <eurephia.h>
#include <eurephia_nullsafe.h>
+#include <eurephia_values.h>
#include <environment.h>
#ifdef ENABLE_DEBUG /* To avoid compiler warnings when ENABLE_DEBUG is not defined */
@@ -78,7 +79,6 @@ static const char *plugin_type_name(const int type)
}
}
-
/**
* Dumps the contents of the environmental table to the given FILE. This function is only available
* if DEBUG is defined during compilation. If SHOW_SECRETS is not defined, it will mask the contents
@@ -102,6 +102,81 @@ static void dump_env(FILE *f, const char *prefix, const char *envp[]) {
#endif // ENABLE_DEBUG
+/**
+ * Simple function for converting a device name/type string to
+ * a OVPN_tunnelType constant
+ */
+static OVPN_tunnelType conv_str2tuntype(const char *str) {
+ if( str ) {
+ if( strncmp(str, "tun", 3) == 0 ) {
+ return tuntype_TUN;
+ } else if( strncmp(str, "tap", 3) == 0 ) {
+ return tuntype_TAP;
+ }
+ }
+ return tuntype_UNKN;
+}
+
+
+static inline int detect_tunnel_type(eurephiaCTX *ctx, const char const *env[]) {
+ char *devname = NULL;
+ char *devtype = NULL;
+ OVPN_tunnelType tuntype = tuntype_UNKN;
+ int forced = 0;
+
+ devname = GETENV_DEVNAME(ctx, env);
+
+ // Check if eurephia is configured to override the device type
+ devtype = eGet_value(ctx->dbc->config, "openvpn_devtype");
+ if( devtype ) {
+ tuntype = conv_str2tuntype(devtype);
+ if( tuntype == tuntype_UNKN ) {
+ eurephia_log(ctx, LOG_ERR, 0,
+ "Unkown openvpn_devtype configuration value: '%s'. "
+ "Will try to auto-detect the type for the %s device.",
+ devtype, devname);
+ free_nullsafe(ctx, devtype);
+
+ } else {
+ ctx->tuntype = tuntype;
+ forced = 1;
+ goto success;
+ }
+ }
+
+ // Check if we got the 'dev_type' environment variable
+ devtype = GETENV_DEVTYPE(ctx, env);
+ tuntype = conv_str2tuntype(devtype);
+ if( tuntype != tuntype_UNKN ) {
+ ctx->tuntype = tuntype;
+ goto success;
+ }
+
+ // If no 'dev_type', try to guess the dev-type based on the dev name
+ tuntype = conv_str2tuntype(devname);
+ if( tuntype != tuntype_UNKN ) {
+ ctx->tuntype = tuntype;
+ goto success;
+ }
+
+ // If we're here, it's an unknown device type
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Could not detect automatically which device type the %s device is. "
+ "You need to force the tunnel device type setting the 'openvpn_devtype' "
+ "configuration value.",
+ devname);
+ return 0;
+
+ success:
+ eurephia_log(ctx, LOG_INFO, 1,
+ "OpenVPN device type is %s %s on the %s device.",
+ (forced ? "forced to" : "detected as"),
+ (tuntype == tuntype_TUN ? "TUN" : "TAP"), devname);
+ free_nullsafe(ctx, devtype);
+ free_nullsafe(ctx, devname);
+ return 1;
+}
+
/**
* Prepares a eurephiaCTX (context) for the openvpn process and tells openvpn which hooks eurephia
@@ -124,7 +199,8 @@ OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v1(unsigned int *type
#endif
// Define what will trigger eurephia
- *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
+ *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_UP)
+ | OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
| OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_VERIFY)
| OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT)
| OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
@@ -132,6 +208,7 @@ OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v1(unsigned int *type
// Setup a eurephia context
context = eurephiaInit(argv, envp);
+ context->tuntype = tuntype_UNKN; // Make sure tunnel type is unknown
return (openvpn_plugin_handle_t) context;
}
@@ -170,6 +247,15 @@ OPENVPN_EXPORT int openvpn_plugin_func_v1(openvpn_plugin_handle_t handle,
#endif
switch( type ) {
+ case OPENVPN_PLUGIN_UP:
+ result = detect_tunnel_type(ctx, envp); // Figure out what kind of tunnel type we got.
+ if( result == 0 ) {
+ // If we cannot identify the tunnel type, we will anyway reject
+ // OpenVPN from starting up. In that case, shutdown eurephia properly
+ eurephiaShutdown(ctx);
+ }
+ break;
+
case OPENVPN_PLUGIN_TLS_VERIFY: // Validate certificates
result = eurephia_tlsverify(ctx, envp, argv[1]);
break;