Solved

Password once only

Posted on 2002-04-11
15
425 Views
Last Modified: 2012-06-19
I would like to "sell" access through a password to a pdf-file, but somehow i want the password to be "consumed" after one use. That is, i don't want the users to be able to pass the PW along to all their friends for a multitude of downloads.
Is there a way in Perl to allow a PW to be sent by e-mail, allow the user to download the file once, but then no more?

Best,
Al
0
Comment
Question by:algabatz
[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
  • 8
  • 3
  • 3
  • +1
15 Comments
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6934046
yaou can do sth like this :


Give the pass:
1. Generate encoded password
2.1 Send it to the users email
2.2 Save it to local file

Users login:
1. Check if the password match to any of the passwords in the local file
If no :
2. deny access
If so :
2. read the pdf and print it to the user
3. delete his password from the local file


0
 
LVL 1

Author Comment

by:algabatz
ID: 6936064
Sounds great. tricky part is to write the code...

/Al
0
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6936876
OK  I'll write the code for you :)but just pls give me some time becouse I have no time now.

I hope to do it till tommorow :) is it OK ?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6937006
pls tel me also can you use sendmail? what is  the web server?  the OS ? Perl version ?
0
 
LVL 1

Author Comment

by:algabatz
ID: 6938113
Sendmail yes, Apache, dunno right off th version.
I'll try to check.

Best,
Al
0
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6939013
OK :)

it's ready
It folows the scheme I gave you:
##########################################################
Give the pass (give.cgi):
1. Generate encoded password
2.1 Send it to the users email
2.2 Save it to local file

Users login (login.cgi):
1. Check if the password match to any of the passwords in the local file
If no :
2. deny access
If so :
2. read the pdf and print it to the user
3. delete his password from the local file
##########################################################



1st script - give the pass :
##########################################################
#!/usr/bin/perl
# give.cgi
use strict;
use warnings;
use Fcntl qw(:flock);

# Initialize variables
my $recipient = 'so@email.com';
my $pass_file=".passwords";
my $sendmail = '/usr/bin/sendmail';
my $pass;



# Generate random password
$pass = crypt localtime, join "", (0..9, 'A'..'Z', 'a'..'z')[rand 62, rand 62];
$pass=~s/\W/_/g;


# Save the pass to the pass file
open FILE, ">>$pass_file" or die "can't open pass file \n $!\n";
flock FILE, LOCK_EX;
print  FILE $pass, "\n";
flock FILE, LOCK_UN;  
close FILE;


# Send it to the user's email
open (SENDMAIL, "| $sendmail -t -n") or die "can't open $sendmail !\n $!";
#*SENDMAIL=STDOUT; #for test purposes (prints the mail  to STDOUT instead sending it)

# Configure these to match your info
print SENDMAIL <<End_of_Mail;
From: your name here
To: $recipient
Reply-To: your_email\@email.com
Subject: your password bla bla  bla

Your password is $pass. blablabla bla bla bla
Please note that it is valid only for one download ...
bla bla bla ...
End_of_Mail

# End -->
##########################################################



Exapmle login.html
##########################################################
<HTML>
<HEAD>
<TITLE>Login</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF" text="#000000">
enter your password:
<FORM name="form1" method="post" action="http://mydomain.com/cgi-bin/login.cgi/file.zip">
  <INPUT type="password" name="user_pass">
  <INPUT type="submit" name="Submit" value="Submit">
</FORM>
</BODY>
</HTML>
##########################################################



the 2d perl script - login.cgi:
##########################################################
#!/usr/bin/perl
# login.cgi
use strict;
use warnings;
use Fcntl qw(:flock);
use CGI;

my $bad_page='htpp://yourdomain.com/badlogin.htm';
my $protected_file='thefile.zip';
my $pass_file='.passwords';
my @passwords;

# Let say the user enters the password in form field called "user_pass"
my $q=new CGI;
my $user_pass = $q->param("user_pass");



# Get the passwords from the file:
open DATFILE, "<$pass_file" or die "can't open $pass_file \n $!\n";
@passwords=<DATFILE>;
close DATFILE;
chomp @passwords;


# Check if the entered pass is OK (exist in the file):
if (grep {$_ eq $user_pass} @passwords) {
    return_protected_file(); # give  file to the user
    update_passfile(); #remove it from the pass file
} else {
    print $q->redirect($bad_page); # redirect to bad pass page
}


