summaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
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;