#!/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 script my $timeout = "20"; # seconds before logout 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='$vname' AND nname='$nname' ~; $sth=$dbh->prepare($dbquery); $sth->execute; $sth->finish; } sub putstate { $dbquery = qq~ UPDATE users SET state='$currentstate' WHERE vname='$vname' AND nname='$nname' ~; $sth=$dbh->prepare($dbquery); $sth->execute; $sth->finish; } sub login { print <Loginprompt:
login-name:
password:

EOF } sub html_end { if ($vname) { print <

Hallo $vname $nname

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)|| die "Couldn't connect to db $dbname at $dbhost $DBI::errstr"; # safe control data $short=$q->param('short'); # used to identify user all the 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 connection coming from the database $vname=$q->param('vname'); # data to present all the time after login and to keep contact(!) $nname=$q->param('nname'); # data to present all the time 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 form print $q->header(); print < User-Tracking

User-Tracking

EOF if (not $vname) { login; html_end; } # this is, where the keycode is compared to enshure it is the right user 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!!!
"; print "...or the server has a current problem.
"; print "Anyway, report this to the webmaster.
"; 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'