summaryrefslogtreecommitdiff
path: root/sample/sample-scripts
diff options
context:
space:
mode:
Diffstat (limited to 'sample/sample-scripts')
-rwxr-xr-xsample/sample-scripts/auth-pam.pl97
-rwxr-xr-xsample/sample-scripts/bridge-start39
-rwxr-xr-xsample/sample-scripts/bridge-stop18
-rwxr-xr-xsample/sample-scripts/ucn.pl11
-rwxr-xr-xsample/sample-scripts/verify-cn64
5 files changed, 229 insertions, 0 deletions
diff --git a/sample/sample-scripts/auth-pam.pl b/sample/sample-scripts/auth-pam.pl
new file mode 100755
index 0000000..5333bad
--- /dev/null
+++ b/sample/sample-scripts/auth-pam.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl -t
+
+# OpenVPN PAM AUTHENTICATON
+# This script can be used to add PAM-based authentication
+# to OpenVPN 2.0. The OpenVPN client must provide
+# a username/password, using the --auth-user-pass directive.
+# The OpenVPN server should specify --auth-user-pass-verify
+# with this script as the argument and the 'via-file' method
+# specified. The server can also optionally specify
+# --client-cert-not-required and/or --username-as-common-name.
+
+# SCRIPT OPERATION
+# Return success or failure status based on whether or not a
+# given username/password authenticates using PAM.
+# Caller should write username/password as two lines in a file
+# which is passed to this script as a command line argument.
+
+# CAVEATS
+# * Requires Authen::PAM module, which may also
+# require the pam-devel package.
+# * May need to be run as root in order to
+# access username/password file.
+
+# NOTES
+# * This script is provided mostly as a demonstration of the
+# --auth-user-pass-verify script capability in OpenVPN.
+# For real world usage, see the auth-pam module in the plugin
+# folder.
+
+use Authen::PAM;
+use POSIX;
+
+# This "conversation function" will pass
+# $password to PAM when it asks for it.
+
+sub my_conv_func {
+ my @res;
+ while ( @_ ) {
+ my $code = shift;
+ my $msg = shift;
+ my $ans = "";
+
+ $ans = $password if $msg =~ /[Pp]assword/;
+
+ push @res, (PAM_SUCCESS(),$ans);
+ }
+ push @res, PAM_SUCCESS();
+ return @res;
+}
+
+# Identify service type to PAM
+$service = "login";
+
+# Get username/password from file
+
+if ($ARG = shift @ARGV) {
+ if (!open (UPFILE, "<$ARG")) {
+ print "Could not open username/password file: $ARG\n";
+ exit 1;
+ }
+} else {
+ print "No username/password file specified on command line\n";
+ exit 1;
+}
+
+$username = <UPFILE>;
+$password = <UPFILE>;
+
+if (!$username || !$password) {
+ print "Username/password not found in file: $ARG\n";
+ exit 1;
+}
+
+chomp $username;
+chomp $password;
+
+close (UPFILE);
+
+# Initialize PAM object
+
+if (!ref($pamh = new Authen::PAM($service, $username, \&my_conv_func))) {
+ print "Authen::PAM init failed\n";
+ exit 1;
+}
+
+# Authenticate with PAM
+
+$res = $pamh->pam_authenticate;
+
+# Return success or failure
+
+if ($res == PAM_SUCCESS()) {
+ exit 0;
+} else {
+ print "Auth '$username' failed, PAM said: ", $pamh->pam_strerror($res), "\n";
+ exit 1;
+}
diff --git a/sample/sample-scripts/bridge-start b/sample/sample-scripts/bridge-start
new file mode 100755
index 0000000..d20a260
--- /dev/null
+++ b/sample/sample-scripts/bridge-start
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+#################################
+# Set up Ethernet bridge on Linux
+# Requires: bridge-utils
+#################################
+
+# Define Bridge Interface
+br="br0"
+
+# Define list of TAP interfaces to be bridged,
+# for example tap="tap0 tap1 tap2".
+tap="tap0"
+
+# Define physical ethernet interface to be bridged
+# with TAP interface(s) above.
+eth="eth0"
+eth_ip="192.168.8.4"
+eth_netmask="255.255.255.0"
+eth_broadcast="192.168.8.255"
+
+for t in $tap; do
+ openvpn --mktun --dev $t
+done
+
+brctl addbr $br
+brctl addif $br $eth
+
+for t in $tap; do
+ brctl addif $br $t
+done
+
+for t in $tap; do
+ ifconfig $t 0.0.0.0 promisc up
+done
+
+ifconfig $eth 0.0.0.0 promisc up
+
+ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
diff --git a/sample/sample-scripts/bridge-stop b/sample/sample-scripts/bridge-stop
new file mode 100755
index 0000000..8192779
--- /dev/null
+++ b/sample/sample-scripts/bridge-stop
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+####################################
+# Tear Down Ethernet bridge on Linux
+####################################
+
+# Define Bridge Interface
+br="br0"
+
+# Define list of TAP interfaces to be bridged together
+tap="tap0"
+
+ifconfig $br down
+brctl delbr $br
+
+for t in $tap; do
+ openvpn --rmtun --dev $t
+done
diff --git a/sample/sample-scripts/ucn.pl b/sample/sample-scripts/ucn.pl
new file mode 100755
index 0000000..6d708f8
--- /dev/null
+++ b/sample/sample-scripts/ucn.pl
@@ -0,0 +1,11 @@
+#!/usr/bin/perl -t
+
+# OpenVPN --auth-user-pass-verify script.
+# Only authenticate if username equals common_name.
+# In OpenVPN config file:
+# auth-user-pass-verify ./ucn.pl via-env
+
+$username = $ENV{'username'};
+$common_name = $ENV{'common_name'};
+
+exit !(length($username) > 0 && length($common_name) > 0 && $username eq $common_name);
diff --git a/sample/sample-scripts/verify-cn b/sample/sample-scripts/verify-cn
new file mode 100755
index 0000000..6e747ef
--- /dev/null
+++ b/sample/sample-scripts/verify-cn
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+
+# verify-cn -- a sample OpenVPN tls-verify script
+#
+# Return 0 if cn matches the common name component of
+# subject, 1 otherwise.
+#
+# For example in OpenVPN, you could use the directive:
+#
+# tls-verify "./verify-cn /etc/openvpn/allowed_clients"
+#
+# This would cause the connection to be dropped unless
+# the client common name is listed on a line in the
+# allowed_clients file.
+
+die "usage: verify-cn cnfile certificate_depth subject" if (@ARGV != 3);
+
+# Parse out arguments:
+# cnfile -- The file containing the list of common names, one per
+# line, which the client is required to have,
+# taken from the argument to the tls-verify directive
+# in the OpenVPN config file.
+# The file can have blank lines and comment lines that begin
+# with the # character.
+# depth -- The current certificate chain depth. In a typical
+# bi-level chain, the root certificate will be at level
+# 1 and the client certificate will be at level 0.
+# This script will be called separately for each level.
+# x509 -- the X509 subject string as extracted by OpenVPN from
+# the client's provided certificate.
+($cnfile, $depth, $x509) = @ARGV;
+
+if ($depth == 0) {
+ # If depth is zero, we know that this is the final
+ # certificate in the chain (i.e. the client certificate),
+ # and the one we are interested in examining.
+ # If so, parse out the common name substring in
+ # the X509 subject string.
+
+ if ($x509 =~ / CN=([^,]+)/) {
+ $cn = $1;
+ # Accept the connection if the X509 common name
+ # string matches the passed cn argument.
+ open(FH, '<', $cnfile) or exit 1; # can't open, nobody authenticates!
+ while (defined($line = <FH>)) {
+ if ($line !~ /^[[:space:]]*(#|$)/o) {
+ chop($line);
+ if ($line eq $cn) {
+ exit 0;
+ }
+ }
+ }
+ close(FH);
+ }
+
+ # Authentication failed -- Either we could not parse
+ # the X509 subject string, or the common name in the
+ # subject string didn't match the passed cn argument.
+ exit 1;
+}
+
+# If depth is nonzero, tell OpenVPN to continue processing
+# the certificate chain.
+exit 0;