As disucssed[1], keep plugins in repository.
1, Proper automake/libtool build.
2. Move example plugins to samples/sample-plugins.
3. Plugins are installed at LIBDIR/openvpn/plugins.
[1] http://comments.gmane.org/gmane.network.openvpn.devel/6436
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
Acked-by: David Sommerseth <davids@redhat.com>
Message-Id: 1337035323-27465-1-git-send-email-alon.barlev@gmail.com
URL: http://article.gmane.org/gmane.network.openvpn.devel/6591
Signed-off-by: David Sommerseth <davids@redhat.com>
| ... | ... |
@@ -194,6 +194,27 @@ AC_ARG_ENABLE( |
| 194 | 194 |
) |
| 195 | 195 |
|
| 196 | 196 |
AC_ARG_ENABLE( |
| 197 |
+ [plugin-auth-pam], |
|
| 198 |
+ [AS_HELP_STRING([--disable-plugin-auth-pam], [disable auth-pam plugin @<:@default=yes@:>@])], |
|
| 199 |
+ , |
|
| 200 |
+ [enable_plugin_auth_pam="yes"] |
|
| 201 |
+) |
|
| 202 |
+ |
|
| 203 |
+AC_ARG_ENABLE( |
|
| 204 |
+ [plugin-down-root], |
|
| 205 |
+ [AS_HELP_STRING([--disable-plugin-down-root], [disable down-root plugin @<:@default=yes@:>@])], |
|
| 206 |
+ , |
|
| 207 |
+ [enable_plugin_down_root="yes"] |
|
| 208 |
+) |
|
| 209 |
+ |
|
| 210 |
+AC_ARG_ENABLE( |
|
| 211 |
+ [pam-dlopen], |
|
| 212 |
+ [AS_HELP_STRING([--enable-pam-dlopen], [dlopen libpam @<:@default=no@:>@])], |
|
| 213 |
+ , |
|
| 214 |
+ [enable_pam_dlopen="no"] |
|
| 215 |
+) |
|
| 216 |
+ |
|
| 217 |
+AC_ARG_ENABLE( |
|
| 197 | 218 |
[strict], |
| 198 | 219 |
[AS_HELP_STRING([--enable-strict], [enable strict compiler warnings (debugging option) @<:@default=no@:>@])], |
| 199 | 220 |
, |
| ... | ... |
@@ -258,6 +279,14 @@ AC_ARG_WITH( |
| 258 | 258 |
[with_crypto_library="openssl"] |
| 259 | 259 |
) |
| 260 | 260 |
|
| 261 |
+AC_ARG_WITH( |
|
| 262 |
+ [plugindir], |
|
| 263 |
+ [AS_HELP_STRING([--with-plugindir], [plugin directory @<:@default=LIBDIR/openvpn@:>@])], |
|
| 264 |
+ , |
|
| 265 |
+ [with_plugindir="\$(libdir)/openvpn/plugins"] |
|
| 266 |
+) |
|
| 267 |
+ |
|
| 268 |
+ |
|
| 261 | 269 |
AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host])
|
| 262 | 270 |
case "$host" in |
| 263 | 271 |
*-*-linux*) |
| ... | ... |
@@ -624,6 +653,16 @@ AC_CHECK_LIB( |
| 624 | 624 |
) |
| 625 | 625 |
AC_SUBST([SELINUX_LIBS]) |
| 626 | 626 |
|
| 627 |
+AC_ARG_VAR([LIBPAM_CFLAGS], [C compiler flags for libpam]) |
|
| 628 |
+AC_ARG_VAR([LIBPAM_LIBS], [linker flags for libpam]) |
|
| 629 |
+if test -z "${LIBPAM_LIBS}"; then
|
|
| 630 |
+ AC_CHECK_LIB( |
|
| 631 |
+ [pam], |
|
| 632 |
+ [pam_start], |
|
| 633 |
+ [LIBPAM_LIBS="-lpam"] |
|
| 634 |
+ ) |
|
| 635 |
+fi |
|
| 636 |
+ |
|
| 627 | 637 |
case "${with_mem_check}" in
|
| 628 | 638 |
valgrind) |
| 629 | 639 |
AC_CHECK_HEADER( |
| ... | ... |
@@ -894,6 +933,9 @@ if test "${enable_plugins}" = "yes"; then
|
| 894 | 894 |
OPTIONAL_DL_LIBS="${DL_LIBS}"
|
| 895 | 895 |
AC_DEFINE([ENABLE_PLUGIN], [1], [Enable systemd support]) |
| 896 | 896 |
test "${enable_eurephia}" = "yes" && AC_DEFINE([ENABLE_EUREPHIA], [1], [Enable support for the eurephia plug-in])
|
| 897 |
+else |
|
| 898 |
+ enable_plugin_auth_pam="no" |
|
| 899 |
+ enable_plugin_down_root="no" |
|
| 897 | 900 |
fi |
| 898 | 901 |
|
| 899 | 902 |
if test "${enable_iproute2}" = "yes"; then
|
| ... | ... |
@@ -945,6 +987,17 @@ if test "${WIN32}" = "yes"; then
|
| 945 | 945 |
test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32])
|
| 946 | 946 |
fi |
| 947 | 947 |
|
| 948 |
+if test "${enable_plugin_auth_pam}" = "yes"; then
|
|
| 949 |
+ PLUGIN_AUTH_PAM_CFLAGS="${LIBPAM_CFLAGS}"
|
|
| 950 |
+ if test "${enable_pam_dlopen}" = "yes"; then
|
|
| 951 |
+ AC_DEFINE([USE_PAM_DLOPEN], [1], [dlopen libpam]) |
|
| 952 |
+ PLUGIN_AUTH_PAM_LIBS="${DL_LIBS}"
|
|
| 953 |
+ else |
|
| 954 |
+ test -z "${LIBPAM_LIBS}" && AC_MSG_ERROR([libpam required but missing])
|
|
| 955 |
+ PLUGIN_AUTH_PAM_LIBS="${LIBPAM_LIBS}"
|
|
| 956 |
+ fi |
|
| 957 |
+fi |
|
| 958 |
+ |
|
| 948 | 959 |
CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`" |
| 949 | 960 |
AC_DEFINE_UNQUOTED([CONFIGURE_DEFINES], ["`echo ${CONFIGURE_DEFINES}`"], [Configuration settings])
|
| 950 | 961 |
|
| ... | ... |
@@ -967,10 +1020,17 @@ AC_SUBST([OPTIONAL_LZO_LIBS]) |
| 967 | 967 |
AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS]) |
| 968 | 968 |
AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS]) |
| 969 | 969 |
|
| 970 |
+AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS]) |
|
| 971 |
+AC_SUBST([PLUGIN_AUTH_PAM_LIBS]) |
|
| 972 |
+ |
|
| 970 | 973 |
AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
|
| 971 | 974 |
AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])
|
| 975 |
+AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"])
|
|
| 976 |
+AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"])
|
|
| 972 | 977 |
|
| 978 |
+plugindir="${with_plugindir}"
|
|
| 973 | 979 |
sampledir="\$(docdir)/sample" |
| 980 |
+AC_SUBST([plugindir]) |
|
| 974 | 981 |
AC_SUBST([sampledir]) |
| 975 | 982 |
|
| 976 | 983 |
AC_CONFIG_FILES([ |
| ... | ... |
@@ -987,6 +1047,9 @@ AC_CONFIG_FILES([ |
| 987 | 987 |
src/compat/Makefile |
| 988 | 988 |
src/openvpn/Makefile |
| 989 | 989 |
src/openvpnserv/Makefile |
| 990 |
+ src/plugins/Makefile |
|
| 991 |
+ src/plugins/auth-pam/Makefile |
|
| 992 |
+ src/plugins/down-root/Makefile |
|
| 990 | 993 |
tests/Makefile |
| 991 | 994 |
sample/Makefile |
| 992 | 995 |
doc/Makefile |
| ... | ... |
@@ -83,13 +83,6 @@ Development support for OpenVPN. |
| 83 | 83 |
%endif |
| 84 | 84 |
|
| 85 | 85 |
# |
| 86 |
-# Should we build the auth-pam module? |
|
| 87 |
-# |
|
| 88 |
- |
|
| 89 |
-%define build_auth_pam 1 |
|
| 90 |
-%{?without_pam:%define build_auth_pam 0}
|
|
| 91 |
- |
|
| 92 |
-# |
|
| 93 | 86 |
# Other definitions |
| 94 | 87 |
# |
| 95 | 88 |
|
| ... | ... |
@@ -108,20 +101,9 @@ Development support for OpenVPN. |
| 108 | 108 |
--docdir="%{_docdir}/%{name}-%{version}" \
|
| 109 | 109 |
%{?with_password_save:--enable-password-save} \
|
| 110 | 110 |
%{!?without_lzo:--enable-lzo} \
|
| 111 |
- %{?with_pkcs11:--enable-pkcs11}
|
|
| 112 |
-%__make |
|
| 113 |
- |
|
| 114 |
-# Build down-root plugin |
|
| 115 |
-pushd src/plugins/down-root |
|
| 111 |
+ %{?with_pkcs11:--enable-pkcs11} \
|
|
| 112 |
+ %{?without_pam:--disable-plugin-auth-pam}
|
|
| 116 | 113 |
%__make |
| 117 |
-popd |
|
| 118 |
- |
|
| 119 |
-# Build auth-pam plugin |
|
| 120 |
-%if %{build_auth_pam}
|
|
| 121 |
-pushd src/plugins/auth-pam |
|
| 122 |
-%__make |
|
| 123 |
-popd |
|
| 124 |
-%endif |
|
| 125 | 114 |
|
| 126 | 115 |
# |
| 127 | 116 |
# Installation section |
| ... | ... |
@@ -143,29 +125,8 @@ popd |
| 143 | 143 |
# Install /etc/openvpn |
| 144 | 144 |
%__install -c -d -m 755 "%{buildroot}/etc/%{name}"
|
| 145 | 145 |
|
| 146 |
-# |
|
| 147 |
-# Build /usr/share/openvpn |
|
| 148 |
-# |
|
| 149 |
- |
|
| 150 |
-%__mkdir_p %{buildroot}%{_datadir}/%{name}
|
|
| 151 |
- |
|
| 152 |
-# |
|
| 153 |
-# Install the plugins |
|
| 154 |
-# |
|
| 155 |
- |
|
| 156 |
-%__mkdir_p "%{buildroot}%{_datadir}/%{name}/plugins/lib"
|
|
| 157 |
- |
|
| 158 |
-for pi in auth-pam down-root; do |
|
| 159 |
- %__mv -f src/plugins/$pi/README src/plugins/README.$pi |
|
| 160 |
- if [ -e src/plugins/$pi/openvpn-$pi.so ]; then |
|
| 161 |
- %__install -c -m 755 src/plugins/$pi/openvpn-$pi.so "%{buildroot}%{_datadir}/openvpn/plugins/lib/openvpn-$pi.so"
|
|
| 162 |
- fi |
|
| 163 |
-done |
|
| 164 |
- |
|
| 165 |
-%__mv -f src/plugins/README src/plugins/README.plugins |
|
| 166 |
- |
|
| 167 | 146 |
# Install extra %doc stuff |
| 168 |
-cp -r AUTHORS ChangeLog NEWS contrib/ sample/ src/plugins/README.* \ |
|
| 147 |
+cp -r AUTHORS ChangeLog NEWS contrib/ sample/ \ |
|
| 169 | 148 |
"%{buildroot}/%{_docdir}/%{name}-%{version}"
|
| 170 | 149 |
|
| 171 | 150 |
# |
| ... | ... |
@@ -218,7 +179,7 @@ fi |
| 218 | 218 |
%defattr(-,root,root) |
| 219 | 219 |
%{_mandir}
|
| 220 | 220 |
%{_sbindir}/%{name}
|
| 221 |
-%{_datadir}/%{name}
|
|
| 221 |
+%{_libdir}/%{name}
|
|
| 222 | 222 |
%{_docdir}/%{name}-%{version}
|
| 223 | 223 |
%dir /etc/%{name}
|
| 224 | 224 |
%if "%{VENDOR}" == "SuSE"
|
| ... | ... |
@@ -17,8 +17,11 @@ CLEANFILES = openvpn.8.html |
| 17 | 17 |
dist_doc_DATA = \ |
| 18 | 18 |
management-notes.txt |
| 19 | 19 |
|
| 20 |
+dist_noinst_DATA = \ |
|
| 21 |
+ README.plugins |
|
| 22 |
+ |
|
| 20 | 23 |
if WIN32 |
| 21 |
-dist_noinst_DATA = openvpn.8 |
|
| 24 |
+dist_noinst_DATA += openvpn.8 |
|
| 22 | 25 |
nodist_html_DATA = openvpn.8.html |
| 23 | 26 |
openvpn.8.html: $(srcdir)/openvpn.8 |
| 24 | 27 |
$(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html |
| 25 | 28 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,47 @@ |
| 0 |
+OpenVPN Plugins |
|
| 1 |
+--------------- |
|
| 2 |
+ |
|
| 3 |
+Starting with OpenVPN 2.0-beta17, compiled plugin modules are |
|
| 4 |
+supported on any *nix OS which includes libdl or on Windows. |
|
| 5 |
+One or more modules may be loaded into OpenVPN using |
|
| 6 |
+the --plugin directive, and each plugin module is capable of |
|
| 7 |
+intercepting any of the script callbacks which OpenVPN supports: |
|
| 8 |
+ |
|
| 9 |
+(1) up |
|
| 10 |
+(2) down |
|
| 11 |
+(3) route-up |
|
| 12 |
+(4) ipchange |
|
| 13 |
+(5) tls-verify |
|
| 14 |
+(6) auth-user-pass-verify |
|
| 15 |
+(7) client-connect |
|
| 16 |
+(8) client-disconnect |
|
| 17 |
+(9) learn-address |
|
| 18 |
+ |
|
| 19 |
+See the openvpn-plugin.h file in the top-level directory of the |
|
| 20 |
+OpenVPN source distribution for more detailed information |
|
| 21 |
+on the plugin interface. |
|
| 22 |
+ |
|
| 23 |
+Included Plugins |
|
| 24 |
+---------------- |
|
| 25 |
+ |
|
| 26 |
+auth-pam -- Authenticate using PAM and a split privilege |
|
| 27 |
+ execution model which functions even if |
|
| 28 |
+ root privileges or the execution environment |
|
| 29 |
+ have been altered with --user/--group/--chroot. |
|
| 30 |
+ Tested on Linux only. |
|
| 31 |
+ |
|
| 32 |
+down-root -- Enable the running of down scripts with root privileges |
|
| 33 |
+ even if --user/--group/--chroot have been used |
|
| 34 |
+ to drop root privileges or change the execution |
|
| 35 |
+ environment. Not applicable on Windows. |
|
| 36 |
+ |
|
| 37 |
+examples -- A simple example that demonstrates a portable |
|
| 38 |
+ plugin, i.e. one which can be built for *nix |
|
| 39 |
+ or Windows from the same source. |
|
| 40 |
+ |
|
| 41 |
+Building Plugins |
|
| 42 |
+---------------- |
|
| 43 |
+ |
|
| 44 |
+cd to the top-level directory of a plugin, and use the |
|
| 45 |
+"make" command to build it. The examples plugin is |
|
| 46 |
+built using a build script, not a makefile. |
| 19 | 20 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,16 @@ |
| 0 |
+OpenVPN plugin examples. |
|
| 1 |
+ |
|
| 2 |
+Examples provided: |
|
| 3 |
+ |
|
| 4 |
+simple.c -- using the --auth-user-pass-verify callback, |
|
| 5 |
+ test deferred authentication. |
|
| 6 |
+ |
|
| 7 |
+To build: |
|
| 8 |
+ |
|
| 9 |
+ ./build simple (Linux/BSD/etc.) |
|
| 10 |
+ ./winbuild simple (MinGW on Windows) |
|
| 11 |
+ |
|
| 12 |
+To use in OpenVPN, add to config file: |
|
| 13 |
+ |
|
| 14 |
+ plugin simple.so (Linux/BSD/etc.) |
|
| 15 |
+ plugin simple.dll (MinGW on Windows) |
| 0 | 16 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+#!/bin/sh |
|
| 1 |
+ |
|
| 2 |
+# |
|
| 3 |
+# Build an OpenVPN plugin module on *nix. The argument should |
|
| 4 |
+# be the base name of the C source file (without the .c). |
|
| 5 |
+# |
|
| 6 |
+ |
|
| 7 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 8 |
+CPPFLAGS="${CPPFLAGS:--I../../../include}"
|
|
| 9 |
+ |
|
| 10 |
+CC="${CC:-gcc}"
|
|
| 11 |
+CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
|
| 12 |
+ |
|
| 13 |
+$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ |
|
| 14 |
+$CC $CFLAGS -fPIC -shared ${LDFLAS} -Wl,-soname,$1.so -o $1.so $1.o -lc
|
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,305 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 8 |
+ * |
|
| 9 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 10 |
+ * it under the terms of the GNU General Public License version 2 |
|
| 11 |
+ * as published by the Free Software Foundation. |
|
| 12 |
+ * |
|
| 13 |
+ * This program is distributed in the hope that it will be useful, |
|
| 14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 |
+ * GNU General Public License for more details. |
|
| 17 |
+ * |
|
| 18 |
+ * You should have received a copy of the GNU General Public License |
|
| 19 |
+ * along with this program (see the file COPYING included with this |
|
| 20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+/* |
|
| 25 |
+ * This file implements a simple OpenVPN plugin module which |
|
| 26 |
+ * will test deferred authentication and packet filtering. |
|
| 27 |
+ * |
|
| 28 |
+ * Will run on Windows or *nix. |
|
| 29 |
+ * |
|
| 30 |
+ * Sample usage: |
|
| 31 |
+ * |
|
| 32 |
+ * setenv test_deferred_auth 20 |
|
| 33 |
+ * setenv test_packet_filter 10 |
|
| 34 |
+ * plugin plugin/defer/simple.so |
|
| 35 |
+ * |
|
| 36 |
+ * This will enable deferred authentication to occur 20 |
|
| 37 |
+ * seconds after the normal TLS authentication process, |
|
| 38 |
+ * and will cause a packet filter file to be generated 10 |
|
| 39 |
+ * seconds after the initial TLS negotiation, using |
|
| 40 |
+ * {common-name}.pf as the source.
|
|
| 41 |
+ * |
|
| 42 |
+ * Sample packet filter configuration: |
|
| 43 |
+ * |
|
| 44 |
+ * [CLIENTS DROP] |
|
| 45 |
+ * +otherclient |
|
| 46 |
+ * [SUBNETS DROP] |
|
| 47 |
+ * +10.0.0.0/8 |
|
| 48 |
+ * -10.10.0.8 |
|
| 49 |
+ * [END] |
|
| 50 |
+ * |
|
| 51 |
+ * See the README file for build instructions. |
|
| 52 |
+ */ |
|
| 53 |
+ |
|
| 54 |
+#include <stdio.h> |
|
| 55 |
+#include <string.h> |
|
| 56 |
+#include <stdlib.h> |
|
| 57 |
+ |
|
| 58 |
+#include "openvpn-plugin.h" |
|
| 59 |
+ |
|
| 60 |
+/* bool definitions */ |
|
| 61 |
+#define bool int |
|
| 62 |
+#define true 1 |
|
| 63 |
+#define false 0 |
|
| 64 |
+ |
|
| 65 |
+/* |
|
| 66 |
+ * Our context, where we keep our state. |
|
| 67 |
+ */ |
|
| 68 |
+ |
|
| 69 |
+struct plugin_context {
|
|
| 70 |
+ int test_deferred_auth; |
|
| 71 |
+ int test_packet_filter; |
|
| 72 |
+}; |
|
| 73 |
+ |
|
| 74 |
+struct plugin_per_client_context {
|
|
| 75 |
+ int n_calls; |
|
| 76 |
+ bool generated_pf_file; |
|
| 77 |
+}; |
|
| 78 |
+ |
|
| 79 |
+/* |
|
| 80 |
+ * Given an environmental variable name, search |
|
| 81 |
+ * the envp array for its value, returning it |
|
| 82 |
+ * if found or NULL otherwise. |
|
| 83 |
+ */ |
|
| 84 |
+static const char * |
|
| 85 |
+get_env (const char *name, const char *envp[]) |
|
| 86 |
+{
|
|
| 87 |
+ if (envp) |
|
| 88 |
+ {
|
|
| 89 |
+ int i; |
|
| 90 |
+ const int namelen = strlen (name); |
|
| 91 |
+ for (i = 0; envp[i]; ++i) |
|
| 92 |
+ {
|
|
| 93 |
+ if (!strncmp (envp[i], name, namelen)) |
|
| 94 |
+ {
|
|
| 95 |
+ const char *cp = envp[i] + namelen; |
|
| 96 |
+ if (*cp == '=') |
|
| 97 |
+ return cp + 1; |
|
| 98 |
+ } |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ return NULL; |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+/* used for safe printf of possible NULL strings */ |
|
| 105 |
+static const char * |
|
| 106 |
+np (const char *str) |
|
| 107 |
+{
|
|
| 108 |
+ if (str) |
|
| 109 |
+ return str; |
|
| 110 |
+ else |
|
| 111 |
+ return "[NULL]"; |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+static int |
|
| 115 |
+atoi_null0 (const char *str) |
|
| 116 |
+{
|
|
| 117 |
+ if (str) |
|
| 118 |
+ return atoi (str); |
|
| 119 |
+ else |
|
| 120 |
+ return 0; |
|
| 121 |
+} |
|
| 122 |
+ |
|
| 123 |
+OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 124 |
+openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) |
|
| 125 |
+{
|
|
| 126 |
+ struct plugin_context *context; |
|
| 127 |
+ |
|
| 128 |
+ printf ("FUNC: openvpn_plugin_open_v1\n");
|
|
| 129 |
+ |
|
| 130 |
+ /* |
|
| 131 |
+ * Allocate our context |
|
| 132 |
+ */ |
|
| 133 |
+ context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 134 |
+ |
|
| 135 |
+ context->test_deferred_auth = atoi_null0 (get_env ("test_deferred_auth", envp));
|
|
| 136 |
+ printf ("TEST_DEFERRED_AUTH %d\n", context->test_deferred_auth);
|
|
| 137 |
+ |
|
| 138 |
+ context->test_packet_filter = atoi_null0 (get_env ("test_packet_filter", envp));
|
|
| 139 |
+ printf ("TEST_PACKET_FILTER %d\n", context->test_packet_filter);
|
|
| 140 |
+ |
|
| 141 |
+ /* |
|
| 142 |
+ * Which callbacks to intercept. |
|
| 143 |
+ */ |
|
| 144 |
+ *type_mask = |
|
| 145 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | |
|
| 146 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | |
|
| 147 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | |
|
| 148 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | |
|
| 149 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | |
|
| 150 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | |
|
| 151 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | |
|
| 152 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | |
|
| 153 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | |
|
| 154 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL) | |
|
| 155 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ENABLE_PF); |
|
| 156 |
+ |
|
| 157 |
+ return (openvpn_plugin_handle_t) context; |
|
| 158 |
+} |
|
| 159 |
+ |
|
| 160 |
+static int |
|
| 161 |
+auth_user_pass_verify (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) |
|
| 162 |
+{
|
|
| 163 |
+ if (context->test_deferred_auth) |
|
| 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 |
+ /* get auth_control_file filename from envp string array*/ |
|
| 170 |
+ const char *auth_control_file = get_env ("auth_control_file", envp);
|
|
| 171 |
+ |
|
| 172 |
+ printf ("DEFER u='%s' p='%s' acf='%s'\n",
|
|
| 173 |
+ np(username), |
|
| 174 |
+ np(password), |
|
| 175 |
+ np(auth_control_file)); |
|
| 176 |
+ |
|
| 177 |
+ /* Authenticate asynchronously in n seconds */ |
|
| 178 |
+ if (auth_control_file) |
|
| 179 |
+ {
|
|
| 180 |
+ char buf[256]; |
|
| 181 |
+ int auth = 2; |
|
| 182 |
+ sscanf (username, "%d", &auth); |
|
| 183 |
+ snprintf (buf, sizeof(buf), "( sleep %d ; echo AUTH %s %d ; echo %d >%s ) &", |
|
| 184 |
+ context->test_deferred_auth, |
|
| 185 |
+ auth_control_file, |
|
| 186 |
+ auth, |
|
| 187 |
+ pcc->n_calls < auth, |
|
| 188 |
+ auth_control_file); |
|
| 189 |
+ printf ("%s\n", buf);
|
|
| 190 |
+ system (buf); |
|
| 191 |
+ pcc->n_calls++; |
|
| 192 |
+ return OPENVPN_PLUGIN_FUNC_DEFERRED; |
|
| 193 |
+ } |
|
| 194 |
+ else |
|
| 195 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 196 |
+ } |
|
| 197 |
+ else |
|
| 198 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 199 |
+} |
|
| 200 |
+ |
|
| 201 |
+static int |
|
| 202 |
+tls_final (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) |
|
| 203 |
+{
|
|
| 204 |
+ if (context->test_packet_filter) |
|
| 205 |
+ {
|
|
| 206 |
+ if (!pcc->generated_pf_file) |
|
| 207 |
+ {
|
|
| 208 |
+ const char *pff = get_env ("pf_file", envp);
|
|
| 209 |
+ const char *cn = get_env ("username", envp);
|
|
| 210 |
+ if (pff && cn) |
|
| 211 |
+ {
|
|
| 212 |
+ char buf[256]; |
|
| 213 |
+ snprintf (buf, sizeof(buf), "( sleep %d ; echo PF %s/%s ; cp \"%s.pf\" \"%s\" ) &", |
|
| 214 |
+ context->test_packet_filter, cn, pff, cn, pff); |
|
| 215 |
+ printf ("%s\n", buf);
|
|
| 216 |
+ system (buf); |
|
| 217 |
+ pcc->generated_pf_file = true; |
|
| 218 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 219 |
+ } |
|
| 220 |
+ else |
|
| 221 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 222 |
+ } |
|
| 223 |
+ else |
|
| 224 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 225 |
+ } |
|
| 226 |
+ else |
|
| 227 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 228 |
+} |
|
| 229 |
+ |
|
| 230 |
+OPENVPN_EXPORT int |
|
| 231 |
+openvpn_plugin_func_v2 (openvpn_plugin_handle_t handle, |
|
| 232 |
+ const int type, |
|
| 233 |
+ const char *argv[], |
|
| 234 |
+ const char *envp[], |
|
| 235 |
+ void *per_client_context, |
|
| 236 |
+ struct openvpn_plugin_string_list **return_list) |
|
| 237 |
+{
|
|
| 238 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 239 |
+ struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) per_client_context; |
|
| 240 |
+ switch (type) |
|
| 241 |
+ {
|
|
| 242 |
+ case OPENVPN_PLUGIN_UP: |
|
| 243 |
+ printf ("OPENVPN_PLUGIN_UP\n");
|
|
| 244 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 245 |
+ case OPENVPN_PLUGIN_DOWN: |
|
| 246 |
+ printf ("OPENVPN_PLUGIN_DOWN\n");
|
|
| 247 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 248 |
+ case OPENVPN_PLUGIN_ROUTE_UP: |
|
| 249 |
+ printf ("OPENVPN_PLUGIN_ROUTE_UP\n");
|
|
| 250 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 251 |
+ case OPENVPN_PLUGIN_IPCHANGE: |
|
| 252 |
+ printf ("OPENVPN_PLUGIN_IPCHANGE\n");
|
|
| 253 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 254 |
+ case OPENVPN_PLUGIN_TLS_VERIFY: |
|
| 255 |
+ printf ("OPENVPN_PLUGIN_TLS_VERIFY\n");
|
|
| 256 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 257 |
+ case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: |
|
| 258 |
+ printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
|
|
| 259 |
+ return auth_user_pass_verify (context, pcc, argv, envp); |
|
| 260 |
+ case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: |
|
| 261 |
+ printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
|
|
| 262 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 263 |
+ case OPENVPN_PLUGIN_CLIENT_DISCONNECT: |
|
| 264 |
+ printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
|
|
| 265 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 266 |
+ case OPENVPN_PLUGIN_LEARN_ADDRESS: |
|
| 267 |
+ printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
|
|
| 268 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 269 |
+ case OPENVPN_PLUGIN_TLS_FINAL: |
|
| 270 |
+ printf ("OPENVPN_PLUGIN_TLS_FINAL\n");
|
|
| 271 |
+ return tls_final (context, pcc, argv, envp); |
|
| 272 |
+ case OPENVPN_PLUGIN_ENABLE_PF: |
|
| 273 |
+ printf ("OPENVPN_PLUGIN_ENABLE_PF\n");
|
|
| 274 |
+ if (context->test_packet_filter) |
|
| 275 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 276 |
+ else |
|
| 277 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 278 |
+ default: |
|
| 279 |
+ printf ("OPENVPN_PLUGIN_?\n");
|
|
| 280 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 281 |
+ } |
|
| 282 |
+} |
|
| 283 |
+ |
|
| 284 |
+OPENVPN_EXPORT void * |
|
| 285 |
+openvpn_plugin_client_constructor_v1 (openvpn_plugin_handle_t handle) |
|
| 286 |
+{
|
|
| 287 |
+ printf ("FUNC: openvpn_plugin_client_constructor_v1\n");
|
|
| 288 |
+ return calloc (1, sizeof (struct plugin_per_client_context)); |
|
| 289 |
+} |
|
| 290 |
+ |
|
| 291 |
+OPENVPN_EXPORT void |
|
| 292 |
+openvpn_plugin_client_destructor_v1 (openvpn_plugin_handle_t handle, void *per_client_context) |
|
| 293 |
+{
|
|
| 294 |
+ printf ("FUNC: openvpn_plugin_client_destructor_v1\n");
|
|
| 295 |
+ free (per_client_context); |
|
| 296 |
+} |
|
| 297 |
+ |
|
| 298 |
+OPENVPN_EXPORT void |
|
| 299 |
+openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 300 |
+{
|
|
| 301 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 302 |
+ printf ("FUNC: openvpn_plugin_close_v1\n");
|
|
| 303 |
+ free (context); |
|
| 304 |
+} |
| 0 | 6 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+# |
|
| 1 |
+# Build an OpenVPN plugin module on Windows/MinGW. |
|
| 2 |
+# The argument should be the base name of the C source file |
|
| 3 |
+# (without the .c). |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 7 |
+INCLUDE="-I../../../build" |
|
| 8 |
+ |
|
| 9 |
+CC_FLAGS="-O2 -Wall" |
|
| 10 |
+ |
|
| 11 |
+gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c |
|
| 12 |
+gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o |
|
| 13 |
+rm junk.tmp |
|
| 14 |
+dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def |
|
| 15 |
+rm base.tmp |
|
| 16 |
+gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp |
|
| 17 |
+rm temp.exp |
| 0 | 18 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+#!/bin/sh |
|
| 1 |
+ |
|
| 2 |
+# |
|
| 3 |
+# Build an OpenVPN plugin module on *nix. The argument should |
|
| 4 |
+# be the base name of the C source file (without the .c). |
|
| 5 |
+# |
|
| 6 |
+ |
|
| 7 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 8 |
+CPPFLAGS="${CPPFLAGS:--I../../..}"
|
|
| 9 |
+ |
|
| 10 |
+CC="${CC:-gcc}"
|
|
| 11 |
+CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
|
| 12 |
+ |
|
| 13 |
+$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ |
|
| 14 |
+$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,184 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 8 |
+ * |
|
| 9 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 10 |
+ * it under the terms of the GNU General Public License version 2 |
|
| 11 |
+ * as published by the Free Software Foundation. |
|
| 12 |
+ * |
|
| 13 |
+ * This program is distributed in the hope that it will be useful, |
|
| 14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 |
+ * GNU General Public License for more details. |
|
| 17 |
+ * |
|
| 18 |
+ * You should have received a copy of the GNU General Public License |
|
| 19 |
+ * along with this program (see the file COPYING included with this |
|
| 20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+/* |
|
| 25 |
+ * This plugin is similar to simple.c, except it also logs extra information |
|
| 26 |
+ * to stdout for every plugin method called by OpenVPN. |
|
| 27 |
+ * |
|
| 28 |
+ * See the README file for build instructions. |
|
| 29 |
+ */ |
|
| 30 |
+ |
|
| 31 |
+#include <stdio.h> |
|
| 32 |
+#include <string.h> |
|
| 33 |
+#include <stdlib.h> |
|
| 34 |
+ |
|
| 35 |
+#include "openvpn-plugin.h" |
|
| 36 |
+ |
|
| 37 |
+/* |
|
| 38 |
+ * Our context, where we keep our state. |
|
| 39 |
+ */ |
|
| 40 |
+struct plugin_context {
|
|
| 41 |
+ const char *username; |
|
| 42 |
+ const char *password; |
|
| 43 |
+}; |
|
| 44 |
+ |
|
| 45 |
+/* |
|
| 46 |
+ * Given an environmental variable name, search |
|
| 47 |
+ * the envp array for its value, returning it |
|
| 48 |
+ * if found or NULL otherwise. |
|
| 49 |
+ */ |
|
| 50 |
+static const char * |
|
| 51 |
+get_env (const char *name, const char *envp[]) |
|
| 52 |
+{
|
|
| 53 |
+ if (envp) |
|
| 54 |
+ {
|
|
| 55 |
+ int i; |
|
| 56 |
+ const int namelen = strlen (name); |
|
| 57 |
+ for (i = 0; envp[i]; ++i) |
|
| 58 |
+ {
|
|
| 59 |
+ if (!strncmp (envp[i], name, namelen)) |
|
| 60 |
+ {
|
|
| 61 |
+ const char *cp = envp[i] + namelen; |
|
| 62 |
+ if (*cp == '=') |
|
| 63 |
+ return cp + 1; |
|
| 64 |
+ } |
|
| 65 |
+ } |
|
| 66 |
+ } |
|
| 67 |
+ return NULL; |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 71 |
+openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) |
|
| 72 |
+{
|
|
| 73 |
+ struct plugin_context *context; |
|
| 74 |
+ |
|
| 75 |
+ /* |
|
| 76 |
+ * Allocate our context |
|
| 77 |
+ */ |
|
| 78 |
+ context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 79 |
+ |
|
| 80 |
+ /* |
|
| 81 |
+ * Set the username/password we will require. |
|
| 82 |
+ */ |
|
| 83 |
+ context->username = "foo"; |
|
| 84 |
+ context->password = "bar"; |
|
| 85 |
+ |
|
| 86 |
+ /* |
|
| 87 |
+ * Which callbacks to intercept. |
|
| 88 |
+ */ |
|
| 89 |
+ *type_mask = |
|
| 90 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | |
|
| 91 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | |
|
| 92 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | |
|
| 93 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | |
|
| 94 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | |
|
| 95 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | |
|
| 96 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | |
|
| 97 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | |
|
| 98 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | |
|
| 99 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); |
|
| 100 |
+ |
|
| 101 |
+ return (openvpn_plugin_handle_t) context; |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+void |
|
| 105 |
+show (const int type, const char *argv[], const char *envp[]) |
|
| 106 |
+{
|
|
| 107 |
+ size_t i; |
|
| 108 |
+ switch (type) |
|
| 109 |
+ {
|
|
| 110 |
+ case OPENVPN_PLUGIN_UP: |
|
| 111 |
+ printf ("OPENVPN_PLUGIN_UP\n");
|
|
| 112 |
+ break; |
|
| 113 |
+ case OPENVPN_PLUGIN_DOWN: |
|
| 114 |
+ printf ("OPENVPN_PLUGIN_DOWN\n");
|
|
| 115 |
+ break; |
|
| 116 |
+ case OPENVPN_PLUGIN_ROUTE_UP: |
|
| 117 |
+ printf ("OPENVPN_PLUGIN_ROUTE_UP\n");
|
|
| 118 |
+ break; |
|
| 119 |
+ case OPENVPN_PLUGIN_IPCHANGE: |
|
| 120 |
+ printf ("OPENVPN_PLUGIN_IPCHANGE\n");
|
|
| 121 |
+ break; |
|
| 122 |
+ case OPENVPN_PLUGIN_TLS_VERIFY: |
|
| 123 |
+ printf ("OPENVPN_PLUGIN_TLS_VERIFY\n");
|
|
| 124 |
+ break; |
|
| 125 |
+ case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: |
|
| 126 |
+ printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
|
|
| 127 |
+ break; |
|
| 128 |
+ case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: |
|
| 129 |
+ printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
|
|
| 130 |
+ break; |
|
| 131 |
+ case OPENVPN_PLUGIN_CLIENT_DISCONNECT: |
|
| 132 |
+ printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
|
|
| 133 |
+ break; |
|
| 134 |
+ case OPENVPN_PLUGIN_LEARN_ADDRESS: |
|
| 135 |
+ printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
|
|
| 136 |
+ break; |
|
| 137 |
+ case OPENVPN_PLUGIN_TLS_FINAL: |
|
| 138 |
+ printf ("OPENVPN_PLUGIN_TLS_FINAL\n");
|
|
| 139 |
+ break; |
|
| 140 |
+ default: |
|
| 141 |
+ printf ("OPENVPN_PLUGIN_?\n");
|
|
| 142 |
+ break; |
|
| 143 |
+ } |
|
| 144 |
+ |
|
| 145 |
+ printf ("ARGV\n");
|
|
| 146 |
+ for (i = 0; argv[i] != NULL; ++i) |
|
| 147 |
+ printf ("%d '%s'\n", (int)i, argv[i]);
|
|
| 148 |
+ |
|
| 149 |
+ printf ("ENVP\n");
|
|
| 150 |
+ for (i = 0; envp[i] != NULL; ++i) |
|
| 151 |
+ printf ("%d '%s'\n", (int)i, envp[i]);
|
|
| 152 |
+} |
|
| 153 |
+ |
|
| 154 |
+OPENVPN_EXPORT int |
|
| 155 |
+openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) |
|
| 156 |
+{
|
|
| 157 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 158 |
+ |
|
| 159 |
+ show (type, argv, envp); |
|
| 160 |
+ |
|
| 161 |
+ /* check entered username/password against what we require */ |
|
| 162 |
+ if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) |
|
| 163 |
+ {
|
|
| 164 |
+ /* get username/password from envp string array */ |
|
| 165 |
+ const char *username = get_env ("username", envp);
|
|
| 166 |
+ const char *password = get_env ("password", envp);
|
|
| 167 |
+ |
|
| 168 |
+ if (username && !strcmp (username, context->username) |
|
| 169 |
+ && password && !strcmp (password, context->password)) |
|
| 170 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 171 |
+ else |
|
| 172 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 173 |
+ } |
|
| 174 |
+ else |
|
| 175 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 176 |
+} |
|
| 177 |
+ |
|
| 178 |
+OPENVPN_EXPORT void |
|
| 179 |
+openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 180 |
+{
|
|
| 181 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 182 |
+ free (context); |
|
| 183 |
+} |
| 0 | 184 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,247 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 8 |
+ * Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.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. The only difference |
|
| 28 |
+ * between this (log_v3.c) and log.c is that this module uses the v3 plug-in |
|
| 29 |
+ * API. |
|
| 30 |
+ * |
|
| 31 |
+ * See the README file for build instructions. |
|
| 32 |
+ */ |
|
| 33 |
+ |
|
| 34 |
+#include <stdio.h> |
|
| 35 |
+#include <string.h> |
|
| 36 |
+#include <stdlib.h> |
|
| 37 |
+ |
|
| 38 |
+#define ENABLE_SSL |
|
| 39 |
+ |
|
| 40 |
+#include "openvpn-plugin.h" |
|
| 41 |
+ |
|
| 42 |
+/* |
|
| 43 |
+ * Our context, where we keep our state. |
|
| 44 |
+ */ |
|
| 45 |
+struct plugin_context {
|
|
| 46 |
+ const char *username; |
|
| 47 |
+ const char *password; |
|
| 48 |
+}; |
|
| 49 |
+ |
|
| 50 |
+/* |
|
| 51 |
+ * Given an environmental variable name, search |
|
| 52 |
+ * the envp array for its value, returning it |
|
| 53 |
+ * if found or NULL otherwise. |
|
| 54 |
+ */ |
|
| 55 |
+static const char * |
|
| 56 |
+get_env (const char *name, const char *envp[]) |
|
| 57 |
+{
|
|
| 58 |
+ if (envp) |
|
| 59 |
+ {
|
|
| 60 |
+ int i; |
|
| 61 |
+ const int namelen = strlen (name); |
|
| 62 |
+ for (i = 0; envp[i]; ++i) |
|
| 63 |
+ {
|
|
| 64 |
+ if (!strncmp (envp[i], name, namelen)) |
|
| 65 |
+ {
|
|
| 66 |
+ const char *cp = envp[i] + namelen; |
|
| 67 |
+ if (*cp == '=') |
|
| 68 |
+ return cp + 1; |
|
| 69 |
+ } |
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+ return NULL; |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+OPENVPN_EXPORT int |
|
| 76 |
+openvpn_plugin_open_v3 (const int v3structver, |
|
| 77 |
+ struct openvpn_plugin_args_open_in const *args, |
|
| 78 |
+ struct openvpn_plugin_args_open_return *ret) |
|
| 79 |
+{
|
|
| 80 |
+ struct plugin_context *context = NULL; |
|
| 81 |
+ |
|
| 82 |
+ /* Check that we are API compatible */ |
|
| 83 |
+ if( v3structver != OPENVPN_PLUGINv3_STRUCTVER ) {
|
|
| 84 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 85 |
+ } |
|
| 86 |
+ |
|
| 87 |
+ /* Which callbacks to intercept. */ |
|
| 88 |
+ ret->type_mask = |
|
| 89 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | |
|
| 90 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | |
|
| 91 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | |
|
| 92 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | |
|
| 93 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | |
|
| 94 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | |
|
| 95 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | |
|
| 96 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | |
|
| 97 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | |
|
| 98 |
+ OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); |
|
| 99 |
+ |
|
| 100 |
+ |
|
| 101 |
+ /* Allocate our context */ |
|
| 102 |
+ context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 103 |
+ |
|
| 104 |
+ /* Set the username/password we will require. */ |
|
| 105 |
+ context->username = "foo"; |
|
| 106 |
+ context->password = "bar"; |
|
| 107 |
+ |
|
| 108 |
+ /* Point the global context handle to our newly created context */ |
|
| 109 |
+ ret->handle = (void *) context; |
|
| 110 |
+ |
|
| 111 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+void |
|
| 115 |
+show (const int type, const char *argv[], const char *envp[]) |
|
| 116 |
+{
|
|
| 117 |
+ size_t i; |
|
| 118 |
+ switch (type) |
|
| 119 |
+ {
|
|
| 120 |
+ case OPENVPN_PLUGIN_UP: |
|
| 121 |
+ printf ("OPENVPN_PLUGIN_UP\n");
|
|
| 122 |
+ break; |
|
| 123 |
+ case OPENVPN_PLUGIN_DOWN: |
|
| 124 |
+ printf ("OPENVPN_PLUGIN_DOWN\n");
|
|
| 125 |
+ break; |
|
| 126 |
+ case OPENVPN_PLUGIN_ROUTE_UP: |
|
| 127 |
+ printf ("OPENVPN_PLUGIN_ROUTE_UP\n");
|
|
| 128 |
+ break; |
|
| 129 |
+ case OPENVPN_PLUGIN_IPCHANGE: |
|
| 130 |
+ printf ("OPENVPN_PLUGIN_IPCHANGE\n");
|
|
| 131 |
+ break; |
|
| 132 |
+ case OPENVPN_PLUGIN_TLS_VERIFY: |
|
| 133 |
+ printf ("OPENVPN_PLUGIN_TLS_VERIFY\n");
|
|
| 134 |
+ break; |
|
| 135 |
+ case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: |
|
| 136 |
+ printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
|
|
| 137 |
+ break; |
|
| 138 |
+ case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: |
|
| 139 |
+ printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
|
|
| 140 |
+ break; |
|
| 141 |
+ case OPENVPN_PLUGIN_CLIENT_DISCONNECT: |
|
| 142 |
+ printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
|
|
| 143 |
+ break; |
|
| 144 |
+ case OPENVPN_PLUGIN_LEARN_ADDRESS: |
|
| 145 |
+ printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
|
|
| 146 |
+ break; |
|
| 147 |
+ case OPENVPN_PLUGIN_TLS_FINAL: |
|
| 148 |
+ printf ("OPENVPN_PLUGIN_TLS_FINAL\n");
|
|
| 149 |
+ break; |
|
| 150 |
+ default: |
|
| 151 |
+ printf ("OPENVPN_PLUGIN_?\n");
|
|
| 152 |
+ break; |
|
| 153 |
+ } |
|
| 154 |
+ |
|
| 155 |
+ printf ("ARGV\n");
|
|
| 156 |
+ for (i = 0; argv[i] != NULL; ++i) |
|
| 157 |
+ printf ("%d '%s'\n", (int)i, argv[i]);
|
|
| 158 |
+ |
|
| 159 |
+ printf ("ENVP\n");
|
|
| 160 |
+ for (i = 0; envp[i] != NULL; ++i) |
|
| 161 |
+ printf ("%d '%s'\n", (int)i, envp[i]);
|
|
| 162 |
+} |
|
| 163 |
+ |
|
| 164 |
+static void |
|
| 165 |
+x509_print_info (X509 *x509crt) |
|
| 166 |
+{
|
|
| 167 |
+ int i, n; |
|
| 168 |
+ int fn_nid; |
|
| 169 |
+ ASN1_OBJECT *fn; |
|
| 170 |
+ ASN1_STRING *val; |
|
| 171 |
+ X509_NAME *x509_name; |
|
| 172 |
+ X509_NAME_ENTRY *ent; |
|
| 173 |
+ const char *objbuf; |
|
| 174 |
+ unsigned char *buf; |
|
| 175 |
+ |
|
| 176 |
+ x509_name = X509_get_subject_name (x509crt); |
|
| 177 |
+ n = X509_NAME_entry_count (x509_name); |
|
| 178 |
+ for (i = 0; i < n; ++i) |
|
| 179 |
+ {
|
|
| 180 |
+ ent = X509_NAME_get_entry (x509_name, i); |
|
| 181 |
+ if (!ent) |
|
| 182 |
+ continue; |
|
| 183 |
+ fn = X509_NAME_ENTRY_get_object (ent); |
|
| 184 |
+ if (!fn) |
|
| 185 |
+ continue; |
|
| 186 |
+ val = X509_NAME_ENTRY_get_data (ent); |
|
| 187 |
+ if (!val) |
|
| 188 |
+ continue; |
|
| 189 |
+ fn_nid = OBJ_obj2nid (fn); |
|
| 190 |
+ if (fn_nid == NID_undef) |
|
| 191 |
+ continue; |
|
| 192 |
+ objbuf = OBJ_nid2sn (fn_nid); |
|
| 193 |
+ if (!objbuf) |
|
| 194 |
+ continue; |
|
| 195 |
+ buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ |
|
| 196 |
+ if (ASN1_STRING_to_UTF8 (&buf, val) <= 0) |
|
| 197 |
+ continue; |
|
| 198 |
+ |
|
| 199 |
+ printf("X509 %s: %s\n", objbuf, (char *)buf);
|
|
| 200 |
+ OPENSSL_free (buf); |
|
| 201 |
+ } |
|
| 202 |
+} |
|
| 203 |
+ |
|
| 204 |
+ |
|
| 205 |
+ |
|
| 206 |
+OPENVPN_EXPORT int |
|
| 207 |
+openvpn_plugin_func_v3 (const int version, |
|
| 208 |
+ struct openvpn_plugin_args_func_in const *args, |
|
| 209 |
+ struct openvpn_plugin_args_func_return *retptr) |
|
| 210 |
+{
|
|
| 211 |
+ struct plugin_context *context = (struct plugin_context *) args->handle; |
|
| 212 |
+ |
|
| 213 |
+ printf("\nopenvpn_plugin_func_v3() :::::>> ");
|
|
| 214 |
+ show (args->type, args->argv, args->envp); |
|
| 215 |
+ |
|
| 216 |
+ /* Dump some X509 information if we're in the TLS_VERIFY phase */ |
|
| 217 |
+ if ((args->type == OPENVPN_PLUGIN_TLS_VERIFY) && args->current_cert ) {
|
|
| 218 |
+ printf("---- X509 Subject information ----\n");
|
|
| 219 |
+ printf("Certificate depth: %i\n", args->current_cert_depth);
|
|
| 220 |
+ x509_print_info(args->current_cert); |
|
| 221 |
+ printf("----------------------------------\n");
|
|
| 222 |
+ } |
|
| 223 |
+ |
|
| 224 |
+ /* check entered username/password against what we require */ |
|
| 225 |
+ if (args->type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) |
|
| 226 |
+ {
|
|
| 227 |
+ /* get username/password from envp string array */ |
|
| 228 |
+ const char *username = get_env ("username", args->envp);
|
|
| 229 |
+ const char *password = get_env ("password", args->envp);
|
|
| 230 |
+ |
|
| 231 |
+ if (username && !strcmp (username, context->username) |
|
| 232 |
+ && password && !strcmp (password, context->password)) |
|
| 233 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 234 |
+ else |
|
| 235 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 236 |
+ } |
|
| 237 |
+ else |
|
| 238 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 239 |
+} |
|
| 240 |
+ |
|
| 241 |
+OPENVPN_EXPORT void |
|
| 242 |
+openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 243 |
+{
|
|
| 244 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 245 |
+ free (context); |
|
| 246 |
+} |
| 0 | 247 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+# |
|
| 1 |
+# Build an OpenVPN plugin module on Windows/MinGW. |
|
| 2 |
+# The argument should be the base name of the C source file |
|
| 3 |
+# (without the .c). |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 7 |
+INCLUDE="-I../../../include" |
|
| 8 |
+ |
|
| 9 |
+CC_FLAGS="-O2 -Wall" |
|
| 10 |
+ |
|
| 11 |
+gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c |
|
| 12 |
+gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o |
|
| 13 |
+rm junk.tmp |
|
| 14 |
+dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def |
|
| 15 |
+rm base.tmp |
|
| 16 |
+gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp |
|
| 17 |
+rm temp.exp |
| 0 | 18 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,16 @@ |
| 0 |
+OpenVPN plugin examples. |
|
| 1 |
+ |
|
| 2 |
+Examples provided: |
|
| 3 |
+ |
|
| 4 |
+simple.c -- using the --auth-user-pass-verify callback, verify |
|
| 5 |
+ that the username/password is "foo"/"bar". |
|
| 6 |
+ |
|
| 7 |
+To build: |
|
| 8 |
+ |
|
| 9 |
+ ./build simple (Linux/BSD/etc.) |
|
| 10 |
+ ./winbuild simple (MinGW on Windows) |
|
| 11 |
+ |
|
| 12 |
+To use in OpenVPN, add to config file: |
|
| 13 |
+ |
|
| 14 |
+ plugin simple.so (Linux/BSD/etc.) |
|
| 15 |
+ plugin simple.dll (MinGW on Windows) |
| 0 | 16 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+#!/bin/sh |
|
| 1 |
+ |
|
| 2 |
+# |
|
| 3 |
+# Build an OpenVPN plugin module on *nix. The argument should |
|
| 4 |
+# be the base name of the C source file (without the .c). |
|
| 5 |
+# |
|
| 6 |
+ |
|
| 7 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 8 |
+CPPFLAGS="${CPPFLAGS:--I../../..}"
|
|
| 9 |
+ |
|
| 10 |
+CC="${CC:-gcc}"
|
|
| 11 |
+CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
|
| 12 |
+ |
|
| 13 |
+$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ |
|
| 14 |
+$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,120 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 8 |
+ * |
|
| 9 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 10 |
+ * it under the terms of the GNU General Public License version 2 |
|
| 11 |
+ * as published by the Free Software Foundation. |
|
| 12 |
+ * |
|
| 13 |
+ * This program is distributed in the hope that it will be useful, |
|
| 14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 |
+ * GNU General Public License for more details. |
|
| 17 |
+ * |
|
| 18 |
+ * You should have received a copy of the GNU General Public License |
|
| 19 |
+ * along with this program (see the file COPYING included with this |
|
| 20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+/* |
|
| 25 |
+ * This file implements a simple OpenVPN plugin module which |
|
| 26 |
+ * will examine the username/password provided by a client, |
|
| 27 |
+ * and make an accept/deny determination. Will run |
|
| 28 |
+ * on Windows or *nix. |
|
| 29 |
+ * |
|
| 30 |
+ * See the README file for build instructions. |
|
| 31 |
+ */ |
|
| 32 |
+ |
|
| 33 |
+#include <stdio.h> |
|
| 34 |
+#include <string.h> |
|
| 35 |
+#include <stdlib.h> |
|
| 36 |
+ |
|
| 37 |
+#include "openvpn-plugin.h" |
|
| 38 |
+ |
|
| 39 |
+/* |
|
| 40 |
+ * Our context, where we keep our state. |
|
| 41 |
+ */ |
|
| 42 |
+struct plugin_context {
|
|
| 43 |
+ const char *username; |
|
| 44 |
+ const char *password; |
|
| 45 |
+}; |
|
| 46 |
+ |
|
| 47 |
+/* |
|
| 48 |
+ * Given an environmental variable name, search |
|
| 49 |
+ * the envp array for its value, returning it |
|
| 50 |
+ * if found or NULL otherwise. |
|
| 51 |
+ */ |
|
| 52 |
+static const char * |
|
| 53 |
+get_env (const char *name, const char *envp[]) |
|
| 54 |
+{
|
|
| 55 |
+ if (envp) |
|
| 56 |
+ {
|
|
| 57 |
+ int i; |
|
| 58 |
+ const int namelen = strlen (name); |
|
| 59 |
+ for (i = 0; envp[i]; ++i) |
|
| 60 |
+ {
|
|
| 61 |
+ if (!strncmp (envp[i], name, namelen)) |
|
| 62 |
+ {
|
|
| 63 |
+ const char *cp = envp[i] + namelen; |
|
| 64 |
+ if (*cp == '=') |
|
| 65 |
+ return cp + 1; |
|
| 66 |
+ } |
|
| 67 |
+ } |
|
| 68 |
+ } |
|
| 69 |
+ return NULL; |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 72 |
+OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 73 |
+openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) |
|
| 74 |
+{
|
|
| 75 |
+ struct plugin_context *context; |
|
| 76 |
+ |
|
| 77 |
+ /* |
|
| 78 |
+ * Allocate our context |
|
| 79 |
+ */ |
|
| 80 |
+ context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 81 |
+ |
|
| 82 |
+ /* |
|
| 83 |
+ * Set the username/password we will require. |
|
| 84 |
+ */ |
|
| 85 |
+ context->username = "foo"; |
|
| 86 |
+ context->password = "bar"; |
|
| 87 |
+ |
|
| 88 |
+ /* |
|
| 89 |
+ * We are only interested in intercepting the |
|
| 90 |
+ * --auth-user-pass-verify callback. |
|
| 91 |
+ */ |
|
| 92 |
+ *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY); |
|
| 93 |
+ |
|
| 94 |
+ return (openvpn_plugin_handle_t) context; |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+OPENVPN_EXPORT int |
|
| 98 |
+openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) |
|
| 99 |
+{
|
|
| 100 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 101 |
+ |
|
| 102 |
+ /* get username/password from envp string array */ |
|
| 103 |
+ const char *username = get_env ("username", envp);
|
|
| 104 |
+ const char *password = get_env ("password", envp);
|
|
| 105 |
+ |
|
| 106 |
+ /* check entered username/password against what we require */ |
|
| 107 |
+ if (username && !strcmp (username, context->username) |
|
| 108 |
+ && password && !strcmp (password, context->password)) |
|
| 109 |
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 110 |
+ else |
|
| 111 |
+ return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+OPENVPN_EXPORT void |
|
| 115 |
+openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 116 |
+{
|
|
| 117 |
+ struct plugin_context *context = (struct plugin_context *) handle; |
|
| 118 |
+ free (context); |
|
| 119 |
+} |
| 0 | 6 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+# |
|
| 1 |
+# Build an OpenVPN plugin module on Windows/MinGW. |
|
| 2 |
+# The argument should be the base name of the C source file |
|
| 3 |
+# (without the .c). |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+# This directory is where we will look for openvpn-plugin.h |
|
| 7 |
+INCLUDE="-I../../../include" |
|
| 8 |
+ |
|
| 9 |
+CC_FLAGS="-O2 -Wall" |
|
| 10 |
+ |
|
| 11 |
+gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c |
|
| 12 |
+gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o |
|
| 13 |
+rm junk.tmp |
|
| 14 |
+dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def |
|
| 15 |
+rm base.tmp |
|
| 16 |
+gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp |
|
| 17 |
+rm temp.exp |
| 19 | 16 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+# |
|
| 1 |
+# OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+# over a single UDP port, with support for SSL/TLS-based |
|
| 3 |
+# session authentication and key exchange, |
|
| 4 |
+# packet encryption, packet authentication, and |
|
| 5 |
+# packet compression. |
|
| 6 |
+# |
|
| 7 |
+# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 8 |
+# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> |
|
| 9 |
+# |
|
| 10 |
+ |
|
| 11 |
+MAINTAINERCLEANFILES = \ |
|
| 12 |
+ $(srcdir)/Makefile.in |
|
| 13 |
+ |
|
| 14 |
+SUBDIRS = auth-pam down-root |
| 0 | 15 |
deleted file mode 100644 |
| ... | ... |
@@ -1,47 +0,0 @@ |
| 1 |
-OpenVPN Plugins |
|
| 2 |
- |
|
| 3 |
-Starting with OpenVPN 2.0-beta17, compiled plugin modules are |
|
| 4 |
-supported on any *nix OS which includes libdl or on Windows. |
|
| 5 |
-One or more modules may be loaded into OpenVPN using |
|
| 6 |
-the --plugin directive, and each plugin module is capable of |
|
| 7 |
-intercepting any of the script callbacks which OpenVPN supports: |
|
| 8 |
- |
|
| 9 |
-(1) up |
|
| 10 |
-(2) down |
|
| 11 |
-(3) route-up |
|
| 12 |
-(4) ipchange |
|
| 13 |
-(5) tls-verify |
|
| 14 |
-(6) auth-user-pass-verify |
|
| 15 |
-(7) client-connect |
|
| 16 |
-(8) client-disconnect |
|
| 17 |
-(9) learn-address |
|
| 18 |
- |
|
| 19 |
-See the openvpn-plugin.h file in the top-level directory of the |
|
| 20 |
-OpenVPN source distribution for more detailed information |
|
| 21 |
-on the plugin interface. |
|
| 22 |
- |
|
| 23 |
-Included Plugins |
|
| 24 |
- |
|
| 25 |
-auth-pam -- Authenticate using PAM and a split privilege |
|
| 26 |
- execution model which functions even if |
|
| 27 |
- root privileges or the execution environment |
|
| 28 |
- have been altered with --user/--group/--chroot. |
|
| 29 |
- Tested on Linux only. |
|
| 30 |
- |
|
| 31 |
-down-root -- Enable the running of down scripts with root privileges |
|
| 32 |
- even if --user/--group/--chroot have been used |
|
| 33 |
- to drop root privileges or change the execution |
|
| 34 |
- environment. Not applicable on Windows. |
|
| 35 |
- |
|
| 36 |
-examples -- A simple example that demonstrates a portable |
|
| 37 |
- plugin, i.e. one which can be built for *nix |
|
| 38 |
- or Windows from the same source. |
|
| 39 |
- |
|
| 40 |
-Building Plugins |
|
| 41 |
- |
|
| 42 |
-cd to the top-level directory of a plugin, and use the |
|
| 43 |
-"make" command to build it. The examples plugin is |
|
| 44 |
-built using a build script, not a makefile. |
| 45 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,32 +0,0 @@ |
| 1 |
-# |
|
| 2 |
-# Build the OpenVPN auth-pam plugin module. |
|
| 3 |
-# |
|
| 4 |
- |
|
| 5 |
-# If PAM modules are not linked against libpam.so, set DLOPEN_PAM to 1. This |
|
| 6 |
-# must be done on SUSE 9.1, at least. |
|
| 7 |
-DLOPEN_PAM=0 |
|
| 8 |
- |
|
| 9 |
-ifeq ($(DLOPEN_PAM),1) |
|
| 10 |
- LIBPAM=-ldl |
|
| 11 |
-else |
|
| 12 |
- LIBPAM=-lpam |
|
| 13 |
-endif |
|
| 14 |
- |
|
| 15 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 16 |
-CPPFLAGS=-I../../../include |
|
| 17 |
- |
|
| 18 |
-CC=gcc |
|
| 19 |
-CFLAGS=-O2 -Wall |
|
| 20 |
-DEFS = -DDLOPEN_PAM=$(DLOPEN_PAM) |
|
| 21 |
- |
|
| 22 |
-openvpn-auth-pam.so : auth-pam.o pamdl.o |
|
| 23 |
- $(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) -Wl,-soname,openvpn-auth-pam.so -o openvpn-auth-pam.so auth-pam.o pamdl.o -lc $(LIBPAM) |
|
| 24 |
- |
|
| 25 |
-auth-pam.o : auth-pam.c pamdl.h |
|
| 26 |
- $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFS) -fPIC -c auth-pam.c |
|
| 27 |
- |
|
| 28 |
-pamdl.o : pamdl.c pamdl.h |
|
| 29 |
- $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFS) -fPIC -c pamdl.c |
|
| 30 |
- |
|
| 31 |
-clean : |
|
| 32 |
- -rm -f *.o *.so |
| 33 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,27 @@ |
| 0 |
+# |
|
| 1 |
+# OpenVPN (TM) PAM Auth Plugin -- OpenVPN Plugin |
|
| 2 |
+# |
|
| 3 |
+# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+MAINTAINERCLEANFILES = \ |
|
| 7 |
+ $(srcdir)/Makefile.in |
|
| 8 |
+ |
|
| 9 |
+AM_CFLAGS = \ |
|
| 10 |
+ -I$(top_srcdir)/include |
|
| 11 |
+ $(PLUGIN_AUTH_PAM_CFLAGS) |
|
| 12 |
+ |
|
| 13 |
+if ENABLE_PLUGIN_AUTH_PAM |
|
| 14 |
+plugin_LTLIBRARIES = openvpn-plugin-auth-pam.la |
|
| 15 |
+dist_doc_DATA = README.auth-pam |
|
| 16 |
+endif |
|
| 17 |
+ |
|
| 18 |
+openvpn_plugin_auth_pam_la_SOURCES = \ |
|
| 19 |
+ auth-pam.c \ |
|
| 20 |
+ pamdl.c pamdl.h \ |
|
| 21 |
+ auth-pam.exports |
|
| 22 |
+openvpn_plugin_auth_pam_la_LIBADD = \ |
|
| 23 |
+ $(PLUGIN_AUTH_PAM_LIBS) |
|
| 24 |
+openvpn_plugin_auth_pam_la_LDFLAGS = $(AM_LDFLAGS) \ |
|
| 25 |
+ -export-symbols "$(srcdir)/auth-pam.exports" \ |
|
| 26 |
+ -module -shared -avoid-version -no-undefined |
| 0 | 27 |
deleted file mode 100644 |
| ... | ... |
@@ -1,74 +0,0 @@ |
| 1 |
-openvpn-auth-pam |
|
| 2 |
- |
|
| 3 |
-SYNOPSIS |
|
| 4 |
- |
|
| 5 |
-The openvpn-auth-pam module implements username/password |
|
| 6 |
-authentication via PAM, and essentially allows any authentication |
|
| 7 |
-method supported by PAM (such as LDAP, RADIUS, or Linux Shadow |
|
| 8 |
-passwords) to be used with OpenVPN. While PAM supports |
|
| 9 |
-username/password authentication, this can be combined with X509 |
|
| 10 |
-certificates to provide two indepedent levels of authentication. |
|
| 11 |
- |
|
| 12 |
-This module uses a split privilege execution model which will |
|
| 13 |
-function even if you drop openvpn daemon privileges using the user, |
|
| 14 |
-group, or chroot directives. |
|
| 15 |
- |
|
| 16 |
-BUILD |
|
| 17 |
- |
|
| 18 |
-To build openvpn-auth-pam, you will need to have the pam-devel |
|
| 19 |
-package installed. |
|
| 20 |
- |
|
| 21 |
-Build with the "make" command. The module will be named |
|
| 22 |
-openvpn-auth-pam.so |
|
| 23 |
- |
|
| 24 |
-USAGE |
|
| 25 |
- |
|
| 26 |
-To use this plugin module, add to your OpenVPN config file: |
|
| 27 |
- |
|
| 28 |
- plugin openvpn-auth-pam.so service-type |
|
| 29 |
- |
|
| 30 |
-The required service-type parameter corresponds to |
|
| 31 |
-the PAM service definition file usually found |
|
| 32 |
-in /etc/pam.d. |
|
| 33 |
- |
|
| 34 |
-This plugin also supports the usage of a list of name/value |
|
| 35 |
-pairs to answer PAM module queries. |
|
| 36 |
- |
|
| 37 |
-For example: |
|
| 38 |
- |
|
| 39 |
- plugin openvpn-auth-pam.so "login login USERNAME password PASSWORD" |
|
| 40 |
- |
|
| 41 |
-tells auth-pam to (a) use the "login" PAM module, (b) answer a |
|
| 42 |
-"login" query with the username given by the OpenVPN client, and |
|
| 43 |
-(c) answer a "password" query with the password given by the |
|
| 44 |
-OpenVPN client. This provides flexibility in dealing with the different |
|
| 45 |
-types of query strings which different PAM modules might generate. |
|
| 46 |
-For example, suppose you were using a PAM module called |
|
| 47 |
-"test" which queried for "name" rather than "login": |
|
| 48 |
- |
|
| 49 |
- plugin openvpn-auth-pam.so "test name USERNAME password PASSWORD" |
|
| 50 |
- |
|
| 51 |
-While "USERNAME" "COMMONNAME" and "PASSWORD" are special strings which substitute |
|
| 52 |
-to client-supplied values, it is also possible to name literal values |
|
| 53 |
-to use as PAM module query responses. For example, suppose that the |
|
| 54 |
-login module queried for a third parameter, "domain" which |
|
| 55 |
-is to be answered with the constant value "mydomain.com": |
|
| 56 |
- |
|
| 57 |
- plugin openvpn-auth-pam.so "login login USERNAME password PASSWORD domain mydomain.com" |
|
| 58 |
- |
|
| 59 |
-The following OpenVPN directives can also influence |
|
| 60 |
-the operation of this plugin: |
|
| 61 |
- |
|
| 62 |
- client-cert-not-required |
|
| 63 |
- username-as-common-name |
|
| 64 |
- |
|
| 65 |
-Run OpenVPN with --verb 7 or higher to get debugging output from |
|
| 66 |
-this plugin, including the list of queries presented by the |
|
| 67 |
-underlying PAM module. This is a useful debugging tool to figure |
|
| 68 |
-out which queries a given PAM module is making, so that you can |
|
| 69 |
-craft the appropriate plugin directive to answer it. |
|
| 70 |
- |
|
| 71 |
-CAVEATS |
|
| 72 |
- |
|
| 73 |
-This module will only work on *nix systems which support PAM, |
|
| 74 |
-not Windows. |
| 75 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,74 @@ |
| 0 |
+openvpn-auth-pam |
|
| 1 |
+ |
|
| 2 |
+SYNOPSIS |
|
| 3 |
+ |
|
| 4 |
+The openvpn-auth-pam module implements username/password |
|
| 5 |
+authentication via PAM, and essentially allows any authentication |
|
| 6 |
+method supported by PAM (such as LDAP, RADIUS, or Linux Shadow |
|
| 7 |
+passwords) to be used with OpenVPN. While PAM supports |
|
| 8 |
+username/password authentication, this can be combined with X509 |
|
| 9 |
+certificates to provide two indepedent levels of authentication. |
|
| 10 |
+ |
|
| 11 |
+This module uses a split privilege execution model which will |
|
| 12 |
+function even if you drop openvpn daemon privileges using the user, |
|
| 13 |
+group, or chroot directives. |
|
| 14 |
+ |
|
| 15 |
+BUILD |
|
| 16 |
+ |
|
| 17 |
+To build openvpn-auth-pam, you will need to have the pam-devel |
|
| 18 |
+package installed. |
|
| 19 |
+ |
|
| 20 |
+Build with the "make" command. The module will be named |
|
| 21 |
+openvpn-auth-pam.so |
|
| 22 |
+ |
|
| 23 |
+USAGE |
|
| 24 |
+ |
|
| 25 |
+To use this plugin module, add to your OpenVPN config file: |
|
| 26 |
+ |
|
| 27 |
+ plugin openvpn-auth-pam.so service-type |
|
| 28 |
+ |
|
| 29 |
+The required service-type parameter corresponds to |
|
| 30 |
+the PAM service definition file usually found |
|
| 31 |
+in /etc/pam.d. |
|
| 32 |
+ |
|
| 33 |
+This plugin also supports the usage of a list of name/value |
|
| 34 |
+pairs to answer PAM module queries. |
|
| 35 |
+ |
|
| 36 |
+For example: |
|
| 37 |
+ |
|
| 38 |
+ plugin openvpn-auth-pam.so "login login USERNAME password PASSWORD" |
|
| 39 |
+ |
|
| 40 |
+tells auth-pam to (a) use the "login" PAM module, (b) answer a |
|
| 41 |
+"login" query with the username given by the OpenVPN client, and |
|
| 42 |
+(c) answer a "password" query with the password given by the |
|
| 43 |
+OpenVPN client. This provides flexibility in dealing with the different |
|
| 44 |
+types of query strings which different PAM modules might generate. |
|
| 45 |
+For example, suppose you were using a PAM module called |
|
| 46 |
+"test" which queried for "name" rather than "login": |
|
| 47 |
+ |
|
| 48 |
+ plugin openvpn-auth-pam.so "test name USERNAME password PASSWORD" |
|
| 49 |
+ |
|
| 50 |
+While "USERNAME" "COMMONNAME" and "PASSWORD" are special strings which substitute |
|
| 51 |
+to client-supplied values, it is also possible to name literal values |
|
| 52 |
+to use as PAM module query responses. For example, suppose that the |
|
| 53 |
+login module queried for a third parameter, "domain" which |
|
| 54 |
+is to be answered with the constant value "mydomain.com": |
|
| 55 |
+ |
|
| 56 |
+ plugin openvpn-auth-pam.so "login login USERNAME password PASSWORD domain mydomain.com" |
|
| 57 |
+ |
|
| 58 |
+The following OpenVPN directives can also influence |
|
| 59 |
+the operation of this plugin: |
|
| 60 |
+ |
|
| 61 |
+ client-cert-not-required |
|
| 62 |
+ username-as-common-name |
|
| 63 |
+ |
|
| 64 |
+Run OpenVPN with --verb 7 or higher to get debugging output from |
|
| 65 |
+this plugin, including the list of queries presented by the |
|
| 66 |
+underlying PAM module. This is a useful debugging tool to figure |
|
| 67 |
+out which queries a given PAM module is making, so that you can |
|
| 68 |
+craft the appropriate plugin directive to answer it. |
|
| 69 |
+ |
|
| 70 |
+CAVEATS |
|
| 71 |
+ |
|
| 72 |
+This module will only work on *nix systems which support PAM, |
|
| 73 |
+not Windows. |
| ... | ... |
@@ -26,12 +26,14 @@ |
| 26 | 26 |
* OpenVPN plugin module to do PAM authentication using a split |
| 27 | 27 |
* privilege model. |
| 28 | 28 |
*/ |
| 29 |
+#ifdef HAVE_CONFIG_H |
|
| 30 |
+#include <config.h> |
|
| 31 |
+#endif |
|
| 29 | 32 |
|
| 30 |
-#if DLOPEN_PAM |
|
| 31 |
-#include <dlfcn.h> |
|
| 32 |
-#include "pamdl.h" |
|
| 33 |
-#else |
|
| 34 | 33 |
#include <security/pam_appl.h> |
| 34 |
+ |
|
| 35 |
+#ifdef USE_PAM_DLOPEN |
|
| 36 |
+#include "pamdl.h" |
|
| 35 | 37 |
#endif |
| 36 | 38 |
|
| 37 | 39 |
#include <stdio.h> |
| ... | ... |
@@ -46,7 +48,7 @@ |
| 46 | 46 |
#include <signal.h> |
| 47 | 47 |
#include <syslog.h> |
| 48 | 48 |
|
| 49 |
-#include "openvpn-plugin.h" |
|
| 49 |
+#include <openvpn-plugin.h> |
|
| 50 | 50 |
|
| 51 | 51 |
#define DEBUG(verb) ((verb) >= 4) |
| 52 | 52 |
|
| ... | ... |
@@ -693,7 +695,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list |
| 693 | 693 |
{
|
| 694 | 694 |
struct user_pass up; |
| 695 | 695 |
int command; |
| 696 |
-#if DLOPEN_PAM |
|
| 696 |
+#ifdef USE_PAM_DLOPEN |
|
| 697 | 697 |
static const char pam_so[] = "libpam.so"; |
| 698 | 698 |
#endif |
| 699 | 699 |
|
| ... | ... |
@@ -703,7 +705,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list |
| 703 | 703 |
if (DEBUG (verb)) |
| 704 | 704 |
fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service); |
| 705 | 705 |
|
| 706 |
-#if DLOPEN_PAM |
|
| 706 |
+#ifdef USE_PAM_DLOPEN |
|
| 707 | 707 |
/* |
| 708 | 708 |
* Load PAM shared object |
| 709 | 709 |
*/ |
| ... | ... |
@@ -794,7 +796,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list |
| 794 | 794 |
} |
| 795 | 795 |
done: |
| 796 | 796 |
|
| 797 |
-#if DLOPEN_PAM |
|
| 797 |
+#ifdef USE_PAM_DLOPEN |
|
| 798 | 798 |
dlclose_pam (); |
| 799 | 799 |
#endif |
| 800 | 800 |
if (DEBUG (verb)) |
| ... | ... |
@@ -1,4 +1,8 @@ |
| 1 |
-#if DLOPEN_PAM |
|
| 1 |
+#ifdef HAVE_CONFIG_H |
|
| 2 |
+#include <config.h> |
|
| 3 |
+#endif |
|
| 4 |
+ |
|
| 5 |
+#ifdef USE_PAM_DLOPEN |
|
| 2 | 6 |
/* |
| 3 | 7 |
* If you want to dynamically load libpam using dlopen() or something, |
| 4 | 8 |
* then dlopen( ' this shared object ' ); It takes care of exporting |
| ... | ... |
@@ -73,7 +77,7 @@ int pam_set_item(pam_handle_t *pamh, int item_type, const void *item) |
| 73 | 73 |
return real_pam_set_item(pamh, item_type, item); |
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
-int pam_get_item(pam_handle_t *pamh, int item_type, const void **item) |
|
| 76 |
+int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item) |
|
| 77 | 77 |
{
|
| 78 | 78 |
int (*real_pam_get_item)(const pam_handle_t *, int, const void **); |
| 79 | 79 |
RESOLVE_PAM_FUNCTION(pam_get_item, int, |
| 7 | 5 |
deleted file mode 100644 |
| ... | ... |
@@ -1,16 +0,0 @@ |
| 1 |
-OpenVPN plugin examples. |
|
| 2 |
- |
|
| 3 |
-Examples provided: |
|
| 4 |
- |
|
| 5 |
-simple.c -- using the --auth-user-pass-verify callback, |
|
| 6 |
- test deferred authentication. |
|
| 7 |
- |
|
| 8 |
-To build: |
|
| 9 |
- |
|
| 10 |
- ./build simple (Linux/BSD/etc.) |
|
| 11 |
- ./winbuild simple (MinGW on Windows) |
|
| 12 |
- |
|
| 13 |
-To use in OpenVPN, add to config file: |
|
| 14 |
- |
|
| 15 |
- plugin simple.so (Linux/BSD/etc.) |
|
| 16 |
- plugin simple.dll (MinGW on Windows) |
| 17 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,15 +0,0 @@ |
| 1 |
-#!/bin/sh |
|
| 2 |
- |
|
| 3 |
-# |
|
| 4 |
-# Build an OpenVPN plugin module on *nix. The argument should |
|
| 5 |
-# be the base name of the C source file (without the .c). |
|
| 6 |
-# |
|
| 7 |
- |
|
| 8 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 9 |
-CPPFLAGS="${CPPFLAGS:--I../../../include}"
|
|
| 10 |
- |
|
| 11 |
-CC="${CC:-gcc}"
|
|
| 12 |
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
|
| 13 |
- |
|
| 14 |
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ |
|
| 15 |
-$CC $CFLAGS -fPIC -shared ${LDFLAS} -Wl,-soname,$1.so -o $1.so $1.o -lc
|
| 16 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,305 +0,0 @@ |
| 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 file implements a simple OpenVPN plugin module which |
|
| 27 |
- * will test deferred authentication and packet filtering. |
|
| 28 |
- * |
|
| 29 |
- * Will run on Windows or *nix. |
|
| 30 |
- * |
|
| 31 |
- * Sample usage: |
|
| 32 |
- * |
|
| 33 |
- * setenv test_deferred_auth 20 |
|
| 34 |
- * setenv test_packet_filter 10 |
|
| 35 |
- * plugin plugin/defer/simple.so |
|
| 36 |
- * |
|
| 37 |
- * This will enable deferred authentication to occur 20 |
|
| 38 |
- * seconds after the normal TLS authentication process, |
|
| 39 |
- * and will cause a packet filter file to be generated 10 |
|
| 40 |
- * seconds after the initial TLS negotiation, using |
|
| 41 |
- * {common-name}.pf as the source.
|
|
| 42 |
- * |
|
| 43 |
- * Sample packet filter configuration: |
|
| 44 |
- * |
|
| 45 |
- * [CLIENTS DROP] |
|
| 46 |
- * +otherclient |
|
| 47 |
- * [SUBNETS DROP] |
|
| 48 |
- * +10.0.0.0/8 |
|
| 49 |
- * -10.10.0.8 |
|
| 50 |
- * [END] |
|
| 51 |
- * |
|
| 52 |
- * See the README file for build instructions. |
|
| 53 |
- */ |
|
| 54 |
- |
|
| 55 |
-#include <stdio.h> |
|
| 56 |
-#include <string.h> |
|
| 57 |
-#include <stdlib.h> |
|
| 58 |
- |
|
| 59 |
-#include "openvpn-plugin.h" |
|
| 60 |
- |
|
| 61 |
-/* bool definitions */ |
|
| 62 |
-#define bool int |
|
| 63 |
-#define true 1 |
|
| 64 |
-#define false 0 |
|
| 65 |
- |
|
| 66 |
-/* |
|
| 67 |
- * Our context, where we keep our state. |
|
| 68 |
- */ |
|
| 69 |
- |
|
| 70 |
-struct plugin_context {
|
|
| 71 |
- int test_deferred_auth; |
|
| 72 |
- int test_packet_filter; |
|
| 73 |
-}; |
|
| 74 |
- |
|
| 75 |
-struct plugin_per_client_context {
|
|
| 76 |
- int n_calls; |
|
| 77 |
- bool generated_pf_file; |
|
| 78 |
-}; |
|
| 79 |
- |
|
| 80 |
-/* |
|
| 81 |
- * Given an environmental variable name, search |
|
| 82 |
- * the envp array for its value, returning it |
|
| 83 |
- * if found or NULL otherwise. |
|
| 84 |
- */ |
|
| 85 |
-static const char * |
|
| 86 |
-get_env (const char *name, const char *envp[]) |
|
| 87 |
-{
|
|
| 88 |
- if (envp) |
|
| 89 |
- {
|
|
| 90 |
- int i; |
|
| 91 |
- const int namelen = strlen (name); |
|
| 92 |
- for (i = 0; envp[i]; ++i) |
|
| 93 |
- {
|
|
| 94 |
- if (!strncmp (envp[i], name, namelen)) |
|
| 95 |
- {
|
|
| 96 |
- const char *cp = envp[i] + namelen; |
|
| 97 |
- if (*cp == '=') |
|
| 98 |
- return cp + 1; |
|
| 99 |
- } |
|
| 100 |
- } |
|
| 101 |
- } |
|
| 102 |
- return NULL; |
|
| 103 |
-} |
|
| 104 |
- |
|
| 105 |
-/* used for safe printf of possible NULL strings */ |
|
| 106 |
-static const char * |
|
| 107 |
-np (const char *str) |
|
| 108 |
-{
|
|
| 109 |
- if (str) |
|
| 110 |
- return str; |
|
| 111 |
- else |
|
| 112 |
- return "[NULL]"; |
|
| 113 |
-} |
|
| 114 |
- |
|
| 115 |
-static int |
|
| 116 |
-atoi_null0 (const char *str) |
|
| 117 |
-{
|
|
| 118 |
- if (str) |
|
| 119 |
- return atoi (str); |
|
| 120 |
- else |
|
| 121 |
- return 0; |
|
| 122 |
-} |
|
| 123 |
- |
|
| 124 |
-OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 125 |
-openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) |
|
| 126 |
-{
|
|
| 127 |
- struct plugin_context *context; |
|
| 128 |
- |
|
| 129 |
- printf ("FUNC: openvpn_plugin_open_v1\n");
|
|
| 130 |
- |
|
| 131 |
- /* |
|
| 132 |
- * Allocate our context |
|
| 133 |
- */ |
|
| 134 |
- context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 135 |
- |
|
| 136 |
- context->test_deferred_auth = atoi_null0 (get_env ("test_deferred_auth", envp));
|
|
| 137 |
- printf ("TEST_DEFERRED_AUTH %d\n", context->test_deferred_auth);
|
|
| 138 |
- |
|
| 139 |
- context->test_packet_filter = atoi_null0 (get_env ("test_packet_filter", envp));
|
|
| 140 |
- printf ("TEST_PACKET_FILTER %d\n", context->test_packet_filter);
|
|
| 141 |
- |
|
| 142 |
- /* |
|
| 143 |
- * Which callbacks to intercept. |
|
| 144 |
- */ |
|
| 145 |
- *type_mask = |
|
| 146 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | |
|
| 147 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | |
|
| 148 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | |
|
| 149 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | |
|
| 150 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | |
|
| 151 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | |
|
| 152 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | |
|
| 153 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | |
|
| 154 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | |
|
| 155 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL) | |
|
| 156 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ENABLE_PF); |
|
| 157 |
- |
|
| 158 |
- return (openvpn_plugin_handle_t) context; |
|
| 159 |
-} |
|
| 160 |
- |
|
| 161 |
-static int |
|
| 162 |
-auth_user_pass_verify (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) |
|
| 163 |
-{
|
|
| 164 |
- if (context->test_deferred_auth) |
|
| 165 |
- {
|
|
| 166 |
- /* get username/password from envp string array */ |
|
| 167 |
- const char *username = get_env ("username", envp);
|
|
| 168 |
- const char *password = get_env ("password", envp);
|
|
| 169 |
- |
|
| 170 |
- /* get auth_control_file filename from envp string array*/ |
|
| 171 |
- const char *auth_control_file = get_env ("auth_control_file", envp);
|
|
| 172 |
- |
|
| 173 |
- printf ("DEFER u='%s' p='%s' acf='%s'\n",
|
|
| 174 |
- np(username), |
|
| 175 |
- np(password), |
|
| 176 |
- np(auth_control_file)); |
|
| 177 |
- |
|
| 178 |
- /* Authenticate asynchronously in n seconds */ |
|
| 179 |
- if (auth_control_file) |
|
| 180 |
- {
|
|
| 181 |
- char buf[256]; |
|
| 182 |
- int auth = 2; |
|
| 183 |
- sscanf (username, "%d", &auth); |
|
| 184 |
- snprintf (buf, sizeof(buf), "( sleep %d ; echo AUTH %s %d ; echo %d >%s ) &", |
|
| 185 |
- context->test_deferred_auth, |
|
| 186 |
- auth_control_file, |
|
| 187 |
- auth, |
|
| 188 |
- pcc->n_calls < auth, |
|
| 189 |
- auth_control_file); |
|
| 190 |
- printf ("%s\n", buf);
|
|
| 191 |
- system (buf); |
|
| 192 |
- pcc->n_calls++; |
|
| 193 |
- return OPENVPN_PLUGIN_FUNC_DEFERRED; |
|
| 194 |
- } |
|
| 195 |
- else |
|
| 196 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 197 |
- } |
|
| 198 |
- else |
|
| 199 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 200 |
-} |
|
| 201 |
- |
|
| 202 |
-static int |
|
| 203 |
-tls_final (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) |
|
| 204 |
-{
|
|
| 205 |
- if (context->test_packet_filter) |
|
| 206 |
- {
|
|
| 207 |
- if (!pcc->generated_pf_file) |
|
| 208 |
- {
|
|
| 209 |
- const char *pff = get_env ("pf_file", envp);
|
|
| 210 |
- const char *cn = get_env ("username", envp);
|
|
| 211 |
- if (pff && cn) |
|
| 212 |
- {
|
|
| 213 |
- char buf[256]; |
|
| 214 |
- snprintf (buf, sizeof(buf), "( sleep %d ; echo PF %s/%s ; cp \"%s.pf\" \"%s\" ) &", |
|
| 215 |
- context->test_packet_filter, cn, pff, cn, pff); |
|
| 216 |
- printf ("%s\n", buf);
|
|
| 217 |
- system (buf); |
|
| 218 |
- pcc->generated_pf_file = true; |
|
| 219 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 220 |
- } |
|
| 221 |
- else |
|
| 222 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 223 |
- } |
|
| 224 |
- else |
|
| 225 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 226 |
- } |
|
| 227 |
- else |
|
| 228 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 229 |
-} |
|
| 230 |
- |
|
| 231 |
-OPENVPN_EXPORT int |
|
| 232 |
-openvpn_plugin_func_v2 (openvpn_plugin_handle_t handle, |
|
| 233 |
- const int type, |
|
| 234 |
- const char *argv[], |
|
| 235 |
- const char *envp[], |
|
| 236 |
- void *per_client_context, |
|
| 237 |
- struct openvpn_plugin_string_list **return_list) |
|
| 238 |
-{
|
|
| 239 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 240 |
- struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) per_client_context; |
|
| 241 |
- switch (type) |
|
| 242 |
- {
|
|
| 243 |
- case OPENVPN_PLUGIN_UP: |
|
| 244 |
- printf ("OPENVPN_PLUGIN_UP\n");
|
|
| 245 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 246 |
- case OPENVPN_PLUGIN_DOWN: |
|
| 247 |
- printf ("OPENVPN_PLUGIN_DOWN\n");
|
|
| 248 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 249 |
- case OPENVPN_PLUGIN_ROUTE_UP: |
|
| 250 |
- printf ("OPENVPN_PLUGIN_ROUTE_UP\n");
|
|
| 251 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 252 |
- case OPENVPN_PLUGIN_IPCHANGE: |
|
| 253 |
- printf ("OPENVPN_PLUGIN_IPCHANGE\n");
|
|
| 254 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 255 |
- case OPENVPN_PLUGIN_TLS_VERIFY: |
|
| 256 |
- printf ("OPENVPN_PLUGIN_TLS_VERIFY\n");
|
|
| 257 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 258 |
- case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: |
|
| 259 |
- printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
|
|
| 260 |
- return auth_user_pass_verify (context, pcc, argv, envp); |
|
| 261 |
- case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: |
|
| 262 |
- printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
|
|
| 263 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 264 |
- case OPENVPN_PLUGIN_CLIENT_DISCONNECT: |
|
| 265 |
- printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
|
|
| 266 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 267 |
- case OPENVPN_PLUGIN_LEARN_ADDRESS: |
|
| 268 |
- printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
|
|
| 269 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 270 |
- case OPENVPN_PLUGIN_TLS_FINAL: |
|
| 271 |
- printf ("OPENVPN_PLUGIN_TLS_FINAL\n");
|
|
| 272 |
- return tls_final (context, pcc, argv, envp); |
|
| 273 |
- case OPENVPN_PLUGIN_ENABLE_PF: |
|
| 274 |
- printf ("OPENVPN_PLUGIN_ENABLE_PF\n");
|
|
| 275 |
- if (context->test_packet_filter) |
|
| 276 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 277 |
- else |
|
| 278 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 279 |
- default: |
|
| 280 |
- printf ("OPENVPN_PLUGIN_?\n");
|
|
| 281 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 282 |
- } |
|
| 283 |
-} |
|
| 284 |
- |
|
| 285 |
-OPENVPN_EXPORT void * |
|
| 286 |
-openvpn_plugin_client_constructor_v1 (openvpn_plugin_handle_t handle) |
|
| 287 |
-{
|
|
| 288 |
- printf ("FUNC: openvpn_plugin_client_constructor_v1\n");
|
|
| 289 |
- return calloc (1, sizeof (struct plugin_per_client_context)); |
|
| 290 |
-} |
|
| 291 |
- |
|
| 292 |
-OPENVPN_EXPORT void |
|
| 293 |
-openvpn_plugin_client_destructor_v1 (openvpn_plugin_handle_t handle, void *per_client_context) |
|
| 294 |
-{
|
|
| 295 |
- printf ("FUNC: openvpn_plugin_client_destructor_v1\n");
|
|
| 296 |
- free (per_client_context); |
|
| 297 |
-} |
|
| 298 |
- |
|
| 299 |
-OPENVPN_EXPORT void |
|
| 300 |
-openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 301 |
-{
|
|
| 302 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 303 |
- printf ("FUNC: openvpn_plugin_close_v1\n");
|
|
| 304 |
- free (context); |
|
| 305 |
-} |
| 7 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,18 +0,0 @@ |
| 1 |
-# |
|
| 2 |
-# Build an OpenVPN plugin module on Windows/MinGW. |
|
| 3 |
-# The argument should be the base name of the C source file |
|
| 4 |
-# (without the .c). |
|
| 5 |
-# |
|
| 6 |
- |
|
| 7 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 8 |
-INCLUDE="-I../../../build" |
|
| 9 |
- |
|
| 10 |
-CC_FLAGS="-O2 -Wall" |
|
| 11 |
- |
|
| 12 |
-gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c |
|
| 13 |
-gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o |
|
| 14 |
-rm junk.tmp |
|
| 15 |
-dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def |
|
| 16 |
-rm base.tmp |
|
| 17 |
-gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp |
|
| 18 |
-rm temp.exp |
| 19 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,18 +0,0 @@ |
| 1 |
-# |
|
| 2 |
-# Build the OpenVPN down-root plugin module. |
|
| 3 |
-# |
|
| 4 |
- |
|
| 5 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 6 |
-CPPFLAGS=-I../../../include |
|
| 7 |
- |
|
| 8 |
-CC=gcc |
|
| 9 |
-CFLAGS=-O2 -Wall |
|
| 10 |
- |
|
| 11 |
-down-root.so : down-root.o |
|
| 12 |
- $(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) -Wl,-soname,openvpn-down-root.so -o openvpn-down-root.so down-root.o -lc |
|
| 13 |
- |
|
| 14 |
-down-root.o : down-root.c |
|
| 15 |
- $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c down-root.c |
|
| 16 |
- |
|
| 17 |
-clean : |
|
| 18 |
- -rm -f *.o *.so |
| 19 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 0 |
+# |
|
| 1 |
+# OpenVPN (TM) Down Root Plugin -- OpenVPN Plugin |
|
| 2 |
+# |
|
| 3 |
+# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+MAINTAINERCLEANFILES = \ |
|
| 7 |
+ $(srcdir)/Makefile.in |
|
| 8 |
+ |
|
| 9 |
+AM_CFLAGS = \ |
|
| 10 |
+ -I$(top_srcdir)/include |
|
| 11 |
+ |
|
| 12 |
+if ENABLE_PLUGIN_DOWN_ROOT |
|
| 13 |
+plugin_LTLIBRARIES = openvpn-plugin-down-root.la |
|
| 14 |
+dist_doc_DATA = README.down-root |
|
| 15 |
+endif |
|
| 16 |
+ |
|
| 17 |
+openvpn_plugin_down_root_la_SOURCES = \ |
|
| 18 |
+ down-root.c \ |
|
| 19 |
+ down-root.exports |
|
| 20 |
+openvpn_plugin_down_root_la_LDFLAGS = $(AM_LDFLAGS) \ |
|
| 21 |
+ -export-symbols "$(srcdir)/down-root.exports" \ |
|
| 22 |
+ -module -shared -avoid-version -no-undefined |
| 0 | 23 |
deleted file mode 100644 |
| ... | ... |
@@ -1,29 +0,0 @@ |
| 1 |
-down-root -- an OpenVPN Plugin Module |
|
| 2 |
- |
|
| 3 |
-SYNOPSIS |
|
| 4 |
- |
|
| 5 |
-The down-root module allows an OpenVPN configuration to |
|
| 6 |
-call a down script with root privileges, even when privileges |
|
| 7 |
-have been dropped using --user/--group/--chroot. |
|
| 8 |
- |
|
| 9 |
-This module uses a split privilege execution model which will |
|
| 10 |
-fork() before OpenVPN drops root privileges, at the point where |
|
| 11 |
-the --up script is usually called. The module will then remain |
|
| 12 |
-in a wait state until it receives a message from OpenVPN via |
|
| 13 |
-pipe to execute the down script. Thus, the down script will be |
|
| 14 |
-run in the same execution environment as the up script. |
|
| 15 |
- |
|
| 16 |
-BUILD |
|
| 17 |
- |
|
| 18 |
-Build this module with the "make" command. The plugin |
|
| 19 |
-module will be named openvpn-down-root.so |
|
| 20 |
- |
|
| 21 |
-USAGE |
|
| 22 |
- |
|
| 23 |
-To use this module, add to your OpenVPN config file: |
|
| 24 |
- |
|
| 25 |
- plugin openvpn-down-root.so "command ..." |
|
| 26 |
- |
|
| 27 |
-CAVEATS |
|
| 28 |
- |
|
| 29 |
-This module will only work on *nix systems, not Windows. |
| 30 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 0 |
+down-root -- an OpenVPN Plugin Module |
|
| 1 |
+ |
|
| 2 |
+SYNOPSIS |
|
| 3 |
+ |
|
| 4 |
+The down-root module allows an OpenVPN configuration to |
|
| 5 |
+call a down script with root privileges, even when privileges |
|
| 6 |
+have been dropped using --user/--group/--chroot. |
|
| 7 |
+ |
|
| 8 |
+This module uses a split privilege execution model which will |
|
| 9 |
+fork() before OpenVPN drops root privileges, at the point where |
|
| 10 |
+the --up script is usually called. The module will then remain |
|
| 11 |
+in a wait state until it receives a message from OpenVPN via |
|
| 12 |
+pipe to execute the down script. Thus, the down script will be |
|
| 13 |
+run in the same execution environment as the up script. |
|
| 14 |
+ |
|
| 15 |
+BUILD |
|
| 16 |
+ |
|
| 17 |
+Build this module with the "make" command. The plugin |
|
| 18 |
+module will be named openvpn-down-root.so |
|
| 19 |
+ |
|
| 20 |
+USAGE |
|
| 21 |
+ |
|
| 22 |
+To use this module, add to your OpenVPN config file: |
|
| 23 |
+ |
|
| 24 |
+ plugin openvpn-down-root.so "command ..." |
|
| 25 |
+ |
|
| 26 |
+CAVEATS |
|
| 27 |
+ |
|
| 28 |
+This module will only work on *nix systems, not Windows. |
| ... | ... |
@@ -26,6 +26,10 @@ |
| 26 | 26 |
* OpenVPN plugin module to do privileged down-script execution. |
| 27 | 27 |
*/ |
| 28 | 28 |
|
| 29 |
+#ifdef HAVE_CONFIG_H |
|
| 30 |
+#include <config.h> |
|
| 31 |
+#endif |
|
| 32 |
+ |
|
| 29 | 33 |
#include <stdio.h> |
| 30 | 34 |
#include <string.h> |
| 31 | 35 |
#include <unistd.h> |
| ... | ... |
@@ -37,7 +41,7 @@ |
| 37 | 37 |
#include <signal.h> |
| 38 | 38 |
#include <syslog.h> |
| 39 | 39 |
|
| 40 |
-#include "openvpn-plugin.h" |
|
| 40 |
+#include <openvpn-plugin.h> |
|
| 41 | 41 |
|
| 42 | 42 |
#define DEBUG(verb) ((verb) >= 7) |
| 43 | 43 |
|
| 0 | 4 |
deleted file mode 100644 |
| ... | ... |
@@ -1,16 +0,0 @@ |
| 1 |
-OpenVPN plugin examples. |
|
| 2 |
- |
|
| 3 |
-Examples provided: |
|
| 4 |
- |
|
| 5 |
-simple.c -- using the --auth-user-pass-verify callback, verify |
|
| 6 |
- that the username/password is "foo"/"bar". |
|
| 7 |
- |
|
| 8 |
-To build: |
|
| 9 |
- |
|
| 10 |
- ./build simple (Linux/BSD/etc.) |
|
| 11 |
- ./winbuild simple (MinGW on Windows) |
|
| 12 |
- |
|
| 13 |
-To use in OpenVPN, add to config file: |
|
| 14 |
- |
|
| 15 |
- plugin simple.so (Linux/BSD/etc.) |
|
| 16 |
- plugin simple.dll (MinGW on Windows) |
| 17 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,15 +0,0 @@ |
| 1 |
-#!/bin/sh |
|
| 2 |
- |
|
| 3 |
-# |
|
| 4 |
-# Build an OpenVPN plugin module on *nix. The argument should |
|
| 5 |
-# be the base name of the C source file (without the .c). |
|
| 6 |
-# |
|
| 7 |
- |
|
| 8 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 9 |
-CPPFLAGS="${CPPFLAGS:--I../../..}"
|
|
| 10 |
- |
|
| 11 |
-CC="${CC:-gcc}"
|
|
| 12 |
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
|
| 13 |
- |
|
| 14 |
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ |
|
| 15 |
-$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc |
| 16 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,184 +0,0 @@ |
| 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 |
- */ |
|
| 41 |
-struct 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 |
- */ |
|
| 51 |
-static const char * |
|
| 52 |
-get_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 |
- |
|
| 71 |
-OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 72 |
-openvpn_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 |
- |
|
| 105 |
-void |
|
| 106 |
-show (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 |
- |
|
| 155 |
-OPENVPN_EXPORT int |
|
| 156 |
-openvpn_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 |
- |
|
| 179 |
-OPENVPN_EXPORT void |
|
| 180 |
-openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 181 |
-{
|
|
| 182 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 183 |
- free (context); |
|
| 184 |
-} |
| 185 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,247 +0,0 @@ |
| 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-2009 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
| 9 |
- * Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> |
|
| 10 |
- * |
|
| 11 |
- * This program is free software; you can redistribute it and/or modify |
|
| 12 |
- * it under the terms of the GNU General Public License version 2 |
|
| 13 |
- * as published by the Free Software Foundation. |
|
| 14 |
- * |
|
| 15 |
- * This program is distributed in the hope that it will be useful, |
|
| 16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 18 |
- * GNU General Public License for more details. |
|
| 19 |
- * |
|
| 20 |
- * You should have received a copy of the GNU General Public License |
|
| 21 |
- * along with this program (see the file COPYING included with this |
|
| 22 |
- * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 23 |
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 24 |
- */ |
|
| 25 |
- |
|
| 26 |
-/* |
|
| 27 |
- * This plugin is similar to simple.c, except it also logs extra information |
|
| 28 |
- * to stdout for every plugin method called by OpenVPN. The only difference |
|
| 29 |
- * between this (log_v3.c) and log.c is that this module uses the v3 plug-in |
|
| 30 |
- * API. |
|
| 31 |
- * |
|
| 32 |
- * See the README file for build instructions. |
|
| 33 |
- */ |
|
| 34 |
- |
|
| 35 |
-#include <stdio.h> |
|
| 36 |
-#include <string.h> |
|
| 37 |
-#include <stdlib.h> |
|
| 38 |
- |
|
| 39 |
-#define ENABLE_SSL |
|
| 40 |
- |
|
| 41 |
-#include "openvpn-plugin.h" |
|
| 42 |
- |
|
| 43 |
-/* |
|
| 44 |
- * Our context, where we keep our state. |
|
| 45 |
- */ |
|
| 46 |
-struct plugin_context {
|
|
| 47 |
- const char *username; |
|
| 48 |
- const char *password; |
|
| 49 |
-}; |
|
| 50 |
- |
|
| 51 |
-/* |
|
| 52 |
- * Given an environmental variable name, search |
|
| 53 |
- * the envp array for its value, returning it |
|
| 54 |
- * if found or NULL otherwise. |
|
| 55 |
- */ |
|
| 56 |
-static const char * |
|
| 57 |
-get_env (const char *name, const char *envp[]) |
|
| 58 |
-{
|
|
| 59 |
- if (envp) |
|
| 60 |
- {
|
|
| 61 |
- int i; |
|
| 62 |
- const int namelen = strlen (name); |
|
| 63 |
- for (i = 0; envp[i]; ++i) |
|
| 64 |
- {
|
|
| 65 |
- if (!strncmp (envp[i], name, namelen)) |
|
| 66 |
- {
|
|
| 67 |
- const char *cp = envp[i] + namelen; |
|
| 68 |
- if (*cp == '=') |
|
| 69 |
- return cp + 1; |
|
| 70 |
- } |
|
| 71 |
- } |
|
| 72 |
- } |
|
| 73 |
- return NULL; |
|
| 74 |
-} |
|
| 75 |
- |
|
| 76 |
-OPENVPN_EXPORT int |
|
| 77 |
-openvpn_plugin_open_v3 (const int v3structver, |
|
| 78 |
- struct openvpn_plugin_args_open_in const *args, |
|
| 79 |
- struct openvpn_plugin_args_open_return *ret) |
|
| 80 |
-{
|
|
| 81 |
- struct plugin_context *context = NULL; |
|
| 82 |
- |
|
| 83 |
- /* Check that we are API compatible */ |
|
| 84 |
- if( v3structver != OPENVPN_PLUGINv3_STRUCTVER ) {
|
|
| 85 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 86 |
- } |
|
| 87 |
- |
|
| 88 |
- /* Which callbacks to intercept. */ |
|
| 89 |
- ret->type_mask = |
|
| 90 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | |
|
| 91 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | |
|
| 92 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | |
|
| 93 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | |
|
| 94 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | |
|
| 95 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | |
|
| 96 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | |
|
| 97 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | |
|
| 98 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | |
|
| 99 |
- OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); |
|
| 100 |
- |
|
| 101 |
- |
|
| 102 |
- /* Allocate our context */ |
|
| 103 |
- context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 104 |
- |
|
| 105 |
- /* Set the username/password we will require. */ |
|
| 106 |
- context->username = "foo"; |
|
| 107 |
- context->password = "bar"; |
|
| 108 |
- |
|
| 109 |
- /* Point the global context handle to our newly created context */ |
|
| 110 |
- ret->handle = (void *) context; |
|
| 111 |
- |
|
| 112 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 113 |
-} |
|
| 114 |
- |
|
| 115 |
-void |
|
| 116 |
-show (const int type, const char *argv[], const char *envp[]) |
|
| 117 |
-{
|
|
| 118 |
- size_t i; |
|
| 119 |
- switch (type) |
|
| 120 |
- {
|
|
| 121 |
- case OPENVPN_PLUGIN_UP: |
|
| 122 |
- printf ("OPENVPN_PLUGIN_UP\n");
|
|
| 123 |
- break; |
|
| 124 |
- case OPENVPN_PLUGIN_DOWN: |
|
| 125 |
- printf ("OPENVPN_PLUGIN_DOWN\n");
|
|
| 126 |
- break; |
|
| 127 |
- case OPENVPN_PLUGIN_ROUTE_UP: |
|
| 128 |
- printf ("OPENVPN_PLUGIN_ROUTE_UP\n");
|
|
| 129 |
- break; |
|
| 130 |
- case OPENVPN_PLUGIN_IPCHANGE: |
|
| 131 |
- printf ("OPENVPN_PLUGIN_IPCHANGE\n");
|
|
| 132 |
- break; |
|
| 133 |
- case OPENVPN_PLUGIN_TLS_VERIFY: |
|
| 134 |
- printf ("OPENVPN_PLUGIN_TLS_VERIFY\n");
|
|
| 135 |
- break; |
|
| 136 |
- case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: |
|
| 137 |
- printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
|
|
| 138 |
- break; |
|
| 139 |
- case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: |
|
| 140 |
- printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
|
|
| 141 |
- break; |
|
| 142 |
- case OPENVPN_PLUGIN_CLIENT_DISCONNECT: |
|
| 143 |
- printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
|
|
| 144 |
- break; |
|
| 145 |
- case OPENVPN_PLUGIN_LEARN_ADDRESS: |
|
| 146 |
- printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
|
|
| 147 |
- break; |
|
| 148 |
- case OPENVPN_PLUGIN_TLS_FINAL: |
|
| 149 |
- printf ("OPENVPN_PLUGIN_TLS_FINAL\n");
|
|
| 150 |
- break; |
|
| 151 |
- default: |
|
| 152 |
- printf ("OPENVPN_PLUGIN_?\n");
|
|
| 153 |
- break; |
|
| 154 |
- } |
|
| 155 |
- |
|
| 156 |
- printf ("ARGV\n");
|
|
| 157 |
- for (i = 0; argv[i] != NULL; ++i) |
|
| 158 |
- printf ("%d '%s'\n", (int)i, argv[i]);
|
|
| 159 |
- |
|
| 160 |
- printf ("ENVP\n");
|
|
| 161 |
- for (i = 0; envp[i] != NULL; ++i) |
|
| 162 |
- printf ("%d '%s'\n", (int)i, envp[i]);
|
|
| 163 |
-} |
|
| 164 |
- |
|
| 165 |
-static void |
|
| 166 |
-x509_print_info (X509 *x509crt) |
|
| 167 |
-{
|
|
| 168 |
- int i, n; |
|
| 169 |
- int fn_nid; |
|
| 170 |
- ASN1_OBJECT *fn; |
|
| 171 |
- ASN1_STRING *val; |
|
| 172 |
- X509_NAME *x509_name; |
|
| 173 |
- X509_NAME_ENTRY *ent; |
|
| 174 |
- const char *objbuf; |
|
| 175 |
- unsigned char *buf; |
|
| 176 |
- |
|
| 177 |
- x509_name = X509_get_subject_name (x509crt); |
|
| 178 |
- n = X509_NAME_entry_count (x509_name); |
|
| 179 |
- for (i = 0; i < n; ++i) |
|
| 180 |
- {
|
|
| 181 |
- ent = X509_NAME_get_entry (x509_name, i); |
|
| 182 |
- if (!ent) |
|
| 183 |
- continue; |
|
| 184 |
- fn = X509_NAME_ENTRY_get_object (ent); |
|
| 185 |
- if (!fn) |
|
| 186 |
- continue; |
|
| 187 |
- val = X509_NAME_ENTRY_get_data (ent); |
|
| 188 |
- if (!val) |
|
| 189 |
- continue; |
|
| 190 |
- fn_nid = OBJ_obj2nid (fn); |
|
| 191 |
- if (fn_nid == NID_undef) |
|
| 192 |
- continue; |
|
| 193 |
- objbuf = OBJ_nid2sn (fn_nid); |
|
| 194 |
- if (!objbuf) |
|
| 195 |
- continue; |
|
| 196 |
- buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ |
|
| 197 |
- if (ASN1_STRING_to_UTF8 (&buf, val) <= 0) |
|
| 198 |
- continue; |
|
| 199 |
- |
|
| 200 |
- printf("X509 %s: %s\n", objbuf, (char *)buf);
|
|
| 201 |
- OPENSSL_free (buf); |
|
| 202 |
- } |
|
| 203 |
-} |
|
| 204 |
- |
|
| 205 |
- |
|
| 206 |
- |
|
| 207 |
-OPENVPN_EXPORT int |
|
| 208 |
-openvpn_plugin_func_v3 (const int version, |
|
| 209 |
- struct openvpn_plugin_args_func_in const *args, |
|
| 210 |
- struct openvpn_plugin_args_func_return *retptr) |
|
| 211 |
-{
|
|
| 212 |
- struct plugin_context *context = (struct plugin_context *) args->handle; |
|
| 213 |
- |
|
| 214 |
- printf("\nopenvpn_plugin_func_v3() :::::>> ");
|
|
| 215 |
- show (args->type, args->argv, args->envp); |
|
| 216 |
- |
|
| 217 |
- /* Dump some X509 information if we're in the TLS_VERIFY phase */ |
|
| 218 |
- if ((args->type == OPENVPN_PLUGIN_TLS_VERIFY) && args->current_cert ) {
|
|
| 219 |
- printf("---- X509 Subject information ----\n");
|
|
| 220 |
- printf("Certificate depth: %i\n", args->current_cert_depth);
|
|
| 221 |
- x509_print_info(args->current_cert); |
|
| 222 |
- printf("----------------------------------\n");
|
|
| 223 |
- } |
|
| 224 |
- |
|
| 225 |
- /* check entered username/password against what we require */ |
|
| 226 |
- if (args->type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) |
|
| 227 |
- {
|
|
| 228 |
- /* get username/password from envp string array */ |
|
| 229 |
- const char *username = get_env ("username", args->envp);
|
|
| 230 |
- const char *password = get_env ("password", args->envp);
|
|
| 231 |
- |
|
| 232 |
- if (username && !strcmp (username, context->username) |
|
| 233 |
- && password && !strcmp (password, context->password)) |
|
| 234 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 235 |
- else |
|
| 236 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 237 |
- } |
|
| 238 |
- else |
|
| 239 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 240 |
-} |
|
| 241 |
- |
|
| 242 |
-OPENVPN_EXPORT void |
|
| 243 |
-openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 244 |
-{
|
|
| 245 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 246 |
- free (context); |
|
| 247 |
-} |
| 248 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,120 +0,0 @@ |
| 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 file implements a simple OpenVPN plugin module which |
|
| 27 |
- * will examine the username/password provided by a client, |
|
| 28 |
- * and make an accept/deny determination. Will run |
|
| 29 |
- * on Windows or *nix. |
|
| 30 |
- * |
|
| 31 |
- * See the README file for build instructions. |
|
| 32 |
- */ |
|
| 33 |
- |
|
| 34 |
-#include <stdio.h> |
|
| 35 |
-#include <string.h> |
|
| 36 |
-#include <stdlib.h> |
|
| 37 |
- |
|
| 38 |
-#include "openvpn-plugin.h" |
|
| 39 |
- |
|
| 40 |
-/* |
|
| 41 |
- * Our context, where we keep our state. |
|
| 42 |
- */ |
|
| 43 |
-struct plugin_context {
|
|
| 44 |
- const char *username; |
|
| 45 |
- const char *password; |
|
| 46 |
-}; |
|
| 47 |
- |
|
| 48 |
-/* |
|
| 49 |
- * Given an environmental variable name, search |
|
| 50 |
- * the envp array for its value, returning it |
|
| 51 |
- * if found or NULL otherwise. |
|
| 52 |
- */ |
|
| 53 |
-static const char * |
|
| 54 |
-get_env (const char *name, const char *envp[]) |
|
| 55 |
-{
|
|
| 56 |
- if (envp) |
|
| 57 |
- {
|
|
| 58 |
- int i; |
|
| 59 |
- const int namelen = strlen (name); |
|
| 60 |
- for (i = 0; envp[i]; ++i) |
|
| 61 |
- {
|
|
| 62 |
- if (!strncmp (envp[i], name, namelen)) |
|
| 63 |
- {
|
|
| 64 |
- const char *cp = envp[i] + namelen; |
|
| 65 |
- if (*cp == '=') |
|
| 66 |
- return cp + 1; |
|
| 67 |
- } |
|
| 68 |
- } |
|
| 69 |
- } |
|
| 70 |
- return NULL; |
|
| 71 |
-} |
|
| 72 |
- |
|
| 73 |
-OPENVPN_EXPORT openvpn_plugin_handle_t |
|
| 74 |
-openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) |
|
| 75 |
-{
|
|
| 76 |
- struct plugin_context *context; |
|
| 77 |
- |
|
| 78 |
- /* |
|
| 79 |
- * Allocate our context |
|
| 80 |
- */ |
|
| 81 |
- context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); |
|
| 82 |
- |
|
| 83 |
- /* |
|
| 84 |
- * Set the username/password we will require. |
|
| 85 |
- */ |
|
| 86 |
- context->username = "foo"; |
|
| 87 |
- context->password = "bar"; |
|
| 88 |
- |
|
| 89 |
- /* |
|
| 90 |
- * We are only interested in intercepting the |
|
| 91 |
- * --auth-user-pass-verify callback. |
|
| 92 |
- */ |
|
| 93 |
- *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY); |
|
| 94 |
- |
|
| 95 |
- return (openvpn_plugin_handle_t) context; |
|
| 96 |
-} |
|
| 97 |
- |
|
| 98 |
-OPENVPN_EXPORT int |
|
| 99 |
-openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) |
|
| 100 |
-{
|
|
| 101 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 102 |
- |
|
| 103 |
- /* get username/password from envp string array */ |
|
| 104 |
- const char *username = get_env ("username", envp);
|
|
| 105 |
- const char *password = get_env ("password", envp);
|
|
| 106 |
- |
|
| 107 |
- /* check entered username/password against what we require */ |
|
| 108 |
- if (username && !strcmp (username, context->username) |
|
| 109 |
- && password && !strcmp (password, context->password)) |
|
| 110 |
- return OPENVPN_PLUGIN_FUNC_SUCCESS; |
|
| 111 |
- else |
|
| 112 |
- return OPENVPN_PLUGIN_FUNC_ERROR; |
|
| 113 |
-} |
|
| 114 |
- |
|
| 115 |
-OPENVPN_EXPORT void |
|
| 116 |
-openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) |
|
| 117 |
-{
|
|
| 118 |
- struct plugin_context *context = (struct plugin_context *) handle; |
|
| 119 |
- free (context); |
|
| 120 |
-} |
| 7 | 1 |
deleted file mode 100755 |
| ... | ... |
@@ -1,18 +0,0 @@ |
| 1 |
-# |
|
| 2 |
-# Build an OpenVPN plugin module on Windows/MinGW. |
|
| 3 |
-# The argument should be the base name of the C source file |
|
| 4 |
-# (without the .c). |
|
| 5 |
-# |
|
| 6 |
- |
|
| 7 |
-# This directory is where we will look for openvpn-plugin.h |
|
| 8 |
-INCLUDE="-I../../../include" |
|
| 9 |
- |
|
| 10 |
-CC_FLAGS="-O2 -Wall" |
|
| 11 |
- |
|
| 12 |
-gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c |
|
| 13 |
-gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o |
|
| 14 |
-rm junk.tmp |
|
| 15 |
-dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def |
|
| 16 |
-rm base.tmp |
|
| 17 |
-gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp |
|
| 18 |
-rm temp.exp |