"Fossies" - the Fresh Open Source Software Archive

Member "absence-v2.1/cgi-bin/AbsenceAuthentication.pm.dna.foo" (10 Dec 2013, 9389 Bytes) of package /linux/www/web-absence-2.1.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #---------------------------------------------------------------------
    2 # authentication
    3 # $Id: AbsenceAuthentication.pm 91 2009-07-14 15:58:06Z urban $
    4 #---------------------------------------------------------------------
    5 
    6 package AbsenceAuthentication;
    7 
    8 use FileHandle;
    9 use Fcntl ':flock'; # import LOCK_* constants
   10 use Carp;
   11 use Data::Dumper;
   12 #use CGI qw(:standard -nph);
   13 
   14 $Data::Dumper::Indent = 1;
   15 
   16 my $COOKIE_NAME;
   17 
   18 BEGIN {
   19 	# an instance has been specified
   20 	if (exists($ENV{INSTANCE_NAME})) {
   21         $COOKIE_NAME = "absence-sid-$ENV{INSTANCE_NAME}";
   22     } else {
   23         $COOKIE_NAME = 'absence-sid';
   24     }
   25 }
   26 
   27 use AbsenceConfig;
   28 use AbsenceDB;
   29 use AbsenceLog;
   30 
   31 
   32 use Digest::MD5 qw(md5_base64);
   33 
   34 #---------------------------------------------------------------------
   35 # package globals
   36 #---------------------------------------------------------------------
   37 
   38 my $AUTH_TYPE		= AbsenceConfig::fetch('auth_type');
   39 my $AUTH			= AbsenceConfig::fetch('authentication');
   40 my $SECRET			= AbsenceConfig::fetch('secret');
   41 my $TOP_PAGE		= AbsenceConfig::fetch('top_page');
   42 my $CRED_SRC		= AbsenceConfig::fetch('credential_src');
   43 my $SESSION_FILE	= AbsenceConfig::fetch('session_file');
   44 my $SESSION_TIMEOUT	= AbsenceConfig::fetch('session_timeout');
   45 my $PW_HASH_FORMAT	= AbsenceConfig::fetch('pw_hash_format');
   46 my $COLOR_MAIN		= AbsenceConfig::fetch('wp_main');
   47 my $COLOR_NOPRIV	= AbsenceConfig::fetch('wp_nopriv');
   48 my $JS_RELOAD_CONTROL	= 'function reload_control() { parent.control.location.reload(); }';
   49 
   50 our $SESSION;
   51 
   52 my $DEBUG		= 1;
   53 my $VERSION		= '1.1';
   54 my $AUTH_UID;
   55 
   56 #---------------------------------------------------------------------
   57 # class methods
   58 #---------------------------------------------------------------------
   59 
   60 sub checkAuthentication
   61 {
   62 	my $cgi = shift;
   63 
   64 	$DEBUG && abslog("checkAuthentication()");
   65 
   66 	my $hack = AbsenceConfig::fetch('partial_auth_hack');
   67 	(!$AUTH && !$hack) && return undef;
   68 
   69 	my $sid = $cgi->cookie($COOKIE_NAME);
   70 
   71 	($AUTH && !defined($sid)) && notAuthenticated($cgi);
   72 
   73 	$SESSION = AbsenceDB::getSession($sid, 0);
   74 	$DEBUG && abslog("  SESSION=$SESSION");
   75 
   76 	(!$AUTH && $hack) && return undef;
   77 
   78 	defined($SESSION) || notAuthenticated($cgi);
   79 
   80 	if ($SESSION->param('authed')) {
   81 		return $SESSION->param('uid');
   82 	}
   83 
   84 	my $cookie = $cgi->cookie(
   85 		-name	=> $COOKIE_NAME,
   86 		-value	=> $SESSION->id(),
   87 	);
   88 	notAuthenticated($cgi, $cookie);
   89 }
   90 
   91 sub isAuthed
   92 {
   93 	defined($SESSION) || confess "SESSION undefined";
   94 	return $SESSION->param('authed') ? 1 : 0;
   95 }
   96 
   97 sub session
   98 {
   99 	return $SESSION;
  100 }
  101 
  102 sub authUid
  103 {
  104 	if (@_) {
  105 		$AUTH_UID = shift;
  106 		my $username = AbsenceDB::getUser(id => $AUTH_UID, 'username');
  107 		defined($username) || die "unable to get username for uid=[$AUTH_UID]";
  108 		AbsenceLog::setAuthUser($username);
  109 	} else {
  110 		return $AUTH_UID;
  111 	}
  112 }
  113 
  114 #-----------------------------------------------------------------
  115 # when logout() is called, $SESSION is already defined
  116 #-----------------------------------------------------------------
  117 sub logout
  118 {
  119 	my $q = shift;
  120 
  121 	dbg("logout(), SESSION=[$SESSION]");
  122 
  123 	my $cook = $q->cookie(
  124 		-name		=> $COOKIE_NAME,
  125 		-value		=> $SESSION->id(),
  126 		-expires	=> '-10y',
  127 	);
  128 
  129 	my @header = (-cookie => $cook);
  130 
  131 	my @js_params = (
  132 	);
  133 
  134 	if ($AUTH_TYPE eq 'http') {
  135 		my $lo_path = AbsenceConfig::fetch('js_dir_rel') . '/logout.js' . '?' . time();
  136 		@js_params = (
  137 			-script		=> { -type => 'JAVASCRIPT', -src => $lo_path },
  138 			-onLoad		=> 'parent.control.document.write(""); clearAuthenticationCache(); parent.location.reload();',
  139 		);
  140 	}
  141 	else {
  142 		@js_params = (
  143 			-script		=> $JS_RELOAD_CONTROL,
  144 			-onLoad		=> 'reload_control();',
  145 		);
  146 	}
  147 
  148 	print $q->header(@header),
  149 		$q->start_html(
  150 			-title	=> 'Absence: logged off',
  151 			-BGCOLOR	=> $COLOR_MAIN,
  152 			#-script		=> "top.location = '$TOP_PAGE';",
  153 			@js_params,
  154 		),
  155 		$q->h1({-align => 'center'},"logged off."),
  156 		$q->start_form(
  157 			-action		=> $TOP_PAGE,
  158 			-method		=> 'POST',
  159 			-target		=> '_parent',
  160 		);
  161 	if ($AUTH_TYPE eq 'simple') {
  162 		print '<center>',
  163 			$q->submit(-name => 'go_to_login', -value => 'Login to Absence'),
  164 			'</center>';
  165 	}
  166 	print $q->end_form(), $q->end_html();
  167 
  168 	$SESSION->delete();
  169 	$SESSION->flush();
  170 }
  171 
  172 sub authenticateUser
  173 {
  174 	my $cgi = shift;
  175 
  176 	#-----------------------------------------------------------------
  177 	# first find or create a session
  178 	#-----------------------------------------------------------------
  179 	
  180 	dbg("authenticateUser: AUTH=[$AUTH]");
  181 
  182 	my $sid = $cgi->cookie($COOKIE_NAME);
  183 	$SESSION = AbsenceDB::getSession($sid, 1);
  184 	abslog("authenticateUser: sid=[$sid]");
  185 
  186 	my $cookie = $cgi->cookie(
  187 		-name	=> $COOKIE_NAME,
  188 		-value	=> $SESSION->id(),
  189 	);
  190 
  191 	if (!$AUTH) {
  192 		if (!AbsenceConfig::fetch('partial_auth_hack')) {
  193 			return (undef, $cookie);
  194 		}
  195 		my $action = $cgi->param('action');
  196 		if (!defined($action)) {
  197 			return (undef, $cookie);
  198 		}
  199 		if ($action eq 'Login') {
  200 			if ($cgi->param('password') eq AbsenceConfig::fetch('partial_auth_hack_pw')) {
  201 				$SESSION->param(authed => 1);
  202 				$SESSION->param(uid => 0);
  203 				$SESSION->flush();
  204 				dbg("add session: uid=[$AUTH_UID], user=[$Q::username], addr=[$ENV{REMOTE_ADDR}]");
  205 				reloadTop($cgi, $cookie);
  206 			} else {
  207 				authenticationFailed($cgi, $cookie);
  208 			}
  209 		}
  210 		elsif ($action eq 'partial_auth') {
  211 			authenticationForm($cgi, 'partial', 'Please enter the SuperUser password', $cookie);
  212 		}
  213 		
  214 		return (undef, $cookie);
  215 	}
  216 
  217 	if ($SESSION->param('authed')) {
  218 		abslog("session is authed");
  219 		return $SESSION->param('uid');
  220 	}
  221 
  222 	$SESSION->expire($SESSION_TIMEOUT);
  223 
  224 	if ($AUTH_TYPE eq 'http') {
  225 		if (exists($ENV{REMOTE_USER})) {
  226 			$AUTH_UID = AbsenceDB::getUser(username => $ENV{REMOTE_USER}, 'id');
  227 			if (defined($AUTH_UID)) {
  228 				$SESSION->param(authed => 1);
  229 				$SESSION->param(uid => $AUTH_UID);
  230 				$SESSION->flush();
  231 				#return $AUTH_UID;
  232 				abslog("http authenticated as uid [$AUTH_UID], remote_user=[$ENV{REMOTE_USER}");
  233 				reloadTop($cgi, $cookie);
  234 			}
  235 		}
  236 		notAuthenticated($cgi, $cookie);
  237 	} elsif ($AUTH_TYPE eq 'simple') {
  238 		dbg("auth_type = simple");
  239 		if (length($Q::action) && ($Q::action eq 'Login')) {
  240 			$AUTH_UID = checkPassword($Q::username, $Q::password);
  241 			dbg("checkPassword returned [$AUTH_UID]");
  242 			if ($AUTH_UID) {
  243 				$SESSION->param(authed => 1);
  244 				$SESSION->param(uid => $AUTH_UID);
  245 				$SESSION->flush();
  246 				dbg("add session: uid=[$AUTH_UID], user=[$Q::username], addr=[$ENV{REMOTE_ADDR}]");
  247 				reloadTop($cgi, $cookie);
  248 			} else {
  249 				authenticationFailed($cgi, $cookie);
  250 			}
  251 		} else {
  252 			dbg("last clause");
  253 			authenticationForm($cgi, 'normal', undef, $cookie);
  254 		}
  255 	}
  256 
  257 	exit;
  258 }
  259 
  260 sub reloadTop
  261 {
  262 	my ($q, $cook) = @_;
  263 	print $q->header(
  264 			-cookie	=> $cook,
  265 		),
  266 		$q->start_html(
  267 			-title		=> 'Absence: Authentication OK',
  268 			-BGCOLOR	=> $COLOR_MAIN,
  269 			-script		=> $JS_RELOAD_CONTROL,
  270 			-onLoad		=> "reload_control(); top.location = '$TOP_PAGE';",
  271 		),
  272 		$q->start_form(
  273 			-action		=> $TOP_PAGE,
  274 			-method		=> 'POST',
  275 			-target		=> '_parent',
  276 		),
  277 		$q->submit(action => 'Authentication OK. Click to Continue...'),
  278 		$q->end_form(),
  279 		$q->end_html();
  280 	exit;
  281 }
  282 
  283 #---------------------------------------------------------------------
  284 # looks up the password for a user and checks the stored password
  285 # against the password passed as parameter.  if the passwords match,
  286 # the user-id is returned.  if no match, returns 0
  287 #---------------------------------------------------------------------
  288 sub checkPassword
  289 {
  290 	my ($user, $pass) = @_;
  291 
  292 	$DEBUG && abslog("checkPassword: user=$user, pass=[$pass]");
  293 
  294 	if ($CRED_SRC eq 'absence') {
  295 		#-----------------------------------------------------------
  296 		# simple built-in authentication
  297 		#-----------------------------------------------------------
  298 		my $uref = AbsenceDB::getUser(username => $user);
  299 		dbg("checkPassword: uref contents:\n".Dumper($uref)."\n--end--");
  300 		defined($uref) || return 0;
  301 		my $pw = ($PW_HASH_FORMAT eq 'md5')
  302 			? md5_base64($pass)
  303 			: $pass;
  304 		($pw eq $uref->{password}) && return $uref->{id};
  305 	}
  306 
  307 	return 0;
  308 }
  309 
  310 sub authenticationForm
  311 {
  312 	my ($q, $type, $msg, $cookie) = @_;
  313 
  314 	print $q->header(-cookie => $cookie),
  315 		$q->start_html(
  316 			-title		=> 'Absence Authentication',
  317 			-BGCOLOR	=> $COLOR_MAIN,
  318 		);
  319 	if ($msg) { print "<H2>$msg</H2>\n<P>\n"; }
  320 	print "<H2>Please log in</H2>\n",
  321 		$q->start_form(-method => 'GET'),
  322 		'<TABLE>';
  323 	if ($type eq 'normal') {
  324 		print '<TR><TH ALIGN="right">USER:</TH><TD>',
  325 		$q->textfield(
  326 			-name		=> 'username',
  327 			-size		=> 16,
  328 			-maxlength	=> 16,
  329 		),
  330 		qq[</TD></TR>\n];
  331 	}
  332 	print qq[<TR><TH ALIGN="right">PASSWORD:</TH><TD>],
  333 		$q->password_field(
  334 			-name		=> 'password',
  335 			-size		=> 16,
  336 			-maxlength	=> 16,
  337 		),
  338 		"</TD></TR></TABLE><P>",
  339 		$q->submit(action => 'Login'),
  340 		$q->end_form(),
  341 		$q->end_html();
  342 }
  343 
  344 sub authenticationFailed
  345 {
  346 	my ($q, $cookie) = @_;
  347 
  348 	print $q->header(
  349 				-expires => 'now',
  350 				-cookie	=> $cookie,
  351 			),
  352 		$q->start_html(
  353 			-BGCOLOR	=> $COLOR_NOPRIV,
  354 			-title		=> 'Absence authentication failed',
  355 		),
  356 		$q->h1('Authentication Failed'),
  357 		$q->end_html;
  358 }
  359 
  360 sub notAuthenticated
  361 {
  362 	my ($q, $cookie) = @_;
  363 
  364 	my @cookie = defined($cookie) ? (-cookie => $cookie) : ();
  365 
  366 	print $q->header(
  367 			-expires	=> 'now',
  368 			@cookie,
  369 		),
  370 		$q->start_html(
  371 			-title		=> 'Absence: not authenticated',
  372 			-BGCOLOR	=> $COLOR_MAIN,
  373 		),
  374 		$q->h1('Not Authenticated'),
  375 		$q->end_html;
  376 	exit;
  377 }
  378 
  379 sub dbg
  380 {
  381 	my $msg = shift;
  382 	$DEBUG || return;
  383 	abslog("auth: $msg");
  384 }
  385 
  386 1;