/* eurephia-auth.c -- Main OpenVPN plugin functions. * The API level between OpenVPN and eurephia-auth * * GPLv2 only - Copyright (C) 2008, 2009 * David Sommerseth * * 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; version 2 * of the License. * * 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. * */ #include #include #include "openvpn-plugin.h" #define EUREPHIA_FWINTF #include #include #include #include #ifdef ENABLE_DEBUG // To avoid compiler warnings when ENABLE_DEBUG is not defined static const char *plugin_type_name(const int type) { switch (type) { case OPENVPN_PLUGIN_UP: return "PLUGIN_UP"; case OPENVPN_PLUGIN_DOWN: return "PLUGIN_DOWN"; case OPENVPN_PLUGIN_ROUTE_UP: return "PLUGIN_ROUTE_UP"; case OPENVPN_PLUGIN_IPCHANGE: return "PLUGIN_IPCHANGE"; case OPENVPN_PLUGIN_TLS_VERIFY: return "PLUGIN_TLS_VERIFY"; case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: return "PLUGIN_AUTH_USER_PASS_VERIFY"; case OPENVPN_PLUGIN_CLIENT_CONNECT: return "PLUGIN_CLIENT_CONNECT"; case OPENVPN_PLUGIN_CLIENT_DISCONNECT: return "PLUGIN_CLIENT_DISCONNECT"; case OPENVPN_PLUGIN_LEARN_ADDRESS: return "PLUGIN_LEARN_ADDRESS"; default: return "(UNKNOWN PLUGIN CODE)"; } } static void dump_env(FILE *f, const char *prefix, const char *envp[]) { int i; for (i = 0; envp[i]; i++) { #ifdef SHOW_SECRETS fprintf(f, "%s%s\n", prefix, envp[i]); #else fprintf(f, "%s%s\n", prefix , (strncmp(envp[i], "password=", 9) == 0) ? "password=xxxxxxx" : envp[i]); #endif // SHOW_SECRETS } } #endif // ENABLE_DEBUG // daemonize if "daemon" environment variable is set. // preserves stderr access after being daemonized, but // only if "daemon_log_direct" enviroment variable is set. // static void daemonize(const char *envp[]) { const char *daemon_string = get_env(NULL, 0, envp, "daemon"); if( daemon_string && daemon_string[0] == '1' ) { const char *log_redirect = get_env(NULL, 0, envp, "daemon_log_redirect"); int fd = -1; if( log_redirect && log_redirect[0] == '1' ) { fd = dup (2); } if( daemon(0, 0) < 0 ) { fprintf(stderr, "eurephia-auth: daemonization failed\n"); } else if( fd >= 3 ) { dup2(fd, 2); close(fd); } } } OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *envp[]) { eurephiaCTX *context = NULL; #ifdef MEMWATCH mwStatistics(3); #warning MEMWATCH enabled #endif // Define what will trigger eurephia *type_mask = 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) | OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_LEARN_ADDRESS); // Setup a eurephia context context = eurephiaInit(argv); // Daemonize if requested daemonize(envp); return (openvpn_plugin_handle_t) context; } OPENVPN_EXPORT int openvpn_plugin_func_v1(openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) { eurephiaCTX *ctx = (eurephiaCTX *) handle; int result = 0; if( (ctx == NULL) || (ctx->dbc == NULL) || (ctx->dbc->dbhandle == NULL) ) { return OPENVPN_PLUGIN_FUNC_ERROR; } DEBUG(ctx, 10, "openvpn_plugin_func_v1(ctx, %s, ...)", plugin_type_name(type)); #ifdef ENABLE_DEBUG if( ctx->loglevel >= 30 ) { dump_env(ctx->log, "ENV: ", envp); dump_env(ctx->log, "ARG: ", argv); } #endif switch( type ) { case OPENVPN_PLUGIN_TLS_VERIFY: result = eurephia_tlsverify(ctx, envp, argv[1]); break; case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: result = eurephia_userauth(ctx, envp); break; case OPENVPN_PLUGIN_CLIENT_CONNECT: result = eurephia_connect(ctx, envp); break; case OPENVPN_PLUGIN_CLIENT_DISCONNECT: result = eurephia_disconnect(ctx, envp); break; case OPENVPN_PLUGIN_LEARN_ADDRESS: result = eurephia_learn_address(ctx, argv[1], argv[2], envp); break; default: eurephia_log(ctx, LOG_FATAL, 0, "Unknown OPENVPN_PLUGIN type: %i", type); break; } return (result == 1 ? OPENVPN_PLUGIN_FUNC_SUCCESS : OPENVPN_PLUGIN_FUNC_ERROR); } OPENVPN_EXPORT void openvpn_plugin_close_v1(openvpn_plugin_handle_t handle) { eurephiaCTX *ctx = (eurephiaCTX *) handle; eurephiaShutdown(ctx); }