diff options
Diffstat (limited to 'app/openvpn/sample/sample-scripts/verify-cn')
| -rwxr-xr-x | app/openvpn/sample/sample-scripts/verify-cn | 64 | 
1 files changed, 64 insertions, 0 deletions
| diff --git a/app/openvpn/sample/sample-scripts/verify-cn b/app/openvpn/sample/sample-scripts/verify-cn new file mode 100755 index 00000000..6e747ef1 --- /dev/null +++ b/app/openvpn/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; | 
