#!/usr/bin/perl -w
#
# $Id$
# 
# Simple CGI script to change your password, currently 'configured' 
# for dovecotpw, but could easy be ported to something else.
# 
# License: BSDLike
# Rick van der Zwet <info@rickvanderzwet.nl>

# WARNING: Fail safe switch 
# WARNING: CHANGE ME TO A STATIC STRING ELSE I FAIL TO WORK
$STATIC_AUTH_KEY= rand(100000);

use CGI;
$q = CGI->new;

$MIN_PASSWD_LENGTH=8;

$PASSWDFILE='/usr/local/www/eurobsdcon2011/.htpasswd';
$HTPASSWD='/usr/local/sbin/htpasswd';


if (! -w $PASSWDFILE || ! -x $HTPASSWD) { 
  print $q->header(-status=>$error);
  print $q->start_html('Problems');
  print $q->h2('Not able to open internals (database or binary)');
  exit 1;
};


# Message 'buffer', entries in here will be pushed on top of form
@messages = ();


#
# Verify validity of CGI input
sub check_cgi() {
  if ($q->request_method() eq "POST") {
    if (! ($q->param('username') && $q->param('auth_key') && 
        $q->param('new_password') && $q->param('verify_password'))) { 
      push(@messages, "Not all fields are provided");
      return 1;
    } 
    if ($q->param('new_password') ne $q->param('verify_password')) {
      push(@messages, 'New passwords does not match');
      return 1;
    }
    if ($q->param('new_password') eq $q->param('auth_key')) {
      push(@messages, 'New password equal to old password not changing');
      return 1;
    }
    if (length($q->param('new_password')) < $MIN_PASSWD_LENGTH) {
      push(@messages, "New password to short (minimal $MIN_PASSWD_LENGTH characters)");
      return 1;
    }
  return 0;
  }
  return 1;
}


# 
# Process CGI, assuming all values are correct
sub process_cgi_for_dovecotpw() {
  my $username = $q->param('username');
  my $auth_key = $q->param('auth_key');
  my $new_password = $q->param('new_password');

  if ($auth_key ne $STATIC_AUTH_KEY) {
    push(@messages, "Auth key invalid");
    return;
  }

  my $retval = `grep '^$username:' $PASSWDFILE`;
  if ( $retval ) {
    push(@messages, "Username does already exists!");
    return;
  } 

  $password = `$HTPASSWD -b $PASSWDFILE $username $new_password 2>&1`;
  push(@messages, "User added succesfully ($password)");
}

# Only process if field are valid
if (check_cgi() == 0) {
 process_cgi_for_dovecotpw();
}

print $q->header;
print $q->start_html('Change Email Password');
print $q->start_center();
if (@messages) {
  print $q->h2($q->ul({-style => 'list-style-type: none'}, $q->li(@messages)));
};
print $q->start_form();
print $q->table($q->caption($q->h2('Please provide your values to change password')),
  $q->Tr([$q->td(['username', $q->textfield('username','somebody')])]),
  $q->Tr([$q->td(['auth key', $q->password_field('auth_key')])]),
  $q->Tr([$q->td(['new password', $q->password_field('new_password')])]),
  $q->Tr([$q->td(['verify new password', $q->password_field('verify_password')])]),
  $q->Tr([$q->td({-colspan=>2,-align=>'center'},[$q->submit('submit', 'Change Password')])])
);
print '</table>';
print $q->end_form();
print $q->end_center();
print $q->end_html;