sub update_passfile {
    # Open the file and print all @paswords but without the used one
    open FILE, ">$pass_file" or die "can't open pass file \n $!\n";
    flock FILE, LOCK_EX;
    local $,="\n";
    print FILE grep {$_ ne $user_pass} @passwords;
    flock FILE, LOCK_UN;
    close FILE;
}

sub return_protected_file {
   # Read the file and print it to user:
    undef $/;
    open FILE, "<$protected_file" or die "can't open $protected_file! \n$!\n";
    binmode FILE;

    print "Content-Type: application/zip\n\n";

    binmode STDOUT;
    print  STDOUT <FILE>;
}


# End -->
0
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6939021
OK now it's your turn - configure it to match your setings, upload, chmode 755 and that's it ! :))

:)))
0
 
LVL 1

Author Comment

by:algabatz
ID: 6939105
Excellent! I'll give it a run and get back to you.

/Al
0
 
LVL 84

Expert Comment

by:ozo
ID: 6939544
Careful with that, if two users try to run that program at the same time, it can truncate $pass_file
I'd suggest instead of having $pass_file contain $user_pass, you use $user_pass as a file name.
0
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6939765
Ozo, the file has exclusive lock
it will look ugly to have 200+ empty textfiles just for that app :)
0
 
LVL 84

Expert Comment

by:ozo
ID: 6940554
Your exclusive lock is applied after the file has already been truncated.
0
 
LVL 3

Expert Comment

by:Tsvetomir
ID: 6940711
Yes! but the info is already in the script and is imediately writen !
You know that that's the idea it has to be like that.

All info needed is already in array @passwords then we open the pass file , "truncate" the old thata (cos' it old!) and print the new one ! then save the file with the updated data ! Where is the problem !? - that's the idea !  


I'm sure that as may be the most advanced here you perfectly understand that ! :)...  are you joking or sth :)???
0
 
LVL 84

Expert Comment

by:ozo
ID: 6940814
In between the truncation and the write, another program can do a read of the empty file,
0
 
LVL 3

Accepted Solution

by:
Tsvetomir earned 300 total points
ID: 6940852
Are you talking about the possibility the 2d user to read the file after it's truncated - to remember  the empty list and write it in the file when the lock is released ????
(this means to accees it when the execution of the sript is between lines  open FILE... and   flock FILE ... !!!)


The chance for this is smaller then wining from the lotery ! :)

but ... as usual:

Yes...  Ozo, I agree with you.  This is realy the better way.
(just may be not the easyest ...)

OK here is the new  script (I also fixed a litle bug that I found in the previous) :



##########################################################
#!/usr/bin/perl
# login.cgi
use strict;
use warnings;
use Fcntl qw(:flock);
use CGI;

my $bad_page='htpp://yourdomain.com/badlogin.htm';
my $protected_file='thefile.zip';
my $pass_file='.passwords';
my @passwords;

# Let say the user enters the password in form field called "user_pass"
my $q=new CGI;
my $user_pass = $q->param("user_pass");



# Get the passwords from the file:
# Open it for read/write  access (doesn't flush the current data)
open FILE, "+<$pass_file" or die "can't open pass file \n $!\n";
# Lock it from the very begining !
flock FILE, LOCK_EX;
@passwords=<FILE>;
chomp @passwords;

# Check if the entered pass is OK (exist in the file):
if (grep {$_ eq $user_pass} @passwords) {
    return_protected_file();
    update_passfile();
} else {
    close FILE;
    print $q->redirect($bad_page);
}


sub update_passfile {
    # print the rest passwords - all @paswords but without the used one
    my @rest = grep {$_ ne $user_pass and $_ ne ""} @passwords;
    # Tha main changes here we delete the previous old but data but now the file is already locked!
    seek FILE, 0 , 0;
    truncate FILE, 0;      

    local $,="\n";
    print FILE @rest;
    print FILE "\n" if @rest;  
    flock FILE, LOCK_UN;
    close FILE;
}

sub return_protected_file {
   # Read the file and print it to user:
    undef $/;
    open FILE, "<$protected_file" or die "can't open $protected_file! \n$!\n";
    binmode FILE;

    print "Content-Type: application/zip\n\n";

    binmode STDOUT;
    print  STDOUT <FILE>;
}


# End -->




OK how is that ?
:)
0
 

Expert Comment

by:larsan
ID: 38099210
I haven't done any programming in years but I wanted to revive this script.
Now I can't get anything to work.
Please help me sort out with which file goes where and if there's a html missing?
Do I need to add a document for the generated passwords?
If the "secret" document is called secret.doc should it be in cgi-bin?

/Al
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
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…
Six Sigma Control Plans

705 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