<?PHP
//  Filename: changepassword.php
//  Author:   Charlie Boisseau  <http://www.boisseau.co.uk>
//                               charlie at boisseau dot co dot uk
//  Modified: 31st March 2004
//  Purpose:  This is an example of how to interact with the PWD
//            server inside every Eudora or Stalker mail server.
//            If you haven't already guessed, PWD is a protocol
//            changing passwords.  So this can be used in webmail
//            or ISP customer service setups to allow users to
//            automatically change their password.

//            I couldn't find any specifications for the protocol,
//            so I used my application, Net Tool Box, to work it
//            out for myself.  You can download Net Tool Box from
//            <http://www.nettoolbox.net/>

//            This code is completely free, however if you are
//            using it, I'd apreciate a post card, email or even
//            a donation (details for all three are available at
//            <http://www.boisseau.co.uk/>.


function changePWD($host$user$pass$newpass) {

    
//  This is the function which actually does the work.
    //  It connects to the PWD server on port 106, sends the
    //  Username and existing Password.  The server sends back a
    //  response code (200 being OK) telling us whether the supplied
    //  credentials were valid.  Providing they were OK, we send the
    //  new password.  The server then gives us another response
    //  code telling us if the new password is valid.  If all is OK,
    //  we send the QUIT command and close the connectioin, returning
    //  an 'OK' messgae.  If there was an error, the returned value
    //  is a message saying what went wrong.

    //  Open the socket and put it in blocking mode.
    
$fp fsockopen ($host106);
    
socket_set_blocking ($fptrue);

    
//  Get the server's greeting (just to keep it happy).  Then send
    //  the username.  We then wait for it to reply with an
    //  acknowledgement then we send the current user password.
    
fgets ($fp);
    
fputs ($fp"USER $user\r\n");
    
fgets ($fp);
    
fputs ($fp"PASS $pass\r\n");
    
    
//  Now we look at the server's response code.  It tells us whether
    //  we sent valid login details and whether we should continue to
    //  send the new password.
    
$s fgets($fp);
    
$t strtok($s" ");
    if (
$t != "200") {
        
//  The error code was something other than 200.  We'll assume
        //  the username or password was wrong.  Store a message in the
        //  $error variable.  We will return this later.
        
$error "Invalid Current User/Pass"; }
    else {
        
//  The error code *was* 200; we can send the new password.
        
fputs ($fp"NEWPASS $newpass\r\n");
        
        
//  It then gives us yet another response code to say whether
        //  or not it agreed that the password we provided was the
        //  correct format.
        
$s fgets($fp);
        
$t strtok($s" ");
        if (
$t != "200") {
            
//  There was a problem; store a message in $error.
            
$error "New password invalid";
        }
    }
    
    
//  Regardless of what happened, we should still be polite, and send
    //  the QUIT command before we close our socket.

    
fputs($fp"QUIT\r\n");
    
fclose($fp);

    
//  Now check to see if our $error variable contains anything.  If it
    //  does, it means there was a problem, so we return the contents to
    //  the user.  If it's empty, we send a message declaring the password
    //  was sucessfully changed.

    
If ($error == "") {
        return 
"OK: Password Changed";
    } else {
        return 
"Error: " $error;
    }
}
?>

<HTML><HEAD>
<TITLE>Change Password</TITLE>
</HEAD>
<BODY>
<div align="center">
  <h1>Change your password:</h1>
<?php
//  We now have the cosmetics to deal with.  First, we privately set the
//  address of our mail/PWD server.  You should change this line to the
//  address of your server.

$server "mail.myisp.net"

//  Check to see if we have any interaction, or is this the first time we
//  have met this user.  If there is a username sent as a parameter, that
//  is our cue to start doing the work.

if ($_REQUEST['User']) {
    
//  Do a little check to see if our new password field and the confirm
    //  field match.  We want to make sure the user can't set a wrongly-typed
    //  password.  The protocol doesn't provide any checking like that, so we
    //  should.  There should probably also be a check in here to make sure
    //  the password fields aren't empty.  It doesn't matter though, because
    //  the server should do a check for that.
    
if ($_REQUEST['NewPass'] != $_REQUEST['Confirm']) {
        
//  The NewPass and Confirm Feilds didn't match.  Print an error in
        //  red, then re-send the form for them to try again.
        
echo "<font color=\"#FF0000\">Your new passwords didn't match.  Please try again:</font>";
        
printForm();
        
    } else {
        
//  The passwords matched.  We can pass the details through to the
        //  changePWD function. We will put the resultig message in $s.
        
$s changePWD($server,$_REQUEST['User'], $_REQUEST['Pass'], $_REQUEST['NewPass']);
        
        
//  We now check the beginning of the message to see if it said 'OK'.
        //  If it does, just print the message returned from the function,
        //  otherwise we print the error message in red and re-print the
        //  form for them to try again.
        
        
$t strtok($s":");
        if (
$t == "OK") {
            
            echo 
$s;
            
        } else {
            
            echo 
"<font color=\"#FF0000\">$s</font>";
            
printForm();
        }
    }
} else {
    
//  We haven't been sent any username parameter, so we'll just assume
    //  this is the first time the page was accessed.  So all we'll do for
    //  now is just send the form for them to fill in.
    
printForm();
}

function 
printForm() {
    
//    This function is only here because we need to print the form at
    //  different times.  If it's in a function, it can be called only
    //  when needed.
?>
<form method="post" action="changepassword.php">
    <table border="0">
      <tr> 
        <td align="right">Username: </td>
        <td><input name="User" type="text" value="<?php echo $_REQUEST['User']; ?>"></td>
      </tr>
      <tr> 
        <td align="right">Current Password: </td>
        <td><input name="Pass" type="password"></td>
      </tr>
      <tr> 
        <td align="right">New Password: </td>
        <td><input name="NewPass" type="password"></td>
      </tr>
      <tr> 
        <td align="right">Confirm: </td>
        <td><input name="Confirm" type="password"></td>
      </tr>
      <tr> 
        <td>&nbsp;</td>
        <td align="right"> <input name="submit" type="submit" value="Submit"> 
        </td>
      </tr>
    </table>
  </form>
  <?php
}
//  End of the printForm function.
?>
  <p>&copy; Charlie Boisseau 2003</p>
</div>
</BODY>
</HTML>