12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- #!/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;
|