'SECRETKEEPER', 'cookie_secure' => 'on']); /* * Figure out the state of the session. This will be set by the previous * run of the script, unless the user has just contacted, in which case * either the cookie will be expired, so not sent to the server, or the * session will have expired so the server no longer retains it. In either * of those cases, you get state 'out'; */ $state = 'out'; if(isset($_SESSION['state'])) $state = $_SESSION['state']; // Current error message, if we find one. $error = ''; // Extra status message, if any. $message = ''; /* * Open the database on the server. First, I'm going to decide if read * perm is okay, or if I might need to write so I will have the right mode. * Important to limit damage from bugs, and because the system will * generally allow only one writer to proceed at a time, but multiple * readers. Basically, we ask for write permission of we have form post * data and see any of buttons which update things. */ $perm = 'r'; if(isset($_POST) && (isset($_POST['CREATE']) || isset($_POST['UPDATE']) || isset($_POST['CHANGE']))) $perm = 'w'; $dbm = @dba_open('/var/wwwwrite/bennet/secrets', $perm, "db4"); if($dbm === false) { $error = 'Unable to open database.'; $state = 'error'; // This will be changed to 'out' before generating HTML. } // Here we implement the state transition based on the current state and the // values in the post data. If there is no post data, the state does not // change. if(isset($_POST)) { if($state == 'out') { if(isset($_POST['SIGNUP'])) { // Signup button. Just changes state to show correct page. $state = 'signup'; } else if(isset($_POST['LOGIN'])) { // Trying to log in. If login fails, state does not change. if(!$_POST['user'] || !$_POST['pass']) { // But didn't fill out everything, or left blanks. $error = 'Login incorrect'; } else { // Filled out, see if we like the creds. The // fetch returns false if the account doesn't // exist, then if it does, we check the password. $encpass = dba_fetch($_POST['user'], $dbm); if($encpass && password_verify($_POST['pass'], $encpass)) { // User sent correct password. Change to a logged in // state, and add the user name to the session. $state = 'show'; $_SESSION['user'] = $_POST['user']; } else { // Either the account does not exist, or // the creds were wrong. $error = 'Login incorrect'; } } } // At this point, state will have changed to signup (if that // button was pressed) or show on a successful login. Otw, // it remains out. } else if($state == 'signup') { // In state signup. See what was sent. if(isset($_POST['CANCEL'])) { // Canceled signup. $state = 'out'; } else if(isset($_POST['CREATE'])) { if(!$_POST['user'] || !$_POST['pass'] || !$_POST['secret']) { $error = 'Please fill out all fields.'; } else if(strspn($_POST['user'], LETTERS.DIGITS) != strlen($_POST['user'])) { $error = 'Account name must be alphanumeric'; } else if(dba_exists($_POST['user'], $dbm)) { // Account already in the database. $error = 'Account '.$_POST['user'].' exists.'; } else { // Check the password and update the database. $msg = store_pwd($_POST['user'], $_POST['pass'], $_POST['pass2'], $dbm); if($msg == '' && !dba_replace($_POST['user'].'_secret', $_POST['secret'], $dbm)) { $msg = 'Database update failed.'; } // See if it all worked. if($msg == '') { // Account was created. Go to the show page. $state = 'show'; $_SESSION['user'] = $_POST['user']; } else { // Failed. $error = $msg; } } } } else if($state == 'show') { if(isset($_POST['UPDATE'])) { // Change the secret. if(!dba_replace($_SESSION['user'].'_secret', $_POST['secret'], $dbm)) { $error = 'Database update failed'; } else { $message = "Updated"; } } else if(isset($_POST['NEWPASS'])) { $state = 'newpass'; } else if(isset($_POST['LOGOUT'])) { $state = 'out'; } } else if($state == 'newpass') { // Performing password change. if(isset($_POST['CANCEL'])) { // Password change cancelled. $state = 'show'; } else if(isset($_POST['CHANGE'])) { // Check the match. if($_POST['pass'] != $_POST['pass2']) { $error = "Passwords don't match."; } else { // Store the new password $msg = store_pwd($_SESSION['user'], $_POST['pass'], $_POST['pass2'], $dbm); if($msg == '') { $state = 'show'; $message = 'Password changed'; } else { $error = $msg; } } } } } if($state == 'error') $state = 'out'; // Make sure session state agrees with any changes made above. $_SESSION['state'] = $state; /* * Functions for generating HTML content. */ // Create an HTML form submit button function button($name, $label) { echo ""; } // Put several buttons in a div by passing an array of $name/$label // values. function buttons($buttons) { echo '
'; for($i = 0; $i < count($buttons); $i += 2) button($buttons[$i], $buttons[$i+1]); echo '
'; } // Create a labeled entry. $type can be 'password' instead of 'entry'. function entry($name, $label, $type='entry') { echo "
", "
\n"; } // Generate the login page. function login_page() { echo '
',"\n"; entry('user', 'User name'); entry('pass', 'Password', 'password'); buttons(array('LOGIN', 'Log in', 'SIGNUP', 'Create Account')); echo '
'; } // Generate the secret page. function secret_page($dbm) { echo "

Secret for ",$_SESSION['user'],"

"; echo '
',"\n"; $secret = htmlspecialchars(dba_fetch($_SESSION['user'].'_secret', $dbm)); echo ""; buttons(array('UPDATE', 'Update Secret', 'NEWPASS', 'Change Password', 'LOGOUT', 'Log out')); echo '
'; } // Generate the password change page. function change_pass_page() { echo "

Change password for ",$_SESSION['user'],"

"; echo '
',"\n"; entry('pass', 'Password', 'password'); entry('pass2', 'Retype Password', 'password'); buttons(array('CHANGE', 'Change Password', 'CANCEL', 'Cancel')); echo '
'; } // Generate the signup page function signup_page() { echo "

Create a Secret Keeper Account

"; echo '
',"\n"; entry('user', 'User name'); entry('pass', 'Password', 'password'); entry('pass2', 'Retype Password', 'password'); echo "

Enter your secret below

\n"; echo ""; buttons(array('CREATE', 'Create Account', 'CANCEL', 'Cancel')); echo '
'; } ?> My Secret Keeper

Secret Keeper

$perm $message $error
"; //print_r($_SESSION); if($error) { echo "$error"; } if($message) { echo "$message"; } ?>

Internal Error

\n"; $_SESSION['state'] = 'out'; $_SESSION['user'] = ''; } ?>