auth-pam.pl 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/perl -t
  2. # OpenVPN PAM AUTHENTICATON
  3. # This script can be used to add PAM-based authentication
  4. # to OpenVPN 2.0. The OpenVPN client must provide
  5. # a username/password, using the --auth-user-pass directive.
  6. # The OpenVPN server should specify --auth-user-pass-verify
  7. # with this script as the argument and the 'via-file' method
  8. # specified. The server can also optionally specify
  9. # --client-cert-not-required and/or --username-as-common-name.
  10. # SCRIPT OPERATION
  11. # Return success or failure status based on whether or not a
  12. # given username/password authenticates using PAM.
  13. # Caller should write username/password as two lines in a file
  14. # which is passed to this script as a command line argument.
  15. # CAVEATS
  16. # * Requires Authen::PAM module, which may also
  17. # require the pam-devel package.
  18. # * May need to be run as root in order to
  19. # access username/password file.
  20. # NOTES
  21. # * This script is provided mostly as a demonstration of the
  22. # --auth-user-pass-verify script capability in OpenVPN.
  23. # For real world usage, see the auth-pam module in the plugin
  24. # folder.
  25. use Authen::PAM;
  26. use POSIX;
  27. # This "conversation function" will pass
  28. # $password to PAM when it asks for it.
  29. sub my_conv_func {
  30. my @res;
  31. while ( @_ ) {
  32. my $code = shift;
  33. my $msg = shift;
  34. my $ans = "";
  35. $ans = $password if $msg =~ /[Pp]assword/;
  36. push @res, (PAM_SUCCESS(),$ans);
  37. }
  38. push @res, PAM_SUCCESS();
  39. return @res;
  40. }
  41. # Identify service type to PAM
  42. $service = "login";
  43. # Get username/password from file
  44. if ($ARG = shift @ARGV) {
  45. if (!open (UPFILE, "<$ARG")) {
  46. print "Could not open username/password file: $ARG\n";
  47. exit 1;
  48. }
  49. } else {
  50. print "No username/password file specified on command line\n";
  51. exit 1;
  52. }
  53. $username = <UPFILE>;
  54. $password = <UPFILE>;
  55. if (!$username || !$password) {
  56. print "Username/password not found in file: $ARG\n";
  57. exit 1;
  58. }
  59. chomp $username;
  60. chomp $password;
  61. close (UPFILE);
  62. # Initialize PAM object
  63. if (!ref($pamh = new Authen::PAM($service, $username, \&my_conv_func))) {
  64. print "Authen::PAM init failed\n";
  65. exit 1;
  66. }
  67. # Authenticate with PAM
  68. $res = $pamh->pam_authenticate;
  69. # Return success or failure
  70. if ($res == PAM_SUCCESS()) {
  71. exit 0;
  72. } else {
  73. print "Auth '$username' failed, PAM said: ", $pamh->pam_strerror($res), "\n";
  74. exit 1;
  75. }