diff --git a/pool/base.php b/pool/base.php
index 860de7c6..aab770b9 100644
--- a/pool/base.php
+++ b/pool/base.php
@@ -65,6 +65,12 @@ function emailStr($str)
return preg_replace(array($all,$beg,$fin), '', $str);
}
#
+function passrequires()
+{
+ return "Passwords require 6 or more characters, including
" .
+ "at least one of each uppercase, lowercase and a digit, but not Tab";
+}
+#
function safepass($pass)
{
if (strlen($pass) < 6)
@@ -171,7 +177,17 @@ function dbd($data, $user)
#
function dbdown()
{
- gopage(NULL, 'dbd', 'dbd', NULL, '', '', true, false, false);
+ gopage(NULL, 'dbd', 'dbd', def_menu(), '', '', true, false, false);
+}
+#
+function syse($data, $user)
+{
+ return "
System error";
+}
+#
+function syserror()
+{
+ gopage(NULL, 'syse', 'syse', def_menu(), '', '', true, false, false);
}
#
function f404($data)
@@ -181,7 +197,7 @@ function f404($data)
#
function do404()
{
- gopage(NULL, 'f404', 'f404', NULL, '', '', true, false, false);
+ gopage(NULL, 'f404', 'f404', def_menu(), '', '', true, false, false);
}
#
function showPage($page, $menu, $name, $user)
@@ -200,7 +216,7 @@ function showPage($page, $menu, $name, $user)
#
function showIndex()
{
- showPage('index', NULL, '', false);
+ showPage('index', def_menu(), '', false);
}
#
function offline()
@@ -250,7 +266,8 @@ function logout()
function requestRegister()
{
$reg = getparam('Register', false);
- if ($reg !== NULL)
+ $reg2 = getparam('Reset', false);
+ if ($reg !== NULL || $reg2 !== NULL)
{
logout();
return true;
diff --git a/pool/db.php b/pool/db.php
index ab67c284..9bff93f2 100644
--- a/pool/db.php
+++ b/pool/db.php
@@ -65,6 +65,12 @@ function repDecode($rep)
return $ans;
}
#
+# Convenience function
+function zeip()
+{
+ return $_SERVER['REMOTE_ADDR'];
+}
+#
function msgEncode($cmd, $id, $fields, $user)
{
global $send_sep, $fld_sep, $val_sep;
@@ -75,7 +81,7 @@ function msgEncode($cmd, $id, $fields, $user)
$msg .= $name . $val_sep . $value . $fld_sep;
$msg .= 'createcode' . $val_sep . 'php' . $fld_sep;
$msg .= 'createby' . $val_sep . $user . $fld_sep;
- $msg .= 'createinet' . $val_sep . $_SERVER['REMOTE_ADDR'];
+ $msg .= 'createinet' . $val_sep . zeip();
return $msg;
}
#
@@ -112,7 +118,7 @@ function checkPass($user, $pass)
{
$passhash = myhash($pass);
$flds = array('username' => $user, 'passwordhash' => $passhash);
- $msg = msgEncode('chkpass', 'log', $flds, $user);
+ $msg = msgEncode('chkpass', 'chkpass', $flds, $user);
$rep = sendsockreply('checkPass', $msg);
if (!$rep)
dbdown();
@@ -124,13 +130,24 @@ function setPass($user, $oldpass, $newpass)
$oldhash = myhash($oldpass);
$newhash = myhash($newpass);
$flds = array('username' => $user, 'oldhash' => $oldhash, 'newhash' => $newhash);
- $msg = msgEncode('newpass', 'log', $flds, $user);
+ $msg = msgEncode('newpass', 'newpass', $flds, $user);
$rep = sendsockreply('setPass', $msg);
if (!$rep)
dbdown();
return repDecode($rep);
}
#
+function resetPass($user, $newpass)
+{
+ $newhash = myhash($newpass);
+ $flds = array('username' => $user, 'newhash' => $newhash);
+ $msg = msgEncode('newpass', 'newpass', $flds, $user);
+ $rep = sendsockreply('resetPass', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
function userReg($user, $email, $pass)
{
$passhash = myhash($pass);
@@ -204,4 +221,78 @@ function getBlocks($user)
return repDecode($rep);
}
#
+# e.g. $atts = array('ua_Reset.str' => 'FortyTwo',
+# 'ua_Reset.date' => 'now+3600')
+# 'ua_Tanuki.str' => 'Meme',
+# 'ua_Tanuki.date' => 'now');
+function setAtts($user, $atts)
+{
+ if ($user == false)
+ showIndex();
+ $flds = array_merge(array('username' => $user), $atts);
+ $msg = msgEncode('setatts', 'setatts', $flds, $user);
+ $rep = sendsockreply('setAtts', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
+# e.g. $attlist = 'Reset.str,Reset.dateexp,Tanuki.str,Tanuki.date'
+function getAtts($user, $attlist)
+{
+ if ($user == false)
+ showIndex();
+ $flds = array('username' => $user, 'attlist' => $attlist);
+ $msg = msgEncode('getatts', 'getatts', $flds, $user);
+ $rep = sendsockreply('getAtts', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
+# e.g. $attlist = 'Reset,Tanuki'
+# effectively makes the useratts disappear (i.e. expired)
+function expAtts($user, $attlist)
+{
+ if ($user == false)
+ showIndex();
+ $flds = array('username' => $user, 'attlist' => $attlist);
+ $msg = msgEncode('expatts', 'expatts', $flds, $user);
+ $rep = sendsockreply('expAtts', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
+# e.g. $opts = array('oc_BlockAmountHalf.value' => '25',
+# 'oc_BlockAmountHalf.height' => '210000',
+# 'oc_BlockAmountHalf.date' => '2012-11-28 15:25:01+00',
+# 'oc_BlockAmountQuarter.value' => '12.5',
+# 'oc_BlockAmountQuarter.height' => '420000');
+# *.value is always required
+function setOpts($user, $opts)
+{
+ if ($user == false)
+ showIndex();
+ $flds = array_merge(array('username' => $user), $opts);
+ $msg = msgEncode('setopts', 'setopts', $flds, $user);
+ $rep = sendsockreply('setOpts', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
+# e.g. $optlist = 'KWebURL,BlockAmountQuarter'
+function getOpts($user, $optlist)
+{
+ if ($user == false)
+ showIndex();
+ $flds = array('username' => $user, 'optlist' => $optlist);
+ $msg = msgEncode('getopts', 'getopts', $flds, $user);
+ $rep = sendsockreply('getOpts', $msg);
+ if (!$rep)
+ dbdown();
+ return repDecode($rep);
+}
+#
?>
diff --git a/pool/email.php b/pool/email.php
new file mode 100644
index 00000000..dbc5a506
--- /dev/null
+++ b/pool/email.php
@@ -0,0 +1,116 @@
+
diff --git a/pool/page.php b/pool/page.php
index d042864a..ed8945bb 100644
--- a/pool/page.php
+++ b/pool/page.php
@@ -327,8 +327,7 @@ function pgtop($dotop, $user, $douser)
- |
';
$ret .= '
';
+
+ $pg .= ' | Password Reset'; + $pg .= makeForm(''); + $pg .= " +
" . - "at least one of each uppercase, lowercase and digits, but not Tab"; + $data['error'] = "Password is unsafe"; } elseif ($pass2 != $pass) { @@ -108,7 +133,86 @@ function show_reg($page, $menu, $name, $u) $data['error'] = "Invalid username, password or email address"; } - gopage($data, 'doreg', $page, $menu, $name, $u, true, true, false); + gopage($data, 'doregres', $page, $menu, $name, $u, true, true, false); +} +# +function doreset2($data) +{ + $user = $data['user']; + $email = $data['email']; + + $emailinfo = getOpts($user, emailOptList()); + if ($emailinfo['STATUS'] != 'ok') + syserror(); + + $ans = getAtts($user, 'KLastReset.dateexp'); + if ($ans['STATUS'] != 'ok') + syserror(); + + // If the last attempt hasn't expired don't do anything but show a fake msg + if (!isset($ans['KLastReset.dateexp']) || $ans['KLastReset.dateexp'] == 'Y') + { + // This line $code = isn't an attempt at security - + // it's simply to ensure the username is readable when we get it back + $code = bin2hex($data['user']). '_'; + + // A code that's large enough to not be worth guessing + $ran = $ans['STAMP'].$user.$email.rand(100000000,999999999); + $hash = hash('md4', $ran); + + $ans = setAtts($user, array('ua_KReset.str' => $hash, + 'ua_KReset.date' => 'now+3600', + 'ua_LastReset.date' => 'now+3600')); + if ($ans['STATUS'] != 'ok') + syserror(); + + $ok = passReset($email, $code.$hash, zeip(), $emailinfo); + if ($ok === false) + syserror(); + } + + $pg = ' Reset Sent'; + $pg .= 'An Email has been sent that will allow you to'; + $pg .= ' reset your password.'; + $pg .= ' If you got your username or email address wrong,'; + $pg .= ' you wont get the email.'; + return $pg; +} +# +function try_reset($page, $menu, $name, $u) +{ + $user = getparam('user', false); + $mail = trim(getparam('mail', false)); + + // Slow this right down + usleep(500000); + + $data = array(); + + if (!nuem($user)) + $user = loginStr($user); + + if (!nuem($user) && !nuem($mail)) + { + $ans = userSettings($user); + if ($ans['STATUS'] == 'ok' && isset($ans['email']) && $ans['email'] == $mail) + { + $data = array('user' => $user, 'email' => $mail); + + gopage($data, 'doreset2', $page, $menu, $name, $u, true, true, false); + } + } + + gopage($data, 'doregres', $page, $menu, $name, $u, true, true, false); +} +# +function show_reg($page, $menu, $name, $u) +{ + $reg = getparam('Register', false); + if ($reg !== NULL) + try_reg($page, $menu, $name, $u); + else + try_reset($page, $menu, $name, $u); } # ?> diff --git a/pool/page_reset.php b/pool/page_reset.php new file mode 100644 index 00000000..7dc584fe --- /dev/null +++ b/pool/page_reset.php @@ -0,0 +1,166 @@ +
Password Reset'; + $pg .= 'Your password has been reset,'; + $pg .= ' login with it on the Home page.'; + return $pg; +} +# +function resetfail() +{ + if (isset($_SESSION['reset_user'])) + unset($_SESSION['reset_user']); + if (isset($_SESSION['reset_hash'])) + unset($_SESSION['reset_hash']); + if (isset($_SESSION['reset_email'])) + unset($_SESSION['reset_email']); + $pg = ' Reset Failed'; + $pg .= 'Try again from the Home page Register/Reset button later'; + return $pg; +} +# +function dbreset() +{ + $user = $_SESSION['reset_user']; + $hash = $_SESSION['reset_hash']; + $email = $_SESSION['reset_email']; + + $pass = getparam('pass', true); + $pass2 = getparam('pass2', true); + + if (nuem($pass) || nuem($pass2)) + return allow_reset('Enter both passwords'); + + if ($pass2 != $pass) + return allow_reset("Passwords don't match"); + + if (safepass($pass) !== true) + return allow_reset('Password is unsafe'); + + $ans = getAtts($user, 'KReset.str,KReset.dateexp'); + if ($ans['STATUS'] != 'ok') + return resetfail(); + + if (!isset($ans['KReset.dateexp']) || $ans['KReset.dateexp'] == 'Y') + return resetfail(); + + if (!isset($ans['KReset.str']) || $ans['KReset.str'] != $hash) + return resetfail(); + + $emailinfo = getOpts($user, emailOptList()); + if ($emailinfo['STATUS'] != 'ok') + syserror(); + + $ans = resetPass($user, $pass); + if ($ans['STATUS'] != 'ok') + syserror(); + + unset($_SESSION['reset_user']); + unset($_SESSION['reset_hash']); + unset($_SESSION['reset_email']); + + $ans = expAtts($user, 'KReset'); + + $ok = passWasReset($email, zeip(), $emailinfo); + + return yok(); +} +# +function doreset($data, $u) +{ + // Slow this right down + usleep(500000); + + if (isset($_SESSION['reset_user']) + && isset($_SESSION['reset_hash']) + && isset($_SESSION['reset_email'])) + return dbreset(); + + $code = getparam('code', true); + if (nuem($code)) + return resetfail(); + + $codes = explode('_', $code, 2); + + if (sizeof($codes) != 2) + return resetfail(); + + $userhex = $codes[0]; + + if (strlen($userhex) == 0 || strlen($userhex) % 2) + return resetfail(); + + $user = loginStr(pack("H*" , $userhex)); + + $hash = preg_replace('/[^A-Fa-f0-9]/', '', $codes[1]); + + if (!nuem($user) && !nuem($hash)) + { + $ans = getAtts($user, 'KReset.str,KReset.dateexp'); + if ($ans['STATUS'] != 'ok') + return resetfail(); + + if (!isset($ans['KReset.dateexp']) || $ans['KReset.dateexp'] == 'Y') + return resetfail(); + + if (!isset($ans['KReset.str']) || $ans['KReset.str'] != $hash) + return resetfail(); + + $ans = userSettings($user); + if ($ans['STATUS'] != 'ok') + return resetfail(); + + if (!isset($ans['email'])) + return resetfail(); + + $email = $ans['email']; + + $_SESSION['reset_user'] = $user; + $_SESSION['reset_hash'] = $hash; + $_SESSION['reset_email'] = $email; + + return allow_reset(null); + } + return resetfail(); +} +# +function show_reset($page, $menu, $name, $u) +{ + gopage(array(), 'doreset', $page, $menu, $name, $u, true, true, false); +} +# +?> diff --git a/pool/prime.php b/pool/prime.php index 55fba0b0..d6599b7d 100644 --- a/pool/prime.php +++ b/pool/prime.php @@ -6,28 +6,8 @@ $stt = microtime(); include_once('param.php'); include_once('base.php'); # -function process($p, $user) +function process($p, $user, $menu) { - $menu = array( - 'Home' => array( - 'Home' => '' - ), - 'Account' => array( - 'Workers' => 'workers', - 'Payments' => 'payments', - 'Settings' => 'settings' - ), - 'Pool' => array( - 'Stats' => 'stats', - 'Blocks' => 'blocks' - ), - 'Admin' => NULL, - 'gap' => NULL, - 'Help' => array( - 'Help' => 'help', - 'Payouts' => 'payout' - ) - ); if ($user == 'Kano' || $user == 'ckolivas' || $user == 'wvr2' || $user == 'aphorise') { $menu['Admin']['ckp'] = 'ckp'; @@ -35,7 +15,10 @@ function process($p, $user) $menu['Admin']['AllWork'] = 'allwork'; } else - unset($menu['Admin']); + { + if (isset($menu['Admin'])) + unset($menu['Admin']); + } $page = ''; $n = ''; foreach ($menu as $item => $options) @@ -53,21 +36,60 @@ function process($p, $user) showPage($page, $menu, $n, $user); } # +function def_menu() +{ + $dmenu = array('Home' => array('Home' => ''), + 'gap' => NULL, + 'Help' => array('Help' => 'help', + 'Payouts' => 'payout')); + return $dmenu; +} +# function check() { + $dmenu = def_menu(); + $menu = array( + 'Home' => array( + 'Home' => '' + ), + 'Account' => array( + 'Workers' => 'workers', + 'Payments' => 'payments', + 'Settings' => 'settings' + ), + 'Pool' => array( + 'Stats' => 'stats', + 'Blocks' => 'blocks' + ), + 'Admin' => NULL, + 'gap' => NULL, + 'Help' => array( + 'Help' => 'help', + 'Payouts' => 'payout' + ) + ); tryLogInOut(); $who = loggedIn(); if ($who === false) { - if (requestRegister() == true) - showPage('reg', NULL, '', $who); + $p = getparam('k', true); + if ($p == 'reset') + showPage('reset', $dmenu, '', $who); else - showIndex(); + { + if (requestRegister() == true) + showPage('reg', $dmenu, '', $who); + else + { + $p = getparam('k', true); + process($p, $who, $dmenu); + } + } } else { $p = getparam('k', true); - process($p, $who); + process($p, $who, $menu); } } # diff --git a/sql/ckdb.sql b/sql/ckdb.sql index 9292f27c..7285972c 100644 --- a/sql/ckdb.sql +++ b/sql/ckdb.sql @@ -415,4 +415,4 @@ CREATE TABLE version ( PRIMARY KEY (vlock) ); -insert into version (vlock,version) values (1,'0.9'); +insert into version (vlock,version) values (1,'0.9.2'); diff --git a/sql/initid.sh b/sql/initid.sh index c2699ecb..31c119d9 100755 --- a/sql/initid.sh +++ b/sql/initid.sh @@ -2,25 +2,10 @@ # fldsep="`echo -e '\x09'`" # -dsp() -{ - cut -c4- -# echo -} -process() -{ - # <256 - len=${#1} - oct="`printf '%03o' "$len"`" - code="`printf "\\\\$oct"`" - all="$code$zero$zero$zero$1" - printf "$code\\0\\0\\000$1" | nc -U -w 1 /opt/ckdb/listener | dsp -} -# addid() { msg="newid.$1.idname=$1${fldsep}idvalue=$2" - process "$msg" + echo "$msg" } # # Default to yyyymmddXXXXXX diff --git a/src/ckdb.c b/src/ckdb.c index c8bfd20d..b6aae128 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -49,7 +49,7 @@ #define DB_VLOCK "1" #define DB_VERSION "0.9.2" -#define CKDB_VERSION DB_VERSION"-0.313" +#define CKDB_VERSION DB_VERSION"-0.320" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -2710,7 +2710,7 @@ static K_ITEM *find_userid(int64_t userid) return find_in_ktree(userid_root, &look, cmp_userid, ctx); } -// TODO: endian? +// TODO: endian? (to avoid being all zeros?) static void make_salt(USERS *users) { long int r1, r2, r3, r4; @@ -2976,13 +2976,14 @@ static K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, STRNCPY(row->username, username); row->status[0] = '\0'; STRNCPY(row->emailaddress, emailaddress); - STRNCPY(row->passwordhash, passwordhash); snprintf(tohash, sizeof(tohash), "%s%s", username, emailaddress); HASH_BER(tohash, strlen(tohash), 1, hash, tmp); __bin2hex(row->secondaryuserid, (void *)(&hash), sizeof(hash)); make_salt(row); + password_hash(row->username, passwordhash, row->salt, + row->passwordhash, sizeof(row->passwordhash)); HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATETRANSFER(trf_root, row); |