verify-cn 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/perl
  2. # verify-cn -- a sample OpenVPN tls-verify script
  3. #
  4. # Return 0 if cn matches the common name component of
  5. # subject, 1 otherwise.
  6. #
  7. # For example in OpenVPN, you could use the directive:
  8. #
  9. # tls-verify "./verify-cn /etc/openvpn/allowed_clients"
  10. #
  11. # This would cause the connection to be dropped unless
  12. # the client common name is listed on a line in the
  13. # allowed_clients file.
  14. die "usage: verify-cn cnfile certificate_depth subject" if (@ARGV != 3);
  15. # Parse out arguments:
  16. # cnfile -- The file containing the list of common names, one per
  17. # line, which the client is required to have,
  18. # taken from the argument to the tls-verify directive
  19. # in the OpenVPN config file.
  20. # The file can have blank lines and comment lines that begin
  21. # with the # character.
  22. # depth -- The current certificate chain depth. In a typical
  23. # bi-level chain, the root certificate will be at level
  24. # 1 and the client certificate will be at level 0.
  25. # This script will be called separately for each level.
  26. # x509 -- the X509 subject string as extracted by OpenVPN from
  27. # the client's provided certificate.
  28. ($cnfile, $depth, $x509) = @ARGV;
  29. if ($depth == 0) {
  30. # If depth is zero, we know that this is the final
  31. # certificate in the chain (i.e. the client certificate),
  32. # and the one we are interested in examining.
  33. # If so, parse out the common name substring in
  34. # the X509 subject string.
  35. if ($x509 =~ / CN=([^,]+)/) {
  36. $cn = $1;
  37. # Accept the connection if the X509 common name
  38. # string matches the passed cn argument.
  39. open(FH, '<', $cnfile) or exit 1; # can't open, nobody authenticates!
  40. while (defined($line = <FH>)) {
  41. if ($line !~ /^[[:space:]]*(#|$)/o) {
  42. chop($line);
  43. if ($line eq $cn) {
  44. exit 0;
  45. }
  46. }
  47. }
  48. close(FH);
  49. }
  50. # Authentication failed -- Either we could not parse
  51. # the X509 subject string, or the common name in the
  52. # subject string didn't match the passed cn argument.
  53. exit 1;
  54. }
  55. # If depth is nonzero, tell OpenVPN to continue processing
  56. # the certificate chain.
  57. exit 0;