Browse Source

php - add direct address validation and allow variable socket timeouts

master
kanoi 10 years ago
parent
commit
ef759a70bc
  1. 6
      pool/db.php
  2. 37
      pool/socket.php
  3. 3
      src/ckdb.h
  4. 42
      src/ckdb_btc.c
  5. 8
      src/ckdb_cmd.c

6
pool/db.php

@ -174,15 +174,19 @@ function userReg($user, $email, $pass)
#
function userSettings($user, $email = null, $addr = null, $pass = null)
{
$tmo = false;
$flds = array('username' => $user);
if ($email != null)
$flds['email'] = $email;
if ($addr != null)
{
$flds['address'] = $addr;
$tmo = 3; # 3x the timeout
}
if ($pass != null)
$flds['passwordhash'] = myhash($pass);
$msg = msgEncode('usersettings', 'userset', $flds, $user);
$rep = sendsockreply('userSettings', $msg);
$rep = sendsockreply('userSettings', $msg, $tmo);
if (!$rep)
dbdown();
return repDecode($rep);

37
pool/socket.php

@ -1,9 +1,26 @@
<?php
#
# See function sendsockreply($fun, $msg) at the end
# See function sendsockreply($fun, $msg, $tmo) at the end
#
function socktmo($socket, $factor)
{
# default timeout factor
if ($factor === false)
$factor = 1;
# on a slower server increase this base value
$tmo = 2;
$usetmo = $tmo * $factor;
$sec = floor($usetmo);
$usec = floor(($usetmo - $sec) * 1000000);
$tmoval = array('sec' => $sec, 'usec' => $use);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $tmo);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $tmo);
}
#
# Note that $port in AF_UNIX should be the socket filename
function _getsock($fun, $port, $unix=true)
function _getsock($fun, $port, $tmo, $unix=true)
{
$socket = null;
if ($unix === true)
@ -57,17 +74,15 @@ function _getsock($fun, $port, $unix=true)
}
}
# Avoid getting locked up for long
$tmo = array('sec' => 2, 'usec' => 0);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $tmo);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $tmo);
socktmo($socket, $tmo);
# Enable timeout
socket_set_block($socket);
return $socket;
}
#
function getsock($fun)
function getsock($fun, $tmo)
{
return _getsock($fun, '/opt/ckdb/listener');
return _getsock($fun, '/opt/ckdb/listener', $tmo);
}
#
function readsockline($fun, $socket)
@ -161,10 +176,10 @@ function dosend($fun, $socket, $msg)
return $ret;
}
#
function sendsock($fun, $msg)
function sendsock($fun, $msg, $tmo = false)
{
$ret = false;
$socket = getsock($fun);
$socket = getsock($fun, $tmo);
if ($socket !== false)
{
$ret = dosend($fun, $socket, $msg);
@ -178,10 +193,10 @@ function sendsock($fun, $msg)
# and the data $msg to send to ckdb
# and it returns $ret = false on error or $ret = the string reply
#
function sendsockreply($fun, $msg)
function sendsockreply($fun, $msg, $tmo = false)
{
$ret = false;
$socket = getsock($fun);
$socket = getsock($fun, $tmo);
if ($socket !== false)
{
$ret = dosend($fun, $socket, $msg);

3
src/ckdb.h

@ -52,7 +52,7 @@
#define DB_VLOCK "1"
#define DB_VERSION "0.9.2"
#define CKDB_VERSION DB_VERSION"-0.513"
#define CKDB_VERSION DB_VERSION"-0.515"
#define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -1494,6 +1494,7 @@ extern struct CMDS ckdb_cmds[];
// *** ckdb_btc.c
// ***
extern bool btc_valid_address(char *addr);
extern void btc_blockstatus(BLOCKS *blocks);
#endif

42
src/ckdb_btc.c

@ -20,6 +20,10 @@
#define GETBLOCK "{\"method\":\"" GETBLOCKCMD "\",\"params\":[\"%s\"],\"id\":1}"
#define GETBLOCKCONFKEY ((const char *)"confirmations")
#define VALIDADDRCMD "validateaddress"
#define VALIDADDR "{\"method\":\"" VALIDADDRCMD "\",\"params\":[\"%s\"],\"id\":1}"
#define VALIDADDRKEY ((const char *)"isvalid")
static char *btc_data(char *json, size_t *len)
{
size_t off;
@ -234,6 +238,31 @@ static int64_t single_decode_int(char *ans, const char *cmd, const char *key)
return val;
}
static bool single_decode_bool(char *ans, const char *cmd, const char *key)
{
json_t *json_ob;
int json_typ;
bool val = false;
json_ob = single_decode(ans, cmd, key);
if (json_ob) {
json_typ = json_typeof(json_ob);
if (json_typ != JSON_TRUE && json_typ != JSON_FALSE) {
char *text = safe_text(ans);
if (!key)
key = BTCKEY;
LOGERR("%s() Json %s key %s "
"not a bool ans='%s'",
__func__, cmd, key, text);
free(text);
} else {
if (json_typ == JSON_TRUE)
val = true;
}
}
return val;
}
static char *btc_blockhash(int32_t height)
{
char buf[1024];
@ -260,6 +289,19 @@ static int32_t btc_confirms(char *hash)
return conf;
}
bool btc_valid_address(char *addr)
{
char buf[1024];
char *ans;
bool valid;
snprintf(buf, sizeof(buf), VALIDADDR, addr);
ans = btc_io(VALIDADDRCMD, buf);
valid = single_decode_bool(ans, VALIDADDRCMD, VALIDADDRKEY);
free(ans);
return valid;
}
// Check for orphan or update confirm count
void btc_blockstatus(BLOCKS *blocks)
{

8
src/ckdb_cmd.c

@ -240,8 +240,12 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
goto struckout;
}
// if (address && *address)
// TODO: validate it
if (address && *address) {
if (!btc_valid_address(address)) {
reason = "Invalid BTC address";
goto struckout;
}
}
if (email && *email) {
ok = users_pass_email(conn, u_item, NULL,

Loading…
Cancel
Save