1/* 2 * OpenVPN -- An application to securely tunnel IP networks 3 * over a single TCP/UDP port, with support for SSL/TLS-based 4 * session authentication and key exchange, 5 * packet encryption, packet authentication, and 6 * packet compression. 7 * 8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 12 * as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program (see the file COPYING included with this 21 * distribution); if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25/* 26 * This plugin is similar to simple.c, except it also logs extra information 27 * to stdout for every plugin method called by OpenVPN. 28 * 29 * See the README file for build instructions. 30 */ 31 32#include <stdio.h> 33#include <string.h> 34#include <stdlib.h> 35 36#include "openvpn-plugin.h" 37 38/* 39 * Our context, where we keep our state. 40 */ 41struct plugin_context { 42 const char *username; 43 const char *password; 44}; 45 46/* 47 * Given an environmental variable name, search 48 * the envp array for its value, returning it 49 * if found or NULL otherwise. 50 */ 51static const char * 52get_env (const char *name, const char *envp[]) 53{ 54 if (envp) 55 { 56 int i; 57 const int namelen = strlen (name); 58 for (i = 0; envp[i]; ++i) 59 { 60 if (!strncmp (envp[i], name, namelen)) 61 { 62 const char *cp = envp[i] + namelen; 63 if (*cp == '=') 64 return cp + 1; 65 } 66 } 67 } 68 return NULL; 69} 70 71OPENVPN_EXPORT openvpn_plugin_handle_t 72openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) 73{ 74 struct plugin_context *context; 75 76 /* 77 * Allocate our context 78 */ 79 context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); 80 81 /* 82 * Set the username/password we will require. 83 */ 84 context->username = "foo"; 85 context->password = "bar"; 86 87 /* 88 * Which callbacks to intercept. 89 */ 90 *type_mask = 91 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | 92 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | 93 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | 94 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | 95 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | 96 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | 97 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | 98 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | 99 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | 100 OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); 101 102 return (openvpn_plugin_handle_t) context; 103} 104 105void 106show (const int type, const char *argv[], const char *envp[]) 107{ 108 size_t i; 109 switch (type) 110 { 111 case OPENVPN_PLUGIN_UP: 112 printf ("OPENVPN_PLUGIN_UP\n"); 113 break; 114 case OPENVPN_PLUGIN_DOWN: 115 printf ("OPENVPN_PLUGIN_DOWN\n"); 116 break; 117 case OPENVPN_PLUGIN_ROUTE_UP: 118 printf ("OPENVPN_PLUGIN_ROUTE_UP\n"); 119 break; 120 case OPENVPN_PLUGIN_IPCHANGE: 121 printf ("OPENVPN_PLUGIN_IPCHANGE\n"); 122 break; 123 case OPENVPN_PLUGIN_TLS_VERIFY: 124 printf ("OPENVPN_PLUGIN_TLS_VERIFY\n"); 125 break; 126 case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: 127 printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n"); 128 break; 129 case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: 130 printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n"); 131 break; 132 case OPENVPN_PLUGIN_CLIENT_DISCONNECT: 133 printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n"); 134 break; 135 case OPENVPN_PLUGIN_LEARN_ADDRESS: 136 printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n"); 137 break; 138 case OPENVPN_PLUGIN_TLS_FINAL: 139 printf ("OPENVPN_PLUGIN_TLS_FINAL\n"); 140 break; 141 default: 142 printf ("OPENVPN_PLUGIN_?\n"); 143 break; 144 } 145 146 printf ("ARGV\n"); 147 for (i = 0; argv[i] != NULL; ++i) 148 printf ("%d '%s'\n", (int)i, argv[i]); 149 150 printf ("ENVP\n"); 151 for (i = 0; envp[i] != NULL; ++i) 152 printf ("%d '%s'\n", (int)i, envp[i]); 153} 154 155OPENVPN_EXPORT int 156openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) 157{ 158 struct plugin_context *context = (struct plugin_context *) handle; 159 160 show (type, argv, envp); 161 162 /* check entered username/password against what we require */ 163 if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) 164 { 165 /* get username/password from envp string array */ 166 const char *username = get_env ("username", envp); 167 const char *password = get_env ("password", envp); 168 169 if (username && !strcmp (username, context->username) 170 && password && !strcmp (password, context->password)) 171 return OPENVPN_PLUGIN_FUNC_SUCCESS; 172 else 173 return OPENVPN_PLUGIN_FUNC_ERROR; 174 } 175 else 176 return OPENVPN_PLUGIN_FUNC_SUCCESS; 177} 178 179OPENVPN_EXPORT void 180openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) 181{ 182 struct plugin_context *context = (struct plugin_context *) handle; 183 free (context); 184} 185