#!/usr/bin/perl -wT ############################################################ # login - a perlscript to make a secure login to any site # # # # Requirements: # # - a server running a cgi-capable webserver # # with perl being installed # # and mysql (tested with apache & linux) # # - perlmodules DBI, DBD::mysql, CGI # # - any use for this :) # # # # This script is able to run at any place if you know how # # to configure your webserver. It runs from the cgi-bin- # # directory without any further configuration. # # If its name conflicts with your files, simply rename it # # and change the url at the "user config" a few lines down # # # # Prerequisite is to execute the sql-statements from the # # usertrack.sql file like this (as root): # # mysqladmin create usertrack # # mysql usertrack < usertrack.sql # # Note that you have to modify this file for your own # # needs (including dbuser und dbpassword). # # # # The special features of this script are: # # -no use of cookies # # -no hints about existing users from its reaction. # # -only one handshake of password transfer. # # -each request creates a new key in konjunction with the # # username. # # -automated logout by reloading after a specified timeout.# # # ############################################################ use strict; use DBI; DBI->trace(1); use CGI; use CGI::Carp qw(fatalsToBrowser); ###################### # user config starts # my $reloadpage = "http://localhost/cgi-bin/login"; # url of this scrip +t my $timeout = "20"; # seconds before lo +gout my $dbhost="localhost"; my $dbuser="gunny"; my $dbpass="RaZoRbLaCk"; my $dbname="usertrack"; # user config ends # ###################### my $q = new CGI; my $dbquery; my $sth; my $dbh; my @row; my $dbpassword; my $short; my $vname; my $nname; my $password; my $currentstate; my $state; my $time = time() . rand 65535; sub getrow { $dbquery = qq~ SELECT * FROM users WHERE short='$short' ~; $sth=$dbh->prepare($dbquery); $sth->execute; @row = $sth->fetchrow_array; $sth->finish; } sub putpassword { $dbquery = qq~ UPDATE users SET password='$password' WHERE vname='$vna +me' AND nname='$nname' ~; $sth=$dbh->prepare($dbquery); $sth->execute; $sth->finish; } sub putstate { $dbquery = qq~ UPDATE users SET state='$currentstate' WHERE vname='$vn +ame' AND nname='$nname' ~; $sth=$dbh->prepare($dbquery); $sth->execute; $sth->finish; } sub login { print <<EOF; <h4 align=center>Loginprompt:</h4> <table align=center border=1 cellpadding=8 bgcolor=#CCFFFF> <form method="post" enctype="application/x-www-form-urlencoded"> <input type=hidden name="currentstate" value=$time> <tr><td align=center>login-name:<br><input type=text name='short'></td +></tr> <tr><td align=center>password:<br><input type=password name='password' +></td></tr> <tr><td align=center><input type=submit name="login"> <input type=reset value="Reset"></td></tr> </form></table></center><hr> EOF } sub html_end { if ($vname) { print <<EOF; <h4 align=center></h4> <table align=center border=1 cellpadding=8 bgcolor=#CCFFFF> <form method="post" enctype="application/x-www-form-urlencoded"> </table> <input type=submit> <input type=reset> <input type=hidden name=vname value=$vname> <input type=hidden name=nname value=$nname> <input type=hidden name=currentstate value=$currentstate> <input type=hidden name=state value=$state> <input type=hidden name=short value=$short> </form></center><hr> <center>Hallo $vname $nname</center><br> EOF } print $q->end_html; $dbh->disconnect; exit; } ###################################################################### +########## # main + # ###################################################################### +########## # start database connectin and die if it fails $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost", $dbuser, $dbpass)|| d +ie "Couldn't connect to db $dbname at $dbhost $DBI::errstr"; # safe control data $short=$q->param('short'); # used to identify user all t +he time after login $password=$q->param('password'); # only used at loginprocedure $currentstate=$q->param('currentstate'); # new state if this script is + invoked, created from the script $state=$q->param('state'); # old state to verify connect +ion coming from the database $vname=$q->param('vname'); # data to present all the tim +e after login and to keep contact(!) $nname=$q->param('nname'); # data to present all the tim +e after login if (# user has given login-name ($short) and # was not logged in before (not $state) ) { # fetch user's data getrow; if (@row) { (undef,undef,$vname,$nname,$dbpassword,undef)=@row; if (# no password was given (not $password) or # password given does not match password at table (not ($dbpassword eq $password)) ) { # erase all data to disable control $q->delete_all(); undef @row; undef $vname; undef $nname; undef $state; undef $currentstate; } } putstate; getrow; (undef,undef,undef,undef,undef,$state)=@row; } # start the html-code # the java-script is not nescessary but focusses the cursor to the for +m print $q->header(); print <<EOF; <html> <head> <title>User-Tracking</title> <meta http-equiv="refresh" content="$timeout; URL=$reloadpage"> <SCRIPT LANGUAGE="JavaScript"><!-- function setFocus() { document.forms[0].elements[1].focus(); } //--></SCRIPT> </head> <body onLoad="setTimeout('setFocus()',1)"> </head> <h1>User-Tracking</h1> EOF if (not $vname) { login; html_end; } # this is, where the keycode is compared to enshure it is the right us +er requesting this getrow; (undef,undef,undef,undef,undef,$state)=@row; if ($currentstate eq $state) { $currentstate=$time; putstate; getrow; (undef,undef,undef,undef,undef,$state)=@row; } elsif ($vname) { print "Your connections has been hijacked!!!<br>"; print "...or the server has a current problem.<br>"; print "Anyway, report this to the webmaster.<br>"; print $q->end_html; $dbh->disconnect; exit; } # space to put in your own code # stop html-code and exit the script html_end;
DROP TABLE IF EXISTS users; CREATE TABLE users ( ID INT PRIMARY KEY AUTO_INCREMENT, short varchar(10) NOT NULL, vname VARCHAR(50) NOT NULL, nname VARCHAR(50) NOT NULL, password char(16) DEFAULT '' NOT NULL, state char(50) DEFAULT '' NOT NULL, UNIQUE short (short) ); INSERT INTO users VALUES ('','admin','Micky','Mouse','admin',''); INSERT INTO users VALUES ('','user1','Donald','Duck','daisy',''); INSERT INTO users VALUES ('','user2','Dagobert','Duck','gold',''); GRANT SELECT, INSERT, UPDATE, DELETE ON usertrack.* TO gunny@localhost + IDENTIFIED BY 'RaZoRbLaCk'
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: usertracking
by $code or die (Deacon) on Sep 22, 2001 at 06:42 UTC | |
by khippy (Scribe) on Sep 22, 2001 at 23:27 UTC |