?
Solved

Change existing perl script/ or write new simple one.

Posted on 2009-07-14
8
Medium Priority
?
509 Views
Last Modified: 2012-06-27
Hi All
I am using OpenVPN in username/pwd mode. In other words with no certifcates. Apart from the security risk that I know I am facing a problem.

The present existing perl script "displayed below" waits for the input to be sent from the client, after that it is suppsed to create a hashed version of the password and compare it to /etc/shadow or /etc/passwd I guess. I am not really sure. From the documentation it says it will check a file I create with user on a line and pwd on another line. Well, I could not get it to work and I am not really interested in using PAM.

In short, I need a perl script working similarly to the below in terms of waiting for input and presenting 0 for failure and 1 for success it should be able to do the following:

1- Parse/receive input arguments the same way the script below does.
2- Compare the username/pwd provided against a file where username + password pairs are one pair per line, example username:password
3- Return 1 for a match and 0 for  failure.

Thanks
#!/usr/bin/perl
 
# 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.
 
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";
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";
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 1;
} else {
    print "Auth '$username' failed, PAM said: ", $pamh->pam_strerror($res), "\n";
    exit 0;
}

Open in new window

0
Comment
Question by:http:// thevpn.guru
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 39

Expert Comment

by:Adam314
ID: 24854253
Was there a copy/paste error in the script?  It doesn't look correct.
0
 
LVL 19

Author Comment

by:http:// thevpn.guru
ID: 24854464
0
 
LVL 39

Accepted Solution

by:
Adam314 earned 2000 total points
ID: 24854509
Replace lines 66 - 77 with this:
my $Line = <UPFILE>;
chomp $Line;
if($Line !~ /^(.*?):(.*)$/) {
	print "Username/password not found in file: $ARG\n";
	exit 1;
}
 
my $username = $1;
my $password = $2;

Open in new window

0
Application Discovery Service in AWS

In the era of the cloud, customers migrating away from their existing on-premise infrastructure. This requires lots of planning, strategies, and effort to identify their existing resources and determine how best to migrate.  Datacenter migrations happen in four phases -

 
LVL 19

Author Comment

by:http:// thevpn.guru
ID: 24854543
One thing to note here is that the username password is blank text in the file and sent over unhashed, while from what I understood from the file is that it uses pam to hash the passwords. Another thing here is that the scripts seems to use the login mechansim of linux to do something ..  I dont need that as well.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24854584
The code snipped I gave will read a single line from a file.  If that line does not have the a username followed by a colon followed by a password, like "username:password", it will display a message and exit with 1.  If it does have that pattern, it'll save the username to the $username variable, and the password to the $password variable.

The script expects the name of the file to be supplied on the command line.  This was the way your original script works, and that was not changed.

If this wasn't what you wanted, I misunderstood your request.
0
 
LVL 19

Author Comment

by:http:// thevpn.guru
ID: 24872117
The thing I am concerned about is that the original script uses the login facilities of the linux system, I dont need those and  the script also uses pam authentication at:

#
if (!ref($pamh = new Authen::PAM($service, $username, \&my_conv_func))) {
#
    print "Authen::PAM init failed\n";
#
    exit 1;

This I dont need as well...I simply want a script to check the username and password against the text file in and take input and out put in the way the orignal script does without going into any other features.


Thanks for all of your help
0
 
LVL 19

Author Comment

by:http:// thevpn.guru
ID: 24872559
I did test the code with the changes you suggested and I got :

212.36.208.1:31055 Expected Remote Options hash (VER=V4): '41690919'
Thu Jul 16 12:03:20 2009 212.36.208.1:31055 TLS: Initial packet from 212.36.208.1:31055, sid=3ee922c5 118483e1
Username/password not found in file: ./newpassword
Thu Jul 16 12:03:24 2009 212.36.208.1:31055 TLS Auth Error: Auth Username/Password verification failed for peer
Thu Jul 16 12:03:24 2009 212.36.208.1:31055 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA
Thu Jul 16 12:03:24 2009 212.36.208.1:31055 [] Peer Connection Initiated with 212.36.208.1:31055
Thu Jul 16 12:03:25 2009 212.36.208.1:31055
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24874594
>>I simply want a script to check the username and password against the text file in and take input and
>>out put in the way the orignal script does
The original script gets the username and password through PAM.  If you don't want to use PAM, but want to get them the same way, I'm not sure what you want.
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Dictionaries contain key:value pairs. Which means a collection of tuples with an attribute name and an assigned value to it. The semicolon present in between each key and values and attribute with values are delimited with a comma.  In python we can…
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question