caciqueman has asked for the wisdom of the Perl Monks concerning the following question:

I am absolutely new and trying to modify a password reminder script to work on my site.
my database is set up like this:
(in a file called userpass.dat)
UserName|Password|email@address.com&AnotherName|AnotherPass|anothermail@whatever.com&
The $user, $name, $email are seperated by "|" and each
entry is seperated by "&", without a carriage return

the script starts like this, after the shebang

$datafile = "/web/home/data/userpass.dat"; read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/~!/ ~!/g; $FORM{$name} = $value; } $string = $FORM{'mail'}; open(INF,$datafile); @mydata = <INF>; close(INF); $count = 0; foreach $i (@mydata) { chomp($i); ($user,$pass,$email) = split(/\|/,$i); if (uc($email) eq uc($string)) { open (MAIL, "| $sendmail -t") || die "I can't open sendmail\n"; print MAIL "To: $email\n"; print MAIL "From: $myemail\n"; print MAIL "Subject: The passwords\n"; print MAIL "\n"; print MAIL "Here are the passwords you asked for:\n"; print MAIL "\n"; print MAIL "Field 1: $user\n"; print MAIL "Field 2: $pass\n"; print MAIL "Field 3: $email\n"; print MAIL "\n";
Can anyone tell me where I am going wrong ??
I tried changing the first
($name, $value) = split(/=/, $pair);
to ($name, $value) = split(/&/, $pair);
and that didnt work.
The script runs but gives me the error message that
it cant find the email address in the database.
Any suggestions ?
Thanks,

Replies are listed 'Best First'.
(Ovid) Re: Lost acolyte
by Ovid (Cardinal) on Aug 25, 2001 at 03:11 UTC

    Here's a much cleaner version of your script.

    #!/usr/bin/perl -wT use strict; use CGI qw/:standard/; my $datafile = "/web/home/data/userpass.dat"; my $myemail = 'foo@bar.com'; my $sendmail = '/usr/bin/mail'; #????? my %FORM = map { $_, @{ [param($_)] } > 1 ? [param($_)] : param($_) } + param(); my $string = $FORM{'mail'}; open INF,"< $datafile" or die "Can't open $datafile for reading: $!"; my @mydata; { local $/ = '&'; @mydata = <INF>; } close(INF); my $count = 0; foreach my $i (@mydata) { my ( $user, $pass, $email ) = split(/\|/,$i); next if (uc($email) ne uc($string)); open (MAIL, "| $sendmail -t") || die "I can't open sendmail\n"; print MAIL "To: $email\n"; print MAIL "From: $myemail\n"; print MAIL "Subject: The passwords\n"; print MAIL "\n"; print MAIL "Here are the passwords you asked for:\n"; print MAIL "\n"; print MAIL "Field 1: $user\n"; print MAIL "Field 2: $pass\n"; print MAIL "Field 3: $email\n"; print MAIL "\n"; }

    Frankly, I don't know much about the security implications of using the mail program that you are wanting to use. I would strongly suggest using one of the CPAN mail packages. Any monks who have advice on this should speak up! :)

    Also, please read perlsec for information on cleaning up the data in the %FORM hash.

    Cheers,
    Ovid

    Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Lost acolyte
by Zaxo (Archbishop) on Aug 25, 2001 at 03:20 UTC

    This is an ambitious first project. You should get an _extremely_ careful review before installing it where the public can get at it.

    1. use CGI; # Really
    2. Read the fine $ perldoc perlsec
    3. Consider how many places a user can get a '&' or '|' into your data.

    When a cgi starts working is the most dangerous moment ;-)

    After Compline,
    Zaxo

Re: Lost acolyte
by rchiav (Deacon) on Aug 25, 2001 at 03:07 UTC
    When you do this..
    open(INF,$datafile); @mydata = <INF>; close(INF);
    It puts each line into the array as a seperate entry. So if there's no new lines in the file, all user records are in one entry in the array. You're never going to look at more than the first entry.

    Secondly, you're splitting some input from STDIN on '&' and then again on '='. What is this data and how is it supposed to be formed? You never mentioned it.

    Rich

Re: Lost acolyte, splitting fields out of flat-file database
by greywolf (Priest) on Aug 25, 2001 at 20:40 UTC
    Since there are no carriage returns in you data file all the info got read as 1 entry.

    You need to split your file data on "&" to get each entry. You then need to split each entry on "|" to get $user, $pass and $email.

    @entries = split(/&/, @mydata); foreach $entry (@entries) { ($user,$pass,$email) = split(/\|/,$entry); ## Work with the vars ## }


    mr greywolf