PHP authentication through .htaccess - problem with if/else?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
MarcX
Forum Newbie
Posts: 5
Joined: Sat Mar 27, 2004 7:47 am

PHP authentication through .htaccess - problem with if/else?

Post by MarcX »

Hello everyone,

I'm new here - not very experienced in PHP. I started with
ready php scripts, but as most of them needed meddling
with to suit my site, I've learned to do bits with PHP...

My whole site is password protected, and so far I've been relying
on .htaccess alone. My ISP doesn't give me access to logfiles
(and can't explain why), so I've been forced to use by-pass
methods.

What I want to do is let users in through PHP, i.e. use PHP
as "entrance" to pass on them to the .htaccess-protected
site. Thus php is only used in a single log-in file, which remains
invisible to users - it looks like the usual Apache log-in.
The function of this log-in.php is to log log-ins, good
logins in a "good-login.txt" above wwwroot, bad logins in
a "bad-login.txt", also placed above wwwroot for increased
security.

It also redirects users after login, if succesful to my front page,
if not, to an error page.

I don't know if it adds security, but the log-in.php file doesn't
include the log commands in itself; instead, the php files that take
care of logging are also placed above wwwroot and used through
include command in log-in.php.

So far so good.

I found the raw code for my log-in.php at
http://www.zend.com/zend/tut/authentication.php
It didn't work on my site, however (most ready
scripts don't), so I tried to change it to suit my needs.

It's nearly doing everything I want it to do - but not everything.
What it does is:

- Checks username & password correctly
- If correct username & password, logs them and redirects to front page
- Logs good logins correctly,

What doesn't work are all the bad log-ins...

For one thing, you will notice the last if statement will suppose
$auth is true and then treat it as a bad login! But if I
change this to !$auth, nothing works. Doesn't make sense to me...
:cry:

Also it does not redirect bad logins to the errorpage. Just in
case you're wondering, the error folder is not password protected,
so it can be accessed even when log-in fails, and it contains
everything used in the error file (css, images etc.).

Here's what I want it to do:

1. User wants to access the log-in.php
2. Check if $_SERVER['PHP_AUTH_USER'] and $_SERVER
['PHP_AUTH_PW'] have a value.
3. If not, launch pop-up box to get the information
4. When username and password are received, check them
against .htpasswd.
5. If good, log username, password and time to good-logins.txt
5.5 Redirect to front page
6. If bad, log attempted username, password and time to bad.txt
6.5 redirect to error page.

In case you're wondering why I use $_SERVER['PHP_AUTH_USER']
and $_SERVER ['PHP_AUTH_PW'] instead of the common php
$PHP_AUTH_USER and $PHP_AUTH_PW, the answer is that the
latter won't work. What's more, I have to use them through
the $login and $pass vars, otherwise they won't work either. I think
this has something to do with how php is installed on my host
server. I know this kind of authentication won't work if php
is installed as CGI module (or whatever), it has to be an
Apache module (which it is). But it seems I've got some kind
of Apache php safe mode turned on (by ISP), which obviously makes
things more complicated. My ISP isn't too heplful either...
Running PHP 4.3.0...

I'd be extremely grateful for help! Been trying to make it work
for days now, done hundreds of searches &tc. It can't be very¨
hard, it nearly works...

Here's the code.

Code: Select all

<?php
<?php

$auth = false; // Assume user is not logged in

$login = $_SERVER['PHP_AUTH_USER'];	
// Assign $login the .htaccess value for username, doesn't work directly with $_SERVER['PHP_AUTH_USER'] - strange
$pass = $_SERVER['PHP_AUTH_PW'];        // Assign $pass the .htaccess value for password

// Check if user already logged in
// If not, launch pop-up box

if (!isset($username) or !isset($password)) {

    header('WWW-Authenticate: Basic realm="Username and password"');
    header('HTTP/1.0 401 Unauthorized');
    exit;
}

// After receiving username and password through pop-up box above,
// check against .htpasswd
// Will check even if logged in before, must do something at that when done with basics, though no sessions...

else {

    $filename = '/home/path.to/.htpasswd'; 
    $fp = fopen( $filename, 'rb' ); 
    $file_contents = fread( $fp, filesize( $filename ) ); 
    fclose( $fp ); 

    // Place the individual lines from the file contents into an array. 

    $lines = explode ( "\n", $file_contents ); 

    // Split each of the lines into a username and a password pair 
    // and attempt to match them to $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW']. 

    foreach ( $lines as $line ) { 

        list( $username, $password ) = explode( ':', $line ); 

        if ( $username == $login ) { 

            // Get the salt from $password. It is always the first 
            // two characters of a DES-encrypted string. 

            $salt = substr( $password , 0 , 2 ); 

            // Encrypt $_SERVER['PHP_AUTH_PW'] based on $salt 

            $enc_pw = crypt( $pass, $salt ); 

            if ( $password == "$enc_pw" ) { 

                // A match is found, meaning the user is authenticated. 
                // Stop the search. 

		$auth = true;
		break; 
		}
	}
}
}

// Check-up done, if successful -> $auth = true;
// if not -> $auth = false.

// If true, log through hidden .php and redirect to front page;
// if false, log through hidden .php and redirect to error page.

if ($auth) {

	include "/home/path.to/errorlog.php";
	header( 'Location: http://www.mysite.com/error/error.html');
}

else {
	include "/home/path.to/successlog.php";
	header( 'Location: http://www.mysite.com/firstpage.html');
}

?>
?>
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Code: Select all

if ($auth) { 

   include "/home/path.to/errorlog.php"; 
   header( 'Location: http://www.mysite.com/error/error.html'); 
}
So you mean, if false display error. But what are you comaring it to. You will always get the else statement this way. You need to do something like

Code: Select all

if (strpos($_SERVER['PHP_AUTH_USER'], $auth) !== flase) {
   
   include "/home/path.to/errorlog.php"; 
   header( 'Location: http://www.mysite.com/error/error.html'); 

}
I'm no expert on php so that code probably wont mean anything but the point i'm trying to make is that
if ($auth)
Doesn't mean anything on its own. You need to compare it with something. You have to work out what you're supposed to be comparing it with and how to do it though cos I don't really know any more than that.
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

Yes it does.

Code: Select all

if($auth){
means "If $auth == TRUE" except with less coding.
same as

Code: Select all

if(!$auth){
means "If $auth == FALSE" (or !=TRUE).
MarcX
Forum Newbie
Posts: 5
Joined: Sat Mar 27, 2004 7:47 am

I think I'm getting there...

Post by MarcX »

Well, it seems my problem is getting $auth to TRUE.
It lets users in if they give correct $pass and $login
IF $auth = false. Of course, they will also have to
provide a correct $pass and $login, otherwise
.htaccess won't let them in (ALL of the site, except
log-in.php, is protected by .htaccess).

But I can't seem to get $auth to TRUE...
If I require $auth = true to let users in,
they won't get in (well, in fact, they'll get to
my error page and will be able to enter the
site if they type in the URl for my front page
or any other page in the address field,
if they gave correct $pass and $login, again
because .htaccess lets them in...)

And, obviously, that must be because $auth
never gets to true. Why? Username and password
are detected correctly. But $auth never gets true,
is that because $auth = false is in the very
beginning of the code? Should it be someplace
else?

Any ideas????
MarcX
Forum Newbie
Posts: 5
Joined: Sat Mar 27, 2004 7:47 am

BTW...

Post by MarcX »

Of course, you will have noticed I have wrong vars in the
first if (!isset) - it's a typo, I've correct vars ($ogin & $pass)
in the real code, otherwise nothing would work.

Still can't understand why $auth doesn't want to get
true...
MarcX
Forum Newbie
Posts: 5
Joined: Sat Mar 27, 2004 7:47 am

Solved!

Post by MarcX »

Well, I never... all I had to do was to remove the double quotes
from "$enc_pw"... I did think it was weird not to have
them in $login but since the author of the code used them,
I thought it wouldn't make a difference... Well it did!

Haven't had many responses, but I thought I'd tell how
I found the solution for reference in similar cases.

Happy PHP:ing!
MarcX
Forum Newbie
Posts: 5
Joined: Sat Mar 27, 2004 7:47 am

Even more complicated than so!

Post by MarcX »

Last follow-up...

Forget all I wrote above. The problem was $auth not
getting TRUE. And guess why? Because the Apache server
I'm using clearly is set to use MD5 encryption, not DES,
which the code was fit for (2-character salt). So my PHP
code was creating 12-character salt MD5 passwords and
trying to compare them against 2-character salt DES-passwords!
(my .htpasswd was encrypted with DES).

8O No surprise it didn't work...

So I simply MD5-encrypted my passwords (better
protection anyway) using a simple php file, changed
my .htpasswd and voilà!
Post Reply