HOWTO: Log users into a members area with DA username

FarCry

Verified User
Joined
Jun 6, 2003
Messages
280
Location
Perth, Australia
Problem:
Well, i was faced with a problem of login users into a members area i'm making for spinnahost. We didn't want users to have to register for the members area, as that would put them off using it, we didn't want to skin it into DA, because then we wouldn't know if they had authenticated or not, and we didn't want to use their client exec details.

So, this left us with using their system username and password. Now, we could have authenticated using the shadow file :eek: but thats a little bit of a security problem, so i thought that i would try out using DirectAdmin to log users in :)

solution
First of all, i worked out what exactly DA needed to have posted to it, "username" and "password", once that was working i had to find out what http headers would be returned on a good login, and a bad... these were (in part) "302 Found" and "401 Unauthorized", fairly standard :)

Now i know that, we have to write up (in php) to request that page, then find out what the http header was, then do something depending on if they were successful or not.

This is the code i came up with, its coded so you could add in more control panels if you needed to :eek:

PHP:
<?php 
session_start();
// nothing was posted, so display the login form
if (empty($_REQUEST['a'])) { ?>
<form action="<?php 
// we are posing this data back to this script
echo $_SERVER['PHP_SELF']; 
?>" method="post" name="frmLogin" id="frmLogin">
  <table width="100%" border="0" cellspacing="1" cellpadding="3">
    <tr> 
      <td colspan="2"> <div align="center"><strong>Member Login</strong></div></td>
    </tr>
    <tr> 
      <td>Domain Name:</td>
      <td><input name="domain" type="text" id="domain"></td>
    </tr>
    <tr> 
      <td width="25%">Username:</td>
      <td> <input name="username" type="text" id="username" maxlength="15"></td>
    </tr>
    <tr> 
      <td>Password:</td>
      <td> <input name="password" type="password" id="password" maxlength="15"></td>
    </tr>
    <tr> 
      <td colspan="2"> <div align="center">Logging in may take a few seconds, 
          please don't refresh the page.<br>
          <input name="cp" type="hidden" value="DA">
          <input name="a" type="hidden" id="a" value="login">
          <input type="submit" name="Submit" value="Login">
        </div></td>
    </tr>
  </table>
</form>
<?php } else { 
	// what IP are we loging users into?? important if we have more than 1 server
	$ip = gethostbyname($_REQUEST['domain']);
	
	// for multipule CP's you need to be able to switch them, so here it is
	switch ($_REQUEST['cp']) {
	
		// we want DA, of course
		case 'DA':
			// DA's port is 2222 ([url]http://YOURIP:2222[/url])
			$port = 2222;
			
			// build up the content to post to DirectAdmin
			$content = "username=".$_REQUEST['username']."&password=".$_REQUEST['password'];
			
			// how long is the content we are posting?
			$contentlen = strlen($content);
			
			// the http header we are going to send to direct admin, don't mess with this!
			$request = "POST /CMD_LOGIN HTTP/1.1\r\nHost: $ip:$port\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: $contentlen\r\n\r\n$content\r\n\r\n";
			
			// what header are we getting if successful?
			$yes = "302 Found";
			
			// what header is going to be there if unsuccessful?
			$no = "401 Unauthorized";
			
			// now we are done, break this statement
			break;
	}
	
	// open a connection to DA
	$fp = fsockopen($ip, $port, $errno, $errstr, 30);
	
	if (!$fp) {
		// something went wrong =( we couldn't open up the connection to DA
		echo "ERROR: $errstr ($errno)<br>\n";
	} else {
		$loggedin=false;
		
		// send DA the http header, and the username/password
		fputs ($fp, $request);
		
		// now we can get the response, grab the first line, then loop though the others
		// this is the correct way to do things, rather than getting the data in the loop =)
		$line = fgets ($fp,1024);
		while (!feof($fp)) {
			// cool, the information we sent logged in our user! set our loggedin variable to true,
			// then break out of the loop (because we dont need anything else)
			if (strpos($line, $yes) != false) { $loggedin = true; break 1; }
			
			// damn, the info we sent over failed, lets break the loop because we dont need anything more
			if (strpos($line, $no) != false) { break 1; }
			
			// get the next line (not that we should need too)
			$line = fgets ($fp,1024);
		}
		
		// close the connection to DA
		fclose ($fp);
		
		// do stuff depending on if they are logged in or not
		if ($loggedin) {
			// user is logged in, lets setup some session vars for use in our scripts
			$_SESSION['LOGGEDIN'] = true;
			$_SESSION['USERNAME'] = $_REQUEST['username'];
			$_SESSION['PASSWORD'] = $_REQUEST['password'];
		} else {
			// use did NOT log in successfully (or something went wrong), you might want a message here
			// saying that they did not login correctly
			$_SESSION['LOGGEDIN'] = false;
			echo "login failed";
		}
	}
}
?>
 
Last edited:
ok im kind of new to this (php) what would i do to give the user a customized billing center page based on their account and login info (including like billing information and current overages from the server) i looked all through this above example and found no links to other "member pages" :\ can you please help with this as this is exactly what i was looking for when i came to the board tonight !
 
also you have session variables but you dont start a session :p
 
Has anyone got any idea how I can leave the DA session open so that when the user logs into this members area they can just click a link and go into the DA panel (ie don't close the connection)

Dan
 
Sorry, but this just verifies a users data, it does not in create a session with DA that can be used afterwards.

I will re-write this as there are new API functions available to do just this.
 
Is there any way you can store the username/pass values when they first login so that you can have a link in your own client control panel that says login to da - and posts the values to da login?
 
so the variables allready exist yes?

so all i need is a login button and a form and thats it?
 
razorblue said:
so the variables allready exist yes?

so all i need is a login button and a form and thats it?

view the source of my example :)
 
