diff options
-rw-r--r-- | common/eurephia_context.h | 9 | ||||
-rw-r--r-- | man/eurephia-variables.7 | 4 | ||||
-rw-r--r-- | plugin/environment.h | 23 | ||||
-rw-r--r-- | plugin/eurephia-auth.c | 90 |
4 files changed, 124 insertions, 2 deletions
diff --git a/common/eurephia_context.h b/common/eurephia_context.h index e323c45..d7c1bae 100644 --- a/common/eurephia_context.h +++ b/common/eurephia_context.h @@ -45,12 +45,21 @@ #define SIZE_PWDCACHE_SALT 2048 /**< Defines the size of the in-memory password salt */ /** + * OpenVPN tunnel types + */ +typedef enum OVPN_tunnelType_e { tuntype_UNKN, /**< Unknwown */ + tuntype_TAP, /**< OpenVPN is used with --dev tap */ + tuntype_TUN /**< OpenVPN is used with --dev tun */ +} OVPN_tunnelType; + +/** * main structure for the eurephia module context * - the same context structure is used for all OpenVPN sessions */ typedef struct { void *eurephia_driver; /**< Pointer to the eurephia database drivers handler */ void *eurephia_fw_intf; /**< Pointer to the eurephia firewall interface handler */ + OVPN_tunnelType tuntype;/**< Type of OpenVPN tunnel - TUN or TAP */ eDBconn *dbc; /**< Pointer to an eurephia database connection */ #ifdef EUREPHIA_FWINTF eurephiaFWINTF *fwcfg; /**< Pointer to the firewall configuration */ diff --git a/man/eurephia-variables.7 b/man/eurephia-variables.7 index 6505a45..967c761 100644 --- a/man/eurephia-variables.7 +++ b/man/eurephia-variables.7 @@ -52,6 +52,10 @@ This defines how long a eurephia administration utility may have an open session .TP .B eurephiadm_xslt_path The \fBeurephiadm\fR utility uses XSLT templates for generating the output to the screen. This variable gives you the possibility to have your own set of templates in a different directory instead of using the system wide XSLT templates installed by default. This variable is not set by default. +.SH "OPENVPN RELATED VARIABLES" +.TP +.B openvpn_devtype +The \fBeurephia-auth\fR plug-in will try to auto-detect the device type, which must be either tun or tap. If this auto-detection fails, this configuration variable needs to be set to \fBtun\fR or \fBtap\fR. This value must correspond to the OpenVPN configuration. .SH "SEE ALSO" \fBeurephiadm\-config\fR(7), \fBeurephia_init\fR(7), 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; |