Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Secure access to page and writing to file 1

Status
Not open for further replies.

theniteowl

Programmer
May 24, 2005
1,975
US
Hi All,
I have a dynamic navigation menu that displays sub options based on which top level option is currently selected.
The menu options are stored in an array and included into the page.

I want to build a content management page so that specific people can visually manage the menu options from a web page and need to find the best way to restrict access to that page.
The site resides on a hosting companies server, the server is Apache and my access is limited only to what I can do directly in the site's folders. The hosting company will not take requests from me as the site is paid for by the local school board and hosts all of the town's school sites.
It is a nightmare trying to get the person who is the official contact to understand and place any requests so I am better off doing whatever I can at the folder level.

Is there a good way to handle this directly in PHP or should I be looking at an Apache solution with HTACCESS files or something similar? I am limited on experience with PHP and Apache both and so am unfamiliar with what is available in those environments.


At my age I still learn something new every day, but I forget two others.
 
php is easy enough. i've posted an access control mechanism using only text files here before. i've also posted a version that doesn't need write access to the server but can just store user names and passwords in itself or in a database.

here is a variant that has the uname and pwd incorporated into the document itself (in the validLogon function).

to use it just require_once("scriptname.php") at the top of each page you wish to protect.

it's not perfect by any means but it should be enough to set you on the right track.

Code:
<?php 
if (session_id() == "") session_start();

define ("TIMEOUT", 10); //set this to the number of minutes
//use this script by just including the page at the top of every real page
if (!loggedon()):  
	login();  
else:
	//do nothing
endif;

function loggedon() {
	//this tests the current status
	if (isset ($_SESSION['dl']['loggedon'])):
		if (login_expired()):
			$GLOBALS['msg'] = "Login expired";
			return false;
		else:
			$_SESSION['dl']['lastaccess'] = strtotime("now");
			return true;
		endif;
	else:
		$GLOBALS['msg'] = "You must log on to access this site";
		return false;
	endif;
}
function login_expired() {
	if (isset($_SESSION['dl']['lastaccess'])):
		if ( ($_SESSION['dl']['lastaccess'] + (TIMEOUT * 60 * 60) ) < strtotime("now") ):
			return true;
		else:
			return false;
		endif;
	else:
		return true;
	endif;
}

function logout($msg=NULL)
{
	$_SESSION['dl']['loggedon'] = $_SESSION['dl']['username']=$_SESSION['dl']['lastaccess'] = "";
	
	/*
	if (isset($_COOKIE[session_name()])):
		setcookie(session_name(), '', time()-42000, '/');
	endif;
	
	session_destroy();*/
	if (!empty($msg)) $GLOBALS['msg'] = $msg;
	display_login();
	exit;
}
//master script
function login()
{
	if (!isset ($_POST['submit'])):
		logout("You must log on to access this site");
	endif;
	
	switch ($_POST['submit']):
		case "Login":
			if (!test_fresh_login()):
				logout("You cannot use the back or refresh button to login");
			endif;
			
			if (!validlogon()):
				logout("Either username or password is incorrect");
			else:
				$_SESSION['dl']['username'] = $_POST[$_SESSION['dl']['uname']];
				$_SESSION['dl']['loggedon'] = true;
				$_SESSION['dl']['lastaccess'] = strtotime("now");
				unset ($_POST);
				updatelog("", "logged in");
			endif;
		break;
		default:
			logout("You must log on to access this site");
	endswitch;
}

function test_fresh_login()
{
	if (isset($_SESSION['dl']['uniqid'])):
		if (isset($_POST['uniqid'])):
			if ($_SESSION['dl']['uniqid'] === $_POST['uniqid']):
				unset ($_SESSION['dl']['uniqid']);
				return true;
			else:
				return false;
			endif;
		else:
			return false;
		endif;
	else:
		return false;
	endif;
}

