"Fossies" - the Fresh Open Source Software Archive

Member "absence-v2.1/cgi-bin/AbsenceAuthentication.pm.dna" (10 Dec 2013, 9344 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 		'<center>',
  162 		$q->submit(-name => 'go_to_login', -value => 'Login to Absence'),
  163 		'</center>',
  164 		$q->end_form(),
  165 		$q->end_html();
  166 
  167 	$SESSION->delete();
  168 	$SESSION->flush();
  169 }
  170 
  171 sub authenticateUser
  172 {
  173 	my $cgi = shift;
  174 
  175 	#-----------------------------------------------------------------
  176 	# first find or create a session
  177 	#-----------------------------------------------------------------
  178 	
  179 	dbg("authenticateUser: AUTH=[$AUTH]");
  180 
  181 	my $sid = $cgi->cookie($COOKIE_NAME);
  182 	$SESSION = AbsenceDB::getSession($sid, 1);
  183 	abslog("authenticateUser: sid=[$sid]");
  184 
  185 	my $cookie = $cgi->cookie(
  186 		-name	=> $COOKIE_NAME,
  187 		-value	=> $SESSION->id(),
  188 	);
  189 
  190 	if (!$AUTH) {
  191 		if (!AbsenceConfig::fetch('partial_auth_hack')) {
  192 			return (undef, $cookie);
  193 		}
  194 		my $action = $cgi->param('action');
  195 		if (!defined($action)) {
  196 			return (undef, $cookie);
  197 		}
  198 		if ($action eq 'Login') {
  199 			if ($cgi->param('password') eq AbsenceConfig::fetch('partial_auth_hack_pw')) {
  200 				$SESSION->param(authed => 1);
  201 				$SESSION->param(uid => 0);
  202 				$SESSION->flush();
  203 				dbg("add session: uid=[$AUTH_UID], user=[$Q::username], addr=[$ENV{REMOTE_ADDR}]");
  204 				reloadTop($cgi, $cookie);
  205 			} else {
  206 				authenticationFailed($cgi, $cookie);
  207 			}
  208 		}
  209 		elsif ($action eq 'partial_auth') {
  210 			authenticationForm($cgi, 'partial', 'Please enter the SuperUser password', $cookie);
  211 		}
  212 		
  213 		return (undef, $cookie);
  214 	}
  215 
  216 	if ($SESSION->param('authed')) {
  217 		abslog("session is authed");
  218 		return $SESSION->param('uid');
  219 	}
  220 
  221 	$SESSION->expire($SESSION_TIMEOUT);
  222 
  223 	if ($AUTH_TYPE eq 'http') {
  224 		if (exists($ENV{REMOTE_USER})) {
  225 			$AUTH_UID = AbsenceDB::getUser(username => $ENV{REMOTE_USER}, 'id');
  226 			if (defined($AUTH_UID)) {
  227 				$SESSION->param(authed => 1);
  228 				$SESSION->param(uid => $AUTH_UID);
  229 				$SESSION->flush();
  230 				#return $AUTH_UID;
  231 				abslog("http authenticated as uid [$AUTH_UID], remote_user=[$ENV{REMOTE_USER}");
  232 				reloadTop($cgi, $cookie);
  233 			}
  234 		}
  235 		notAuthenticated($cgi, $cookie);
  236 	} elsif ($AUTH_TYPE eq 'simple') {
  237 		dbg("auth_type = simple");
  238 		if (length($Q::action) && ($Q::action eq 'Login')) {
  239 			$AUTH_UID = checkPassword($Q::username, $Q::password);
  240 			dbg("checkPassword returned [$AUTH_UID]");
  241 			if ($AUTH_UID) {
  242 				$SESSION->param(authed => 1);
  243 				$SESSION->param(uid => $AUTH_UID);
  244 				$SESSION->flush();
  245 				dbg("add session: uid=[$AUTH_UID], user=[$Q::username], addr=[$ENV{REMOTE_ADDR}]");
  246 				reloadTop($cgi, $cookie);
  247 			} else {
  248 				authenticationFailed($cgi, $cookie);
  249 			}
  250 		} else {
  251 			dbg("last clause");
  252 			authenticationForm($cgi, 'normal', undef, $cookie);
  253 		}
  254 	}
  255 
  256 	exit;
  257 }
  258 
  259 sub reloadTop
  260 {
  261 	my ($q, $cook) = @_;
  262 	print $q->header(
  263 			-cookie	=> $cook,
  264 		),
  265 		$q->start_html(
  266 			-title		=> 'Absence: Authentication OK',
  267 			-BGCOLOR	=> $COLOR_MAIN,
  268 			-script		=> $JS_RELOAD_CONTROL,
  269 			-onLoad		=> "reload_control(); top.location = '$TOP_PAGE';",
  270 		),
  271 		$q->start_form(
  272 			-action		=> $TOP_PAGE,
  273 			-method		=> 'POST',
  274 			-target		=> '_parent',
  275 		),
  276 		$q->submit(action => 'Authentication OK. Click to Continue...'),
  277 		$q->end_form(),
  278 		$q->end_html();
  279 	exit;
  280 }
  281 
  282 #---------------------------------------------------------------------
  283 # looks up the password for a user and checks the stored password
  284 # against the password passed as parameter.  if the passwords match,
  285 # the user-id is returned.  if no match, returns 0
  286 #---------------------------------------------------------------------
  287 sub checkPassword
  288 {
  289 	my ($user, $pass) = @_;
  290 
  291 	$DEBUG && abslog("checkPassword: user=$user, pass=[$pass]");
  292 
  293 	if ($CRED_SRC eq 'absence') {
  294 		#-----------------------------------------------------------
  295 		# simple built-in authentication
  296 		#-----------------------------------------------------------
  297 		my $uref = AbsenceDB::getUser(username => $user);
  298 		dbg("checkPassword: uref contents:\n".Dumper($uref)."\n--end--");
  299 		defined($uref) || return 0;
  300 		my $pw = ($PW_HASH_FORMAT eq 'md5')
  301 			? md5_base64($pass)
  302 			: $pass;
  303 		($pw eq $uref->{password}) && return $uref->{id};
  304 	}
  305 
  306 	return 0;
  307 }
  308 
  309 sub authenticationForm
  310 {
  311 	my ($q, $type, $msg, $cookie) = @_;
  312 
  313 	print $q->header(-cookie => $cookie),
  314 		$q->start_html(
  315 			-title		=> 'Absence Authentication',
  316 			-BGCOLOR	=> $COLOR_MAIN,
  317 		);
  318 	if ($msg) { print "<H2>$msg</H2>\n<P>\n"; }
  319 	print "<H2>Please log in</H2>\n",
  320 		$q->start_form(-method => 'GET'),
  321 		'<TABLE>';
  322 	if ($type eq 'normal') {
  323 		print '<TR><TH ALIGN="right">USER:</TH><TD>',
  324 		$q->textfield(
  325 			-name		=> 'username',
  326 			-size		=> 16,
  327 			-maxlength	=> 16,
  328 		),
  329 		qq[</TD></TR>\n];
  330 	}
  331 	print qq[<TR><TH ALIGN="right">PASSWORD:</TH><TD>],
  332 		$q->password_field(
  333 			-name		=> 'password',
  334 			-size		=> 16,
  335 			-maxlength	=> 16,
  336 		),
  337 		"</TD></TR></TABLE><P>",
  338 		$q->submit(action => 'Login'),
  339 		$q->end_form(),
  340 		$q->end_html();
  341 }
  342 
  343 sub authenticationFailed
  344 {
  345 	my ($q, $cookie) = @_;
  346 
  347 	print $q->header(
  348 				-expires => 'now',
  349 				-cookie	=> $cookie,
  350 			),
  351 		$q->start_html(
  352 			-BGCOLOR	=> $COLOR_NOPRIV,
  353 			-title		=> 'Absence authentication failed',
  354 		),
  355 		$q->h1('Authentication Failed'),
  356 		$q->end_html;
  357 }
  358 
  359 sub notAuthenticated
  360 {
  361 	my ($q, $cookie) = @_;
  362 
  363 	my @cookie = defined($cookie) ? (-cookie => $cookie) : ();
  364 
  365 	print $q->header(
  366 			-expires	=> 'now',
  367 			@cookie,
  368 		),
  369 		$q->start_html(
  370 			-title		=> 'Absence: not authenticated',
  371 			-BGCOLOR	=> $COLOR_MAIN,
  372 		),
  373 		$q->h1('Not Authenticated'),
  374 		$q->end_html;
  375 	exit;
  376 }
  377 
  378 sub dbg
  379 {
  380 	my $msg = shift;
  381 	$DEBUG || return;
  382 	abslog("auth: $msg");
  383 }
  384 
  385 1;