Hmm - its not working code for both files posted below - please can you sort if out for me :D - sorry but im a bit thick when it comes to coding.

PHP:
<?php 
session_start();
// nothing was posted, so display the login form
if (empty($_REQUEST['a'])) { ?>
<form action="http://www.razorblue.com/members.php" method="post" name="frmLogin" id="frmLogin">
  <table width="100%" border="0" cellspacing="1" cellpadding="3">
    <tr> 
      <td colspan="2"> <div align="center"><strong>Member Login</strong></div></td>
    </tr>
    <tr> 
      <td>Domain Name:</td>
      <td><input name="domain" type="text" id="domain"></td>
    </tr>
    <tr> 
      <td width="25%">Username:</td>
      <td> <input name="username" type="text" id="username" maxlength="15"></td>
    </tr>
    <tr> 
      <td>Password:</td>
      <td> <input name="password" type="password" id="password" maxlength="15"></td>
    </tr>
    <tr> 
      <td colspan="2"> <div align="center">Logging in may take a few seconds, 
          please don't refresh the page.<br>
          <input name="cp" type="hidden" value="DA">
          <input name="a" type="hidden" id="a" value="login">
          <input type="submit" name="Submit" value="Login">
        </div></td>
    </tr>
  </table>
</form>
<?php } else { 
    // what IP are we loging users into?? important if we have more than 1 server
    $ip = gethostbyname($_REQUEST['domain']);
    
    // for multipule CP's you need to be able to switch them, so here it is
    switch ($_REQUEST['cp']) {
    
        // we want DA, of course
        case 'DA':
            // DA's port is 2222 (<a href="http://YOURIP:2222" target="_blank">[url]http://YOURIP:2222[/url]</a>)
            $port = 2222;
            
            // build up the content to post to DirectAdmin
            $content = "username=".$_REQUEST['username']."&password=".$_REQUEST['password'];
            
            // how long is the content we are posting?
            $contentlen = strlen($content);
            
            // the http header we are going to send to direct admin, don't mess with this!
            $request = "POST /CMD_LOGIN HTTP/1.1\r\nHost: $ip:$port\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: $contentlen\r\n\r\n$content\r\n\r\n";
            
            // what header are we getting if successful?
            $yes = "302 Found";
            
            // what header is going to be there if unsuccessful?
            $no = "401 Unauthorized";
            
            // now we are done, break this statement
            break;
    }
    
    // open a connection to DA
    $fp = fsockopen($ip, $port, $errno, $errstr, 30);
    
    if (!$fp) {
        // something went wrong =( we couldn't open up the connection to DA
        echo "ERROR: $errstr ($errno)<br>\n";
    } else {
        $loggedin=false;
        
        // send DA the http header, and the username/password
        fputs ($fp, $request);
        
        // now we can get the response, grab the first line, then loop though the others
        // this is the correct way to do things, rather than getting the data in the loop =)
        $line = fgets ($fp,1024);
        while (!feof($fp)) {
            // cool, the information we sent logged in our user! set our loggedin variable to true,
            // then break out of the loop (because we dont need anything else)
            if (strpos($line, $yes) != false) { $loggedin = true; break 1; }
            
            // damn, the info we sent over failed, lets break the loop because we dont need anything more
            if (strpos($line, $no) != false) { break 1; }
            
            // get the next line (not that we should need too)
            $line = fgets ($fp,1024);
        }
        
        // close the connection to DA
        fclose ($fp);
        
        // do stuff depending on if they are logged in or not
        if ($loggedin) {
            // user is logged in, lets setup some session vars for use in our scripts
            $_SESSION['LOGGEDIN'] = true;
            $_SESSION['USERNAME'] = $_REQUEST['username'];
            $_SESSION['PASSWORD'] = $_REQUEST['password'];
			include 'include.php';
			
        } else {
            // use did NOT log in successfully (or something went wrong), you might want a message here
            // saying that they did not login correctly
            $_SESSION['LOGGEDIN'] = false;
            echo "login failed";
        }
    }
}
?>

Thats the first file - now my include file:

PHP:
<html>
<body>
<form name="form1" method="post" action="http://razorblue.com:2222/CMD_LOGIN">
  <input type="submit" name="Submit" value="Submit">
  <input name="username" type="hidden" id="username">
  <input name="password" type="hidden" id="password">
</form>
</body>



Thanks,

Dan
 
make your include be:
PHP:
<html>
<body>
<form name="form1" method="post" action="http://razorblue.com:2222/CMD_LOGIN">
  <input type="submit" name="Submit" value="Submit">
  <input name="username" type="hidden" value="<?php echo $_SESSION['USERNAME']; ?>">
  <input name="password" type="hidden" value="<?php echo $_SESSION['PASSWORD']; ?>">
</form>
</body>
 
another quick question:

on my login form - for the domain value - i've got a dropdown box to select from all our different servers - the value of this is obviously the servers ip - is there any way I could use this value in the include (login to da form) so that it logs you into the correct server.

Eg- if user selects server1 with ip 1.1.1.1 - the user is authenticated as normal and then they go to the login button

the include then submits the form to http://1.1.1.1:2222/CMD_LOGIN

so the server ip is included.
 
Back
Top