function validlogon()
{
	if (!isset ($_POST[$_SESSION['dl']['uname']]) || !isset ($_POST['pwd'])):
		return false;
	endif;
	$valids = array (
				"username"=>"password"
				); //include list of valid username/passwords here
	if (
			(isset($valids[$_POST[ $_SESSION['dl']['uname'] ] ]))
			 && 
			($valids[$_POST[$_SESSION['dl']['uname'] ] ] == $_POST['pwd'])):
		return true;
	else:
		return false;
	endif;
}
function display_login() {
$_SESSION['dl']['uniqid'] = uniqid("tmdl_");
$_SESSION['dl']['uname'] = uniqid("uname_");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head>
<title>Download Manager - Logon</title>
<link rel="stylesheet" href="styles/styles.css"  />
</head>
<div id="loginform">
<div id="top">Login Here</div>
<form action="<?=$_SERVER['PHP_SELF']?>" method="post">
<input type="hidden" name="uniqid" value="<?=$_SESSION['dl']['uniqid'] ?>" />
<div class="spacer">&nbsp;</div>
<div class="row">
	<span class="label">Username:</span>
	<span class="field"><input type="text" name="<?=$_SESSION['dl']['uname']?>"  /></span>
</div>
<div class="row">
	<span class="label">Password:</span>
	<span class="field"><input type="password" name="pwd"  />
<input type="submit" name="submit" value="Login" /></span>
</div>
</form>
<? if (!empty($GLOBALS['msg'])) echo "<span class=\"loginmessage\">{$GLOBALS['msg']}</span>"; ?>
</div> <!-- end login form -->
<?
exit;
}
?>
 
That sounds exactly like what I am looking for.
Is the file relatively secure so that prying eyes cannot get to the script code and see the id/password info?

This is a school web site and you know how kids like to play.
I know that in the computer class the kids all make their own web site and I am not sure if the teacher posts all the student page files to the server or if they gave out the FTP id/password to the kids which I really hope they did not.

I think I remember seeing something about controlling folder access with files on the server so that I could change a specific sub-folders view rights but I have to look into it more.
I get working on the project for a while then get pulled away for months at a time and forget most of what I had learned. :)

Thanks.

At my age I still learn something new every day, but I forget two others.
 
so long as users don't have ftp access to the directory that the login file is in, and the webserver is properly configured, then it is not bad.

but having passwords in clear text is never very secure. for example anyone with access to php on your server could write a script that grabs the code and displays it.

better would be to store the user=>password combo with an md5 hash of the password and then change this line:
Code:
    if (
            (isset($valids[$_POST[ $_SESSION['dl']['uname'] ] ]))
             &&
            ($valids[$_POST[$_SESSION['dl']['uname'] ] ] == $_POST['pwd'])):
to
Code:
    if (
            (isset($valids[$_POST[ $_SESSION['dl']['uname'] ] ]))
             &&
            ($valids[$_POST[$_SESSION['dl']['uname'] ] ] == md5($_POST['pwd']))):

if you have not got many admin users you can generate the md5 hash with a simple script:

Code:
<form action="<?=$_SERVER['PHP_SELF']?> method="post">
<input type="text" name="plaintext" />
<input type="submit" name="submit" value="get Hash"/>
</form>
if(isset($_POST['plaintext'])):
  echo "<br/><hr/><br/>the md5 hash of " . $_POST['plaintext'] . " is ".md5($_POST['plaintext']);
endif;
 
That sounds good. I may only setup one id/password for this function anyway.

Eventually I can set it up to do verification from a database but that's a whole new area to learn.
I did get a database setup a while back and tested the connection but have to determine how to secure the script doing the lookup so it's id/password is not revealed. Just not something I have spent time looking into yet.


At my age I still learn something new every day, but I forget two others.
 
the way i typically do this stuff is by db. and i store the login script and the db connection parameters in folders that are either outside the root or which have htaccess files in them which DENY FROM ALL. i.e they are only available to the php script.

similarly if i am using a site where db's are not available then i put a text file of user->pwd combos in the protected directory.

but in the absence of ssl the user password can still be read by a packet analysis tool in clear text.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top