From ef759a70bc9d211d0892d83dc4d6980014c32147 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 19 Oct 2014 10:28:31 +1100 Subject: [PATCH] php - add direct address validation and allow variable socket timeouts --- pool/db.php | 6 +++++- pool/socket.php | 37 ++++++++++++++++++++++++++----------- src/ckdb.h | 3 ++- src/ckdb_btc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/ckdb_cmd.c | 8 ++++++-- 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/pool/db.php b/pool/db.php index e1939f2f..f8764876 100644 --- a/pool/db.php +++ b/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); diff --git a/pool/socket.php b/pool/socket.php index b8da3e8d..08b683e2 100644 --- a/pool/socket.php +++ b/pool/socket.php @@ -1,9 +1,26 @@ $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); diff --git a/src/ckdb.h b/src/ckdb.h index 35d28ac6..e3661bd6 100644 --- a/src/ckdb.h +++ b/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 diff --git a/src/ckdb_btc.c b/src/ckdb_btc.c index 8f514fc3..7ede69e5 100644 --- a/src/ckdb_btc.c +++ b/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) { diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 3b99a1b8..6c0146dd 100644 --- a/src/ckdb_cmd.c +++ b/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,