Hi snippets watcher!
This is a simple structure of a login script and the very
first attempt to do so.
I'd appreciate proposals of improvements to the very basic
idea itself, and secondly of the code, too.
I know that CGI.pm is capable to substitute some of my
here-documents, but because there are not all function
implemented html offers, so I prefer them.
Also note, that this only the basic form of a standalone
script to serve further functions following the login-procedure
which don't show up here. On the other hand I am pretty shure,
that this is a good snippet to show the way of how to do it,
presumed, that I have not run into a dead-end.

enjoy reading the code!

UPDATE 20010913: I enclosed hijacking detection at the very
end of the script.
--
there are no silly questions
killerhippy
Pipe this to a file named "login"
#!/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;

Pipe this to a file named "usertrack.sql"
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'

In reply to usertracking by khippy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.