mirror of
https://github.com/Yubico/yubikey-val.git
synced 2025-04-10 05:02:26 +02:00
Merge branch 'master' of github.com:Yubico/yubikey-val-server-php
Conflicts: ykval-synclib.php
This commit is contained in:
commit
060b35453d
@ -29,7 +29,7 @@ $myLog = new Log($logname);
|
|||||||
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
|
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
|
@ -64,7 +64,7 @@ function debug() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return eg. 2008-11-21T06:11:55Z0711
|
// Return eg. 2008-11-21T06:11:55Z0711
|
||||||
//
|
//
|
||||||
function getUTCTimeStamp() {
|
function getUTCTimeStamp() {
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
$tiny = substr(microtime(false), 2, 3);
|
$tiny = substr(microtime(false), 2, 3);
|
||||||
@ -72,7 +72,7 @@ function getUTCTimeStamp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# NOTE: When we evolve to using general DB-interface, this functinality
|
# NOTE: When we evolve to using general DB-interface, this functinality
|
||||||
# should be moved there.
|
# should be moved there.
|
||||||
function DbTimeToUnix($db_time)
|
function DbTimeToUnix($db_time)
|
||||||
{
|
{
|
||||||
$unix=strptime($db_time, '%F %H:%M:%S');
|
$unix=strptime($db_time, '%F %H:%M:%S');
|
||||||
@ -82,14 +82,14 @@ function DbTimeToUnix($db_time)
|
|||||||
function UnixToDbTime($unix)
|
function UnixToDbTime($unix)
|
||||||
{
|
{
|
||||||
return date('Y-m-d H:i:s', $unix);
|
return date('Y-m-d H:i:s', $unix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign a http query string in the array of key-value pairs
|
// Sign a http query string in the array of key-value pairs
|
||||||
// return b64 encoded hmac hash
|
// return b64 encoded hmac hash
|
||||||
function sign($a, $apiKey) {
|
function sign($a, $apiKey) {
|
||||||
ksort($a);
|
ksort($a);
|
||||||
$qs = urldecode(http_build_query($a));
|
$qs = urldecode(http_build_query($a));
|
||||||
|
|
||||||
// the TRUE at the end states we want the raw value, not hexadecimal form
|
// the TRUE at the end states we want the raw value, not hexadecimal form
|
||||||
$hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true);
|
$hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true);
|
||||||
$hmac = base64_encode($hmac);
|
$hmac = base64_encode($hmac);
|
||||||
@ -97,7 +97,7 @@ function sign($a, $apiKey) {
|
|||||||
debug('SIGN: ' . $qs . ' H=' . $hmac);
|
debug('SIGN: ' . $qs . ' H=' . $hmac);
|
||||||
|
|
||||||
return $hmac;
|
return $hmac;
|
||||||
|
|
||||||
} // sign an array of query string
|
} // sign an array of query string
|
||||||
|
|
||||||
function hex2b64 ($hex_str) {
|
function hex2b64 ($hex_str) {
|
||||||
@ -115,7 +115,7 @@ function modhex2b64 ($modhex_str) {
|
|||||||
// The request are sent asynchronously. Some of the URLs can fail
|
// The request are sent asynchronously. Some of the URLs can fail
|
||||||
// with unknown host, connection errors, or network timeout, but as
|
// with unknown host, connection errors, or network timeout, but as
|
||||||
// long as one of the URLs given work, data will be returned. If all
|
// long as one of the URLs given work, data will be returned. If all
|
||||||
// URLs fail, data from some URL that did not match parameter $match
|
// URLs fail, data from some URL that did not match parameter $match
|
||||||
// (defaults to ^OK) is returned, or if all URLs failed, false.
|
// (defaults to ^OK) is returned, or if all URLs failed, false.
|
||||||
function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
|
function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
|
||||||
$mh = curl_multi_init();
|
$mh = curl_multi_init();
|
||||||
@ -165,11 +165,11 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
|
|||||||
curl_close ($h);
|
curl_close ($h);
|
||||||
}
|
}
|
||||||
curl_multi_close ($mh);
|
curl_multi_close ($mh);
|
||||||
|
|
||||||
if ($ans_count==1) return $ans_arr[0];
|
if ($ans_count==1) return $ans_arr[0];
|
||||||
else return $ans_arr;
|
else return $ans_arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi_remove_handle ($mh, $info['handle']);
|
curl_multi_remove_handle ($mh, $info['handle']);
|
||||||
curl_close ($info['handle']);
|
curl_close ($info['handle']);
|
||||||
unset ($ch[$info['handle']]);
|
unset ($ch[$info['handle']]);
|
||||||
|
@ -8,13 +8,13 @@ $baseParams['__YKVAL_DB_PW__'] = 'lab';
|
|||||||
$baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
$baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
# For the validation server sync
|
# For the validation server sync
|
||||||
$baseParams['__YKVAL_SYNC_POOL__'] = array("http://api2.example.com/wsapi/2.0/sync",
|
$baseParams['__YKVAL_SYNC_POOL__'] = array("http://api2.example.com/wsapi/2.0/sync",
|
||||||
"http://api3.example.com/wsapi/2.0/sync",
|
"http://api3.example.com/wsapi/2.0/sync",
|
||||||
"http://api4.example.com/wsapi/2.0/sync");
|
"http://api4.example.com/wsapi/2.0/sync");
|
||||||
# An array of IP addresses allowed to issue sync requests
|
# An array of IP addresses allowed to issue sync requests
|
||||||
# NOTE: You must use IP addresses here.
|
# NOTE: You must use IP addresses here.
|
||||||
$baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array("1.2.3.4",
|
$baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array("1.2.3.4",
|
||||||
"2.3.4.5",
|
"2.3.4.5",
|
||||||
"3.4.5.6");
|
"3.4.5.6");
|
||||||
|
|
||||||
# Specify how often the sync daemon awakens
|
# Specify how often the sync daemon awakens
|
||||||
|
50
ykval-db.php
50
ykval-db.php
@ -18,7 +18,7 @@ class Db
|
|||||||
* @param string $user Database user
|
* @param string $user Database user
|
||||||
* @param string $pwd Database password
|
* @param string $pwd Database password
|
||||||
* @param string $name Database table name
|
* @param string $name Database table name
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function __construct($db_dsn, $db_username, $db_password, $db_options, $name='ykval-db')
|
public function __construct($db_dsn, $db_username, $db_password, $db_options, $name='ykval-db')
|
||||||
@ -39,7 +39,7 @@ class Db
|
|||||||
/**
|
/**
|
||||||
* function to convert Db timestamps to unixtime(s)
|
* function to convert Db timestamps to unixtime(s)
|
||||||
*
|
*
|
||||||
* @param string $updated Database timestamp
|
* @param string $updated Database timestamp
|
||||||
* @return int Timestamp in unixtime format
|
* @return int Timestamp in unixtime format
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -53,7 +53,7 @@ class Db
|
|||||||
/**
|
/**
|
||||||
* function to compute delta (s) between 2 Db timestamps
|
* function to compute delta (s) between 2 Db timestamps
|
||||||
*
|
*
|
||||||
* @param string $first Database timestamp 1
|
* @param string $first Database timestamp 1
|
||||||
* @param string $second Database timestamp 2
|
* @param string $second Database timestamp 2
|
||||||
* @return int Deltatime (s)
|
* @return int Deltatime (s)
|
||||||
*
|
*
|
||||||
@ -73,7 +73,7 @@ class Db
|
|||||||
{
|
{
|
||||||
$this->dbh=NULL;
|
$this->dbh=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function to check if database is connected
|
* function to check if database is connected
|
||||||
*
|
*
|
||||||
@ -109,7 +109,7 @@ class Db
|
|||||||
}
|
}
|
||||||
if($this->isConnected()) {
|
if($this->isConnected()) {
|
||||||
$this->myLog->log(LOG_DEBUG, 'DB query is: ' . $query);
|
$this->myLog->log(LOG_DEBUG, 'DB query is: ' . $query);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->result = $this->dbh->query($query);
|
$this->result = $this->dbh->query($query);
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
@ -154,8 +154,8 @@ class Db
|
|||||||
|
|
||||||
$query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "'";
|
$query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "'";
|
||||||
// Insert UPDATE statement at beginning
|
// Insert UPDATE statement at beginning
|
||||||
$query = "UPDATE " . $table . " SET " . $query;
|
$query = "UPDATE " . $table . " SET " . $query;
|
||||||
|
|
||||||
return $this->query($query, false);
|
return $this->query($query, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,11 +199,11 @@ class Db
|
|||||||
|
|
||||||
$query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "' and " . $condition;
|
$query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "' and " . $condition;
|
||||||
// Insert UPDATE statement at beginning
|
// Insert UPDATE statement at beginning
|
||||||
$query = "UPDATE " . $table . " SET " . $query;
|
$query = "UPDATE " . $table . " SET " . $query;
|
||||||
|
|
||||||
return $this->query($query, false);
|
return $this->query($query, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to update row in database based on a condition.
|
* Function to update row in database based on a condition.
|
||||||
@ -258,7 +258,7 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main function used to get rows from Db table.
|
* main function used to get rows from Db table.
|
||||||
*
|
*
|
||||||
* @param string $table Database table to update row in
|
* @param string $table Database table to update row in
|
||||||
* @param string $key Column to select rows by
|
* @param string $key Column to select rows by
|
||||||
@ -274,7 +274,7 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main function used to get rows by multiple key=>value pairs from Db table.
|
* main function used to get rows by multiple key=>value pairs from Db table.
|
||||||
*
|
*
|
||||||
* @param string $table Database table to update row in
|
* @param string $table Database table to update row in
|
||||||
* @param array $where Array with column=>values to select rows by
|
* @param array $where Array with column=>values to select rows by
|
||||||
@ -295,7 +295,7 @@ or false on failure.
|
|||||||
$query.= " *";
|
$query.= " *";
|
||||||
}
|
}
|
||||||
$query.= " FROM " . $table;
|
$query.= " FROM " . $table;
|
||||||
if ($where!=null){
|
if ($where!=null){
|
||||||
foreach ($where as $key=>$value) {
|
foreach ($where as $key=>$value) {
|
||||||
if ($key!=null) {
|
if ($key!=null) {
|
||||||
if ($value!=null) $match.= " ". $key . " = '" . $value . "' and";
|
if ($value!=null) $match.= " ". $key . " = '" . $value . "' and";
|
||||||
@ -311,12 +311,12 @@ or false on failure.
|
|||||||
|
|
||||||
$result = $this->query($query, true);
|
$result = $this->query($query, true);
|
||||||
if (!$result) return false;
|
if (!$result) return false;
|
||||||
|
|
||||||
if ($nr==1) {
|
if ($nr==1) {
|
||||||
$row = $result->fetch(PDO::FETCH_ASSOC);
|
$row = $result->fetch(PDO::FETCH_ASSOC);
|
||||||
$result->closeCursor();
|
$result->closeCursor();
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$collection=array();
|
$collection=array();
|
||||||
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
||||||
@ -329,7 +329,7 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main function used to delete rows by multiple key=>value pairs from Db table.
|
* main function used to delete rows by multiple key=>value pairs from Db table.
|
||||||
*
|
*
|
||||||
* @param string $table Database table to delete row in
|
* @param string $table Database table to delete row in
|
||||||
* @param array $where Array with column=>values to select rows by
|
* @param array $where Array with column=>values to select rows by
|
||||||
@ -343,7 +343,7 @@ or false on failure.
|
|||||||
{
|
{
|
||||||
$query="DELETE";
|
$query="DELETE";
|
||||||
$query.= " FROM " . $table;
|
$query.= " FROM " . $table;
|
||||||
if ($where!=null){
|
if ($where!=null){
|
||||||
$query.= " WHERE";
|
$query.= " WHERE";
|
||||||
foreach ($where as $key=>$value) {
|
foreach ($where as $key=>$value) {
|
||||||
$query.= " ". $key . " = '" . $value . "' and";
|
$query.= " ". $key . " = '" . $value . "' and";
|
||||||
@ -358,10 +358,10 @@ or false on failure.
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to do a custom query on database connection
|
* Function to do a custom query on database connection
|
||||||
*
|
*
|
||||||
* @param string $query Database query
|
* @param string $query Database query
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function customQuery($query)
|
public function customQuery($query)
|
||||||
@ -370,14 +370,14 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to do a custom query on database connection
|
* Function to do a custom query on database connection
|
||||||
*
|
*
|
||||||
* @return int number of rows affected by last statement or 0 if database connection is not functional.
|
* @return int number of rows affected by last statement or 0 if database connection is not functional.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function rowCount()
|
public function rowCount()
|
||||||
{
|
{
|
||||||
if($this->result) {
|
if($this->result) {
|
||||||
$count=count($this->result->fetchAll());
|
$count=count($this->result->fetchAll());
|
||||||
$this->result->closeCursor();
|
$this->result->closeCursor();
|
||||||
return $count;
|
return $count;
|
||||||
@ -387,8 +387,8 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* helper function used to get rows from Db table in reversed order.
|
* helper function used to get rows from Db table in reversed order.
|
||||||
* defaults to obtaining 1 row.
|
* defaults to obtaining 1 row.
|
||||||
*
|
*
|
||||||
* @param string $table Database table to update row in
|
* @param string $table Database table to update row in
|
||||||
* @param string $key Column to select rows by
|
* @param string $key Column to select rows by
|
||||||
@ -403,8 +403,8 @@ or false on failure.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* helper function used to get rows from Db table in standard order.
|
* helper function used to get rows from Db table in standard order.
|
||||||
* defaults to obtaining 1 row.
|
* defaults to obtaining 1 row.
|
||||||
*
|
*
|
||||||
* @param string $table Database table to update row in
|
* @param string $table Database table to update row in
|
||||||
* @param string $key Column to select rows by
|
* @param string $key Column to select rows by
|
||||||
@ -417,7 +417,7 @@ or false on failure.
|
|||||||
{
|
{
|
||||||
return Db::findBy($table, $key, $value, $nr);
|
return Db::findBy($table, $key, $value, $nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@ $myLog = new Log($logname);
|
|||||||
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
|
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
$myLog->log(LOG_WARNING, "Could not connect to database");
|
$myLog->log(LOG_WARNING, "Could not connect to database");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $db->customQuery("select id, active, created, secret, email, notes, otp from clients order by id");
|
$result = $db->customQuery("select id, active, created, secret, email, notes, otp from clients order by id");
|
||||||
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
||||||
|
@ -13,13 +13,13 @@ $myLog = new Log($logname);
|
|||||||
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
|
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
$myLog->log(LOG_WARNING, "Could not connect to database");
|
$myLog->log(LOG_WARNING, "Could not connect to database");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result=$db->customQuery("SELECT active, created, modified, yk_publicname, yk_counter, yk_use, yk_low, yk_high, nonce, notes FROM yubikeys ORDER BY yk_publicname");
|
$result=$db->customQuery("SELECT active, created, modified, yk_publicname, yk_counter, yk_use, yk_low, yk_high, nonce, notes FROM yubikeys ORDER BY yk_publicname");
|
||||||
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
while($row = $result->fetch(PDO::FETCH_ASSOC)){
|
||||||
|
@ -13,26 +13,26 @@ $myLog = new Log($logname);
|
|||||||
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
|
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
$myLog->log(LOG_WARNING, "Could not connect to database");
|
$myLog->log(LOG_WARNING, "Could not connect to database");
|
||||||
error_log("Could not connect to database");
|
error_log("Could not connect to database");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while ($res=fgetcsv(STDIN, 0, "\t")) {
|
while ($res=fgetcsv(STDIN, 0, "\t")) {
|
||||||
$params=array("id"=>$res[0],
|
$params=array("id"=>$res[0],
|
||||||
"active"=>$res[1],
|
"active"=>$res[1],
|
||||||
"created"=>$res[2],
|
"created"=>$res[2],
|
||||||
"secret"=>$res[3],
|
"secret"=>$res[3],
|
||||||
"email"=>$res[4],
|
"email"=>$res[4],
|
||||||
"notes"=>$res[5],
|
"notes"=>$res[5],
|
||||||
"otp"=>$res[6]);
|
"otp"=>$res[6]);
|
||||||
|
|
||||||
|
|
||||||
$query="SELECT * FROM clients WHERE id='" . $params['id'] . "'";
|
$query="SELECT * FROM clients WHERE id='" . $params['id'] . "'";
|
||||||
$result=$db->customQuery($query);
|
$result=$db->customQuery($query);
|
||||||
if(!$result->fetch(PDO::FETCH_ASSOC)) {
|
if(!$result->fetch(PDO::FETCH_ASSOC)) {
|
||||||
@ -46,7 +46,7 @@ while ($res=fgetcsv(STDIN, 0, "\t")) {
|
|||||||
"'" . $params['email'] . "'," .
|
"'" . $params['email'] . "'," .
|
||||||
"'" . $params['notes'] . "'," .
|
"'" . $params['notes'] . "'," .
|
||||||
"'" . $params['otp'] . "')";
|
"'" . $params['otp'] . "')";
|
||||||
|
|
||||||
if(!$db->customQuery($query)){
|
if(!$db->customQuery($query)){
|
||||||
$myLog->log(LOG_ERR, "Failed to insert new client with query " . $query);
|
$myLog->log(LOG_ERR, "Failed to insert new client with query " . $query);
|
||||||
error_log("Failed to insert new client with query " . $query);
|
error_log("Failed to insert new client with query " . $query);
|
||||||
|
@ -13,29 +13,29 @@ $myLog = new Log($logname);
|
|||||||
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
|
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
$myLog->log(LOG_WARNING, "Could not connect to database");
|
$myLog->log(LOG_WARNING, "Could not connect to database");
|
||||||
error_log("Could not connect to database");
|
error_log("Could not connect to database");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while ($res=fgetcsv(STDIN, 0, "\t")) {
|
while ($res=fgetcsv(STDIN, 0, "\t")) {
|
||||||
$params=array("active"=>$res[0],
|
$params=array("active"=>$res[0],
|
||||||
"created"=>$res[1],
|
"created"=>$res[1],
|
||||||
"modified"=>$res[2],
|
"modified"=>$res[2],
|
||||||
"yk_publicname"=>$res[3],
|
"yk_publicname"=>$res[3],
|
||||||
"yk_counter"=>$res[4],
|
"yk_counter"=>$res[4],
|
||||||
"yk_use"=>$res[5],
|
"yk_use"=>$res[5],
|
||||||
"yk_low"=>$res[6],
|
"yk_low"=>$res[6],
|
||||||
"yk_high"=>$res[7],
|
"yk_high"=>$res[7],
|
||||||
"nonce"=>$res[8],
|
"nonce"=>$res[8],
|
||||||
"notes"=>$res[9]);
|
"notes"=>$res[9]);
|
||||||
|
|
||||||
|
|
||||||
$query="SELECT * FROM yubikeys WHERE yk_publicname='" . $params['yk_publicname'] . "'";
|
$query="SELECT * FROM yubikeys WHERE yk_publicname='" . $params['yk_publicname'] . "'";
|
||||||
$result=$db->customQuery($query);
|
$result=$db->customQuery($query);
|
||||||
if($result->fetch(PDO::FETCH_ASSOC)) {
|
if($result->fetch(PDO::FETCH_ASSOC)) {
|
||||||
@ -52,13 +52,13 @@ while ($res=fgetcsv(STDIN, 0, "\t")) {
|
|||||||
"WHERE yk_publicname='" . $params['yk_publicname'] . "' AND " .
|
"WHERE yk_publicname='" . $params['yk_publicname'] . "' AND " .
|
||||||
"(".$params['yk_counter'].">yk_counter or (".$params['yk_counter']."=yk_counter and " .
|
"(".$params['yk_counter'].">yk_counter or (".$params['yk_counter']."=yk_counter and " .
|
||||||
$params['yk_use'] . ">yk_use))";
|
$params['yk_use'] . ">yk_use))";
|
||||||
|
|
||||||
if(!$db->customQuery($query)) {
|
if(!$db->customQuery($query)) {
|
||||||
$myLog->log(LOG_ERR, "Failed to update yk_publicname with query " . $query);
|
$myLog->log(LOG_ERR, "Failed to update yk_publicname with query " . $query);
|
||||||
error_log("Failed to update yk_publicname with query " . $query);
|
error_log("Failed to update yk_publicname with query " . $query);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// We didn't have the yk_publicname in database so we need to do insert instead
|
// We didn't have the yk_publicname in database so we need to do insert instead
|
||||||
$query="INSERT INTO yubikeys " .
|
$query="INSERT INTO yubikeys " .
|
||||||
@ -73,7 +73,7 @@ while ($res=fgetcsv(STDIN, 0, "\t")) {
|
|||||||
"'" . $params['yk_high'] . "'," .
|
"'" . $params['yk_high'] . "'," .
|
||||||
"'" . $params['nonce'] . "'," .
|
"'" . $params['nonce'] . "'," .
|
||||||
"'" . $params['notes'] . "')";
|
"'" . $params['notes'] . "')";
|
||||||
|
|
||||||
if(!$db->customQuery($query)){
|
if(!$db->customQuery($query)){
|
||||||
$myLog->log(LOG_ERR, "Failed to insert new yk_publicname with query " . $query);
|
$myLog->log(LOG_ERR, "Failed to insert new yk_publicname with query " . $query);
|
||||||
error_log("Failed to insert new yk_publicname with query " . $query);
|
error_log("Failed to insert new yk_publicname with query " . $query);
|
||||||
|
@ -2,29 +2,29 @@
|
|||||||
|
|
||||||
class Log
|
class Log
|
||||||
{
|
{
|
||||||
|
|
||||||
function __construct($name='ykval')
|
function __construct($name='ykval')
|
||||||
{
|
{
|
||||||
$this->name=$name;
|
$this->name=$name;
|
||||||
$this->fields=array();
|
$this->fields=array();
|
||||||
|
|
||||||
$this->LOG_LEVELS = array(LOG_EMERG=>'LOG_EMERG',
|
$this->LOG_LEVELS = array(LOG_EMERG=>'LOG_EMERG',
|
||||||
LOG_ALERT=>'LOG_ALERT',
|
LOG_ALERT=>'LOG_ALERT',
|
||||||
LOG_CRIT=>'LOG_CRIT',
|
LOG_CRIT=>'LOG_CRIT',
|
||||||
LOG_ERR=>'LOG_ERR',
|
LOG_ERR=>'LOG_ERR',
|
||||||
LOG_WARNING=>'LOG_WARNING',
|
LOG_WARNING=>'LOG_WARNING',
|
||||||
LOG_NOTICE=>'LOG_NOTICE',
|
LOG_NOTICE=>'LOG_NOTICE',
|
||||||
LOG_INFO=>'LOG_INFO',
|
LOG_INFO=>'LOG_INFO',
|
||||||
LOG_DEBUG=>'LOG_DEBUG');
|
LOG_DEBUG=>'LOG_DEBUG');
|
||||||
|
|
||||||
openlog("ykval", LOG_PID, LOG_LOCAL0);
|
openlog("ykval", LOG_PID, LOG_LOCAL0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addField($name, $value)
|
function addField($name, $value)
|
||||||
{
|
{
|
||||||
$this->fields[$name]=$value;
|
$this->fields[$name]=$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function log($priority, $message, $arr=null){
|
function log($priority, $message, $arr=null){
|
||||||
if (is_array($arr)) {
|
if (is_array($arr)) {
|
||||||
foreach($arr as $key=>$value){
|
foreach($arr as $key=>$value){
|
||||||
@ -36,13 +36,13 @@ class Log
|
|||||||
foreach ($this->fields as $field=>$value) {
|
foreach ($this->fields as $field=>$value) {
|
||||||
$msg_fields .= "[" . $value . "] ";
|
$msg_fields .= "[" . $value . "] ";
|
||||||
}
|
}
|
||||||
syslog($priority,
|
syslog($priority,
|
||||||
$this->LOG_LEVELS[$priority] . ':' .
|
$this->LOG_LEVELS[$priority] . ':' .
|
||||||
$this->name . ':' .
|
$this->name . ':' .
|
||||||
$msg_fields .
|
$msg_fields .
|
||||||
$message);
|
$message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
set_include_path(get_include_path() . PATH_SEPARATOR .
|
set_include_path(get_include_path() . PATH_SEPARATOR .
|
||||||
"/etc/ykval:/usr/share/ykval");
|
"/etc/ykval:/usr/share/ykval");
|
||||||
|
|
||||||
require_once 'ykval-synclib.php';
|
|
||||||
require_once 'ykval-config.php';
|
require_once 'ykval-config.php';
|
||||||
|
require_once 'ykval-synclib.php';
|
||||||
require_once 'ykval-log.php';
|
require_once 'ykval-log.php';
|
||||||
|
|
||||||
if ($argc==2 && strcmp($argv[1], "autoconf") == 0) {
|
if ($argc==2 && strcmp($argv[1], "autoconf") == 0) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
header("content-type: text/plain");
|
header("content-type: text/plain");
|
||||||
|
|
||||||
|
@ -12,18 +12,18 @@ if ($argc==2 && strcmp($argv[1], "install")!=0) {
|
|||||||
set_include_path(get_include_path() . PATH_SEPARATOR . $argv[1]);
|
set_include_path(get_include_path() . PATH_SEPARATOR . $argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once "System/Daemon.php";
|
require_once "System/Daemon.php";
|
||||||
|
|
||||||
$appname="ykval-queue";
|
$appname="ykval-queue";
|
||||||
|
|
||||||
System_Daemon::setOption("appName", $appname);
|
System_Daemon::setOption("appName", $appname);
|
||||||
System_Daemon::setOption("appDescription", "Yubico val-server sync daemon");
|
System_Daemon::setOption("appDescription", "Yubico val-server sync daemon");
|
||||||
System_Daemon::setOption("authorName", "olov@yubico.com");
|
System_Daemon::setOption("authorName", "olov@yubico.com");
|
||||||
System_Daemon::setOption("authorEmail", "olov@yubico.com");
|
System_Daemon::setOption("authorEmail", "olov@yubico.com");
|
||||||
|
|
||||||
if ($argc==2 && strcmp($argv[1], "install")==0) {
|
if ($argc==2 && strcmp($argv[1], "install")==0) {
|
||||||
$autostart_path = System_Daemon::writeAutoRun();
|
$autostart_path = System_Daemon::writeAutoRun();
|
||||||
if ($autostart_path!=1){
|
if ($autostart_path!=1){
|
||||||
echo "Successfully created start script at " . $autostart_path . "\n";
|
echo "Successfully created start script at " . $autostart_path . "\n";
|
||||||
echo "To start daemon use: /etc/init.d/".$appname." start\n";
|
echo "To start daemon use: /etc/init.d/".$appname." start\n";
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +46,7 @@ $sl = new SyncLib('ykval-queue:synclib');
|
|||||||
|
|
||||||
$res==0;
|
$res==0;
|
||||||
while ($res==0) {
|
while ($res==0) {
|
||||||
$sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'],
|
$sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'],
|
||||||
$baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']);
|
$baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']);
|
||||||
$res=sleep($baseParams['__YKVAL_SYNC_INTERVAL__']);
|
$res=sleep($baseParams['__YKVAL_SYNC_INTERVAL__']);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ if ($do != "enable" && $do != "disable") {
|
|||||||
$db = new Db($baseParams['__YKVAL_DB_DSN__'],
|
$db = new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
'ykval-revoke:db');
|
'ykval-revoke:db');
|
||||||
if (!$db->connect()) {
|
if (!$db->connect()) {
|
||||||
logdie("ERROR Database connect error");
|
logdie("ERROR Database connect error");
|
||||||
|
@ -20,7 +20,7 @@ if (! $sync->isConnected()) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Verify that request comes from valid server
|
# Verify that request comes from valid server
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ $myLog->addField('otp', $syncParams['otp']);
|
|||||||
$sync->addField('otp', $syncParams['otp']);
|
$sync->addField('otp', $syncParams['otp']);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Verify correctness of input parameters
|
# Verify correctness of input parameters
|
||||||
#
|
#
|
||||||
|
|
||||||
foreach (array('modified') as $param) {
|
foreach (array('modified') as $param) {
|
||||||
@ -106,27 +106,27 @@ foreach (array('yk_counter', 'yk_use', 'yk_high', 'yk_low') as $param) {
|
|||||||
$yk_publicname = $syncParams['yk_publicname'];
|
$yk_publicname = $syncParams['yk_publicname'];
|
||||||
$localParams = $sync->getLocalParams($yk_publicname);
|
$localParams = $sync->getLocalParams($yk_publicname);
|
||||||
if (!$localParams) {
|
if (!$localParams) {
|
||||||
$myLog->log(LOG_NOTICE, 'Invalid Yubikey ' . $yk_publicname);
|
$myLog->log(LOG_NOTICE, 'Refusing sync of invalid Yubikey ' . $yk_publicname);
|
||||||
sendResp(S_BACKEND_ERROR, $apiKey);
|
sendResp(S_BACKEND_ERROR, $apiKey);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($localParams['active'] != 1) {
|
if ($localParams['active'] != 1) {
|
||||||
$myLog->log(LOG_NOTICE, 'De-activated Yubikey ' . $yk_publicname);
|
$myLog->log(LOG_NOTICE, 'Refusing sync of de-activated Yubikey ' . $yk_publicname);
|
||||||
sendResp(S_BAD_OTP, $apiKey);
|
sendResp(S_BAD_OTP, $apiKey);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Conditional update local database */
|
/* Conditional update local database */
|
||||||
$sync->updateDbCounters($syncParams);
|
$sync->updateDbCounters($syncParams);
|
||||||
|
|
||||||
$myLog->log(LOG_DEBUG, 'Local params ' , $localParams);
|
$myLog->log(LOG_DEBUG, 'Local params ' , $localParams);
|
||||||
$myLog->log(LOG_DEBUG, 'Sync request params ' , $syncParams);
|
$myLog->log(LOG_DEBUG, 'Sync request params ' , $syncParams);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Compare sync and local counters and generate warnings according to
|
# Compare sync and local counters and generate warnings according to
|
||||||
#
|
#
|
||||||
# http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol
|
# http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ if ($sync->countersEqual($localParams, $syncParams)) {
|
|||||||
$syncParams['nonce']==$localParams['nonce']) {
|
$syncParams['nonce']==$localParams['nonce']) {
|
||||||
$myLog->log(LOG_NOTICE, 'Sync request unnessecarily sent');
|
$myLog->log(LOG_NOTICE, 'Sync request unnessecarily sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($syncParams['modified']!=$localParams['modified'] &&
|
if ($syncParams['modified']!=$localParams['modified'] &&
|
||||||
$syncParams['nonce']==$localParams['nonce']) {
|
$syncParams['nonce']==$localParams['nonce']) {
|
||||||
$deltaModified = $syncParams['modified'] - $localParams['modified'];
|
$deltaModified = $syncParams['modified'] - $localParams['modified'];
|
||||||
@ -156,7 +156,7 @@ if ($sync->countersEqual($localParams, $syncParams)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$extra=array('modified'=>$localParams['modified'],
|
$extra=array('modified'=>$localParams['modified'],
|
||||||
'nonce'=>$localParams['nonce'],
|
'nonce'=>$localParams['nonce'],
|
||||||
'yk_publicname'=>$yk_publicname,
|
'yk_publicname'=>$yk_publicname,
|
||||||
|
@ -19,10 +19,10 @@ class SyncLib
|
|||||||
$this->db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
$this->db=new Db($baseParams['__YKVAL_DB_DSN__'],
|
||||||
$baseParams['__YKVAL_DB_USER__'],
|
$baseParams['__YKVAL_DB_USER__'],
|
||||||
$baseParams['__YKVAL_DB_PW__'],
|
$baseParams['__YKVAL_DB_PW__'],
|
||||||
$baseParams['__YKVAL_DB_OPTIONS__'],
|
$baseParams['__YKVAL_DB_OPTIONS__'],
|
||||||
$logname . ':db');
|
$logname . ':db');
|
||||||
$this->isConnected=$this->db->connect();
|
$this->isConnected=$this->db->connect();
|
||||||
$this->server_nonce=md5(uniqid(rand()));
|
$this->server_nonce=md5(uniqid(rand()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class SyncLib
|
|||||||
$this->db->addField($name, $value);
|
$this->db->addField($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isConnected()
|
function isConnected()
|
||||||
{
|
{
|
||||||
return $this->isConnected;
|
return $this->isConnected;
|
||||||
}
|
}
|
||||||
@ -42,11 +42,11 @@ class SyncLib
|
|||||||
$unix=strptime($db_time, '%F %H:%M:%S');
|
$unix=strptime($db_time, '%F %H:%M:%S');
|
||||||
return mktime($unix[tm_hour], $unix[tm_min], $unix[tm_sec], $unix[tm_mon]+1, $unix[tm_mday], $unix[tm_year]+1900);
|
return mktime($unix[tm_hour], $unix[tm_min], $unix[tm_sec], $unix[tm_mon]+1, $unix[tm_mday], $unix[tm_year]+1900);
|
||||||
}
|
}
|
||||||
|
|
||||||
function UnixToDbTime($unix)
|
function UnixToDbTime($unix)
|
||||||
{
|
{
|
||||||
return date('Y-m-d H:i:s', $unix);
|
return date('Y-m-d H:i:s', $unix);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getServer($index)
|
function getServer($index)
|
||||||
{
|
{
|
||||||
@ -91,11 +91,11 @@ class SyncLib
|
|||||||
return $out[0];
|
return $out[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function localParamsFromInfoString($info)
|
public function localParamsFromInfoString($info)
|
||||||
{
|
{
|
||||||
$out=explode(",", $info);
|
$out=explode(",", $info);
|
||||||
parse_str($out[1], $params);
|
parse_str($out[1], $params);
|
||||||
return array('yk_counter'=>$params['local_counter'],
|
return array('yk_counter'=>$params['local_counter'],
|
||||||
'yk_use'=>$params['local_use']);
|
'yk_use'=>$params['local_use']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,14 +105,14 @@ class SyncLib
|
|||||||
$info=$this->createInfoString($otpParams, $localParams);
|
$info=$this->createInfoString($otpParams, $localParams);
|
||||||
$this->otpParams = $otpParams;
|
$this->otpParams = $otpParams;
|
||||||
$this->localParams = $localParams;
|
$this->localParams = $localParams;
|
||||||
|
|
||||||
$queued=time();
|
$queued=time();
|
||||||
$res=True;
|
$res=True;
|
||||||
foreach ($this->syncServers as $server) {
|
foreach ($this->syncServers as $server) {
|
||||||
|
|
||||||
if(! $this->db->save('queue', array('queued'=>$queued,
|
if(! $this->db->save('queue', array('queued'=>$queued,
|
||||||
'modified'=>$otpParams['modified'],
|
'modified'=>$otpParams['modified'],
|
||||||
'otp'=>$otpParams['otp'],
|
'otp'=>$otpParams['otp'],
|
||||||
'server'=>$server,
|
'server'=>$server,
|
||||||
'server_nonce'=>$this->server_nonce,
|
'server_nonce'=>$this->server_nonce,
|
||||||
'info'=>$info))) $res=False;
|
'info'=>$info))) $res=False;
|
||||||
@ -132,9 +132,9 @@ class SyncLib
|
|||||||
if ($params) $logMsg .= ' modified=' . $params['modified'] .
|
if ($params) $logMsg .= ' modified=' . $params['modified'] .
|
||||||
' nonce=' . $params['nonce'] .
|
' nonce=' . $params['nonce'] .
|
||||||
' yk_publicname=' . $params['yk_publicname'] .
|
' yk_publicname=' . $params['yk_publicname'] .
|
||||||
' yk_counter=' . $params['yk_counter'] .
|
' yk_counter=' . $params['yk_counter'] .
|
||||||
' yk_use=' . $params['yk_use'] .
|
' yk_use=' . $params['yk_use'] .
|
||||||
' yk_high=' . $params['yk_high'] .
|
' yk_high=' . $params['yk_high'] .
|
||||||
' yk_low=' . $params['yk_low'];
|
' yk_low=' . $params['yk_low'];
|
||||||
if ($this->myLog) $this->myLog->log($priority, $logMsg);
|
if ($this->myLog) $this->myLog->log($priority, $logMsg);
|
||||||
else error_log("Warning: myLog uninitialized in ykval-synclib.php. Message is " . $logMsg);
|
else error_log("Warning: myLog uninitialized in ykval-synclib.php. Message is " . $logMsg);
|
||||||
@ -147,7 +147,7 @@ class SyncLib
|
|||||||
|
|
||||||
if (!$res) {
|
if (!$res) {
|
||||||
$this->log(LOG_NOTICE, 'Discovered new identity ' . $yk_publicname);
|
$this->log(LOG_NOTICE, 'Discovered new identity ' . $yk_publicname);
|
||||||
$this->db->save('yubikeys', array('active'=>1,
|
$this->db->save('yubikeys', array('active'=>1,
|
||||||
'created'=>time(),
|
'created'=>time(),
|
||||||
'modified'=>-1,
|
'modified'=>-1,
|
||||||
'yk_publicname'=>$yk_publicname,
|
'yk_publicname'=>$yk_publicname,
|
||||||
@ -164,11 +164,11 @@ class SyncLib
|
|||||||
'nonce'=>$res['nonce'],
|
'nonce'=>$res['nonce'],
|
||||||
'active'=>$res['active'],
|
'active'=>$res['active'],
|
||||||
'yk_publicname'=>$yk_publicname,
|
'yk_publicname'=>$yk_publicname,
|
||||||
'yk_counter'=>$res['yk_counter'],
|
'yk_counter'=>$res['yk_counter'],
|
||||||
'yk_use'=>$res['yk_use'],
|
'yk_use'=>$res['yk_use'],
|
||||||
'yk_high'=>$res['yk_high'],
|
'yk_high'=>$res['yk_high'],
|
||||||
'yk_low'=>$res['yk_low']);
|
'yk_low'=>$res['yk_low']);
|
||||||
|
|
||||||
$this->log(LOG_INFO, "yubikey found in db ", $localParams);
|
$this->log(LOG_INFO, "yubikey found in db ", $localParams);
|
||||||
return $localParams;
|
return $localParams;
|
||||||
} else {
|
} else {
|
||||||
@ -230,18 +230,18 @@ class SyncLib
|
|||||||
if (isset($params['yk_publicname'])) {
|
if (isset($params['yk_publicname'])) {
|
||||||
$condition='('.$params['yk_counter'].'>yk_counter or ('.$params['yk_counter'].'=yk_counter and ' .
|
$condition='('.$params['yk_counter'].'>yk_counter or ('.$params['yk_counter'].'=yk_counter and ' .
|
||||||
$params['yk_use'] . '>yk_use))' ;
|
$params['yk_use'] . '>yk_use))' ;
|
||||||
if(! $this->db->conditionalUpdateBy('yubikeys', 'yk_publicname', $params['yk_publicname'],
|
if(! $this->db->conditionalUpdateBy('yubikeys', 'yk_publicname', $params['yk_publicname'],
|
||||||
array('modified'=>$params['modified'],
|
array('modified'=>$params['modified'],
|
||||||
'yk_counter'=>$params['yk_counter'],
|
'yk_counter'=>$params['yk_counter'],
|
||||||
'yk_use'=>$params['yk_use'],
|
'yk_use'=>$params['yk_use'],
|
||||||
'yk_low'=>$params['yk_low'],
|
'yk_low'=>$params['yk_low'],
|
||||||
'yk_high'=>$params['yk_high'],
|
'yk_high'=>$params['yk_high'],
|
||||||
'nonce'=>$params['nonce']),
|
'nonce'=>$params['nonce']),
|
||||||
$condition))
|
$condition))
|
||||||
{
|
{
|
||||||
$this->log(LOG_CRIT, 'failed to update internal DB with new counters');
|
$this->log(LOG_CRIT, 'failed to update internal DB with new counters');
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if ($this->db->rowCount()>0) $this->log(LOG_INFO, "updated database ", $params);
|
if ($this->db->rowCount()>0) $this->log(LOG_INFO, "updated database ", $params);
|
||||||
else $this->log(LOG_INFO, 'database not updated', $params);
|
else $this->log(LOG_INFO, 'database not updated', $params);
|
||||||
@ -249,7 +249,7 @@ class SyncLib
|
|||||||
}
|
}
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countersHigherThan($p1, $p2)
|
public function countersHigherThan($p1, $p2)
|
||||||
{
|
{
|
||||||
if ($p1['yk_counter'] > $p2['yk_counter'] ||
|
if ($p1['yk_counter'] > $p2['yk_counter'] ||
|
||||||
@ -257,7 +257,7 @@ class SyncLib
|
|||||||
$p1['yk_use'] > $p2['yk_use'])) return true;
|
$p1['yk_use'] > $p2['yk_use'])) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countersHigherThanOrEqual($p1, $p2)
|
public function countersHigherThanOrEqual($p1, $p2)
|
||||||
{
|
{
|
||||||
if ($p1['yk_counter'] > $p2['yk_counter'] ||
|
if ($p1['yk_counter'] > $p2['yk_counter'] ||
|
||||||
@ -270,17 +270,17 @@ class SyncLib
|
|||||||
return ($p1['yk_counter']==$p2['yk_counter']) && ($p1['yk_use']==$p2['yk_use']);
|
return ($p1['yk_counter']==$p2['yk_counter']) && ($p1['yk_use']==$p2['yk_use']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteQueueEntry($answer)
|
public function deleteQueueEntry($answer)
|
||||||
{
|
{
|
||||||
|
|
||||||
preg_match('/url=(.*)\?/', $answer, $out);
|
preg_match('/url=(.*)\?/', $answer, $out);
|
||||||
$server=$out[1];
|
$server=$out[1];
|
||||||
$this->log(LOG_INFO, "deleting server=" . $server .
|
$this->log(LOG_INFO, "deleting server=" . $server .
|
||||||
" modified=" . $this->otpParams['modified'] .
|
" modified=" . $this->otpParams['modified'] .
|
||||||
" server_nonce=" . $this->server_nonce);
|
" server_nonce=" . $this->server_nonce);
|
||||||
$this->db->deleteByMultiple('queue',
|
$this->db->deleteByMultiple('queue',
|
||||||
array("modified"=>$this->otpParams['modified'],
|
array("modified"=>$this->otpParams['modified'],
|
||||||
"server_nonce"=>$this->server_nonce,
|
"server_nonce"=>$this->server_nonce,
|
||||||
'server'=>$server));
|
'server'=>$server));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,20 +290,20 @@ class SyncLib
|
|||||||
/* Loop over all unique servers in queue */
|
/* Loop over all unique servers in queue */
|
||||||
$queued_limit=time()-$older_than;
|
$queued_limit=time()-$older_than;
|
||||||
$res=$this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null");
|
$res=$this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null");
|
||||||
|
|
||||||
foreach ($res as $my_server) {
|
foreach ($res as $my_server) {
|
||||||
$this->log(LOG_INFO, "Sending queue request to server on server " . $my_server['server']);
|
$this->log(LOG_INFO, "Sending queue request to server on server " . $my_server['server']);
|
||||||
$res=$this->db->customQuery("select * from queue WHERE (queued < " . $queued_limit . " or queued is null) and server='" . $my_server['server'] . "'");
|
$res=$this->db->customQuery("select * from queue WHERE (queued < " . $queued_limit . " or queued is null) and server='" . $my_server['server'] . "'");
|
||||||
|
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
|
|
||||||
while ($entry=$res->fetch(PDO::FETCH_ASSOC)) {
|
while ($entry=$res->fetch(PDO::FETCH_ASSOC)) {
|
||||||
$this->log(LOG_INFO, "server=" . $entry['server'] . " , info=" . $entry['info']);
|
$this->log(LOG_INFO, "server=" . $entry['server'] . " , info=" . $entry['info']);
|
||||||
$url=$entry['server'] .
|
$url=$entry['server'] .
|
||||||
"?otp=" . $entry['otp'] .
|
"?otp=" . $entry['otp'] .
|
||||||
"&modified=" . $entry['modified'] .
|
"&modified=" . $entry['modified'] .
|
||||||
"&" . $this->otpPartFromInfoString($entry['info']);
|
"&" . $this->otpPartFromInfoString($entry['info']);
|
||||||
|
|
||||||
|
|
||||||
/* Send out sync request */
|
/* Send out sync request */
|
||||||
$this->log(LOG_DEBUG, 'url is ' . $url);
|
$this->log(LOG_DEBUG, 'url is ' . $url);
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
@ -313,101 +313,103 @@ class SyncLib
|
|||||||
curl_setopt($ch, CURLOPT_FAILONERROR, true);
|
curl_setopt($ch, CURLOPT_FAILONERROR, true);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if ($response==False) {
|
if ($response==False) {
|
||||||
$this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $my_server['server']);
|
$this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $my_server['server']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match("/status=OK/", $response)) {
|
if (preg_match("/status=OK/", $response)) {
|
||||||
$resParams=$this->parseParamsFromMultiLineString($response);
|
$resParams=$this->parseParamsFromMultiLineString($response);
|
||||||
$this->log(LOG_DEBUG, "response contains ", $resParams);
|
$this->log(LOG_DEBUG, "response contains ", $resParams);
|
||||||
|
|
||||||
/* Update database counters */
|
/* Update database counters */
|
||||||
$this->updateDbCounters($resParams);
|
$this->updateDbCounters($resParams);
|
||||||
|
|
||||||
/* Retrieve info from entry info string */
|
/* Retrieve info from entry info string */
|
||||||
|
|
||||||
$validationParams=$this->localParamsFromInfoString($entry['info']);
|
$validationParams=$this->localParamsFromInfoString($entry['info']);
|
||||||
$otpParams=$this->otpParamsFromInfoString($entry['info']);
|
$otpParams=$this->otpParamsFromInfoString($entry['info']);
|
||||||
$localParams=$this->getLocalParams($otpParams['yk_publicname']);
|
$localParams=$this->getLocalParams($otpParams['yk_publicname']);
|
||||||
|
|
||||||
$this->log(LOG_DEBUG, "validation params: ", $validationParams);
|
$this->log(LOG_DEBUG, "validation params: ", $validationParams);
|
||||||
$this->log(LOG_DEBUG, "OTP params: ", $otpParams);
|
$this->log(LOG_DEBUG, "OTP params: ", $otpParams);
|
||||||
|
|
||||||
/* Check for warnings */
|
/* Check for warnings */
|
||||||
|
|
||||||
if ($this->countersHigherThan($validationParams, $resParams)) {
|
if ($this->countersHigherThan($validationParams, $resParams)) {
|
||||||
$this->log(LOG_NOTICE, "Remote server out of sync compared to counters at validation request time. ");
|
$this->log(LOG_NOTICE, "Remote server out of sync compared to counters at validation request time. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($resParams, $validationParams)) {
|
if ($this->countersHigherThan($resParams, $validationParams)) {
|
||||||
$this->log(LOG_NOTICE, "Local server out of sync compared to counters at validation request time. ");
|
$this->log(LOG_NOTICE, "Local server out of sync compared to counters at validation request time. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($localParams, $resParams)) {
|
if ($this->countersHigherThan($localParams, $resParams)) {
|
||||||
$this->log(LOG_WARNING, "Remote server out of sync compared to current local counters. ");
|
$this->log(LOG_WARNING, "Remote server out of sync compared to current local counters. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($resParams, $localParams)) {
|
if ($this->countersHigherThan($resParams, $localParams)) {
|
||||||
$this->log(LOG_WARNING, "Local server out of sync compared to current local counters. Local server updated. ");
|
$this->log(LOG_WARNING, "Local server out of sync compared to current local counters. Local server updated. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($resParams, $otpParams)) {
|
if ($this->countersHigherThan($resParams, $otpParams)) {
|
||||||
$this->log(LOG_ERR, "Remote server has higher counters than OTP. This response would have marked the OTP as invalid. ");
|
$this->log(LOG_ERR, "Remote server has higher counters than OTP. This response would have marked the OTP as invalid. ");
|
||||||
}
|
}
|
||||||
elseif ($this->countersEqual($resParams, $otpParams) &&
|
elseif ($this->countersEqual($resParams, $otpParams) &&
|
||||||
$resParams['nonce']!=$otpParams['nonce']) {
|
$resParams['nonce']!=$otpParams['nonce']) {
|
||||||
$this->log(LOG_ERR, "Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid.");
|
$this->log(LOG_ERR, "Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deletion */
|
/* Deletion */
|
||||||
$this->log(LOG_INFO, 'deleting queue entry with modified=' . $entry['modified'] .
|
$this->log(LOG_INFO, 'deleting queue entry with modified=' . $entry['modified'] .
|
||||||
' server_nonce=' . $entry['server_nonce'] .
|
' server_nonce=' . $entry['server_nonce'] .
|
||||||
' server=' . $entry['server']);
|
' server=' . $entry['server']);
|
||||||
$this->db->deleteByMultiple('queue',
|
$this->db->deleteByMultiple('queue',
|
||||||
array("modified"=>$entry['modified'],
|
array("modified"=>$entry['modified'],
|
||||||
"server_nonce"=>$entry['server_nonce'],
|
"server_nonce"=>$entry['server_nonce'],
|
||||||
'server'=>$entry['server']));
|
'server'=>$entry['server']));
|
||||||
|
} else {
|
||||||
|
$this->log(LOG_ERR, "Remote server refused our sync request. Check remote server logs.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* End of loop over each queue entry for a server */
|
} /* End of loop over each queue entry for a server */
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
$res->closeCursor();
|
$res->closeCursor();
|
||||||
} /* End of loop over each distinct server in queue */
|
} /* End of loop over each distinct server in queue */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sync($ans_req, $timeout=1)
|
public function sync($ans_req, $timeout=1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Construct URLs
|
Construct URLs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$urls=array();
|
$urls=array();
|
||||||
$res=$this->db->findByMultiple('queue', array("modified"=>$this->otpParams['modified'], "server_nonce"=>$this->server_nonce));
|
$res=$this->db->findByMultiple('queue', array("modified"=>$this->otpParams['modified'], "server_nonce"=>$this->server_nonce));
|
||||||
foreach ($res as $row) {
|
foreach ($res as $row) {
|
||||||
$urls[]=$row['server'] .
|
$urls[]=$row['server'] .
|
||||||
"?otp=" . $row['otp'] .
|
"?otp=" . $row['otp'] .
|
||||||
"&modified=" . $row['modified'] .
|
"&modified=" . $row['modified'] .
|
||||||
"&" . $this->otpPartFromInfoString($row['info']);
|
"&" . $this->otpPartFromInfoString($row['info']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Send out requests
|
Send out requests
|
||||||
*/
|
*/
|
||||||
$ans_arr=$this->retrieveURLasync($urls, $ans_req, $timeout);
|
$ans_arr=$this->retrieveURLasync($urls, $ans_req, $timeout);
|
||||||
|
|
||||||
if (!is_array($ans_arr)) {
|
if (!is_array($ans_arr)) {
|
||||||
$this->log(LOG_WARNING, 'No responses from validation server pool');
|
$this->log(LOG_WARNING, 'No responses from validation server pool');
|
||||||
$ans_arr=array();
|
$ans_arr=array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse responses
|
Parse responses
|
||||||
*/
|
*/
|
||||||
$localParams = $this->localParams;
|
$localParams = $this->localParams;
|
||||||
|
|
||||||
$this->answers = count($ans_arr);
|
$this->answers = count($ans_arr);
|
||||||
$this->valid_answers = 0;
|
$this->valid_answers = 0;
|
||||||
foreach ($ans_arr as $answer){
|
foreach ($ans_arr as $answer){
|
||||||
@ -418,71 +420,71 @@ class SyncLib
|
|||||||
$this->log(LOG_DEBUG, "OTP contains " , $this->otpParams);
|
$this->log(LOG_DEBUG, "OTP contains " , $this->otpParams);
|
||||||
|
|
||||||
/* Update internal DB (conditional) */
|
/* Update internal DB (conditional) */
|
||||||
|
|
||||||
$this->updateDbCounters($resParams);
|
$this->updateDbCounters($resParams);
|
||||||
|
|
||||||
|
|
||||||
/* Check for warnings
|
/* Check for warnings
|
||||||
|
|
||||||
See http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol
|
See http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol
|
||||||
|
|
||||||
NOTE: We use localParams for validationParams comparison since they are actually the
|
NOTE: We use localParams for validationParams comparison since they are actually the
|
||||||
same in this situation and we have them at hand.
|
same in this situation and we have them at hand.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ($this->countersHigherThan($localParams, $resParams)) {
|
if ($this->countersHigherThan($localParams, $resParams)) {
|
||||||
$this->log(LOG_NOTICE, "Remote server out of sync");
|
$this->log(LOG_NOTICE, "Remote server out of sync");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($resParams, $localParams)) {
|
if ($this->countersHigherThan($resParams, $localParams)) {
|
||||||
$this->log(LOG_NOTICE, "Local server out of sync");
|
$this->log(LOG_NOTICE, "Local server out of sync");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->CountersEqual($resParams, $localParams) &&
|
if ($this->CountersEqual($resParams, $localParams) &&
|
||||||
$resParams['nonce']!=$localParams['nonce']) {
|
$resParams['nonce']!=$localParams['nonce']) {
|
||||||
$this->log(LOG_NOTICE, "Servers out of sync. Nonce differs. ");
|
$this->log(LOG_NOTICE, "Servers out of sync. Nonce differs. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($this->CountersEqual($resParams, $localParams) &&
|
if ($this->CountersEqual($resParams, $localParams) &&
|
||||||
$resParams['modified']!=$localParams['modified']) {
|
$resParams['modified']!=$localParams['modified']) {
|
||||||
$this->log(LOG_NOTICE, "Servers out of sync. Modified differs. ");
|
$this->log(LOG_NOTICE, "Servers out of sync. Modified differs. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->countersHigherThan($resParams, $this->otpParams)){
|
if ($this->countersHigherThan($resParams, $this->otpParams)){
|
||||||
$this->log(LOG_WARNING, 'OTP is replayed. Sync response counters higher than OTP counters.');
|
$this->log(LOG_WARNING, 'OTP is replayed. Sync response counters higher than OTP counters.');
|
||||||
}
|
}
|
||||||
elseif ($this->countersEqual($resParams, $this->otpParams) &&
|
elseif ($this->countersEqual($resParams, $this->otpParams) &&
|
||||||
$resParams['nonce']!=$this->otpParams['nonce']) {
|
$resParams['nonce']!=$this->otpParams['nonce']) {
|
||||||
$this->log(LOG_WARNING, 'OTP is replayed. Sync response counters equal to OTP counters and nonce differs.');
|
$this->log(LOG_WARNING, 'OTP is replayed. Sync response counters equal to OTP counters and nonce differs.');
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* The answer is ok since a REPLAY was not indicated */
|
/* The answer is ok since a REPLAY was not indicated */
|
||||||
|
|
||||||
$this->valid_answers++;
|
$this->valid_answers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Delete entry from table */
|
/* Delete entry from table */
|
||||||
$this->deleteQueueEntry($answer);
|
$this->deleteQueueEntry($answer);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NULL queued_time for remaining entries in queue, to allow
|
NULL queued_time for remaining entries in queue, to allow
|
||||||
daemon to take care of them as soon as possible. */
|
daemon to take care of them as soon as possible. */
|
||||||
|
|
||||||
$this->db->updateBy('queue', 'server_nonce', $this->server_nonce,
|
|
||||||
array('queued'=>NULL));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Return true if valid answers equals required answers.
|
$this->db->updateBy('queue', 'server_nonce', $this->server_nonce,
|
||||||
Since we only obtain the required amount of answers from
|
array('queued'=>NULL));
|
||||||
retrieveAsync this indicates that all answers were actually valid.
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return true if valid answers equals required answers.
|
||||||
|
Since we only obtain the required amount of answers from
|
||||||
|
retrieveAsync this indicates that all answers were actually valid.
|
||||||
Otherwise, return false. */
|
Otherwise, return false. */
|
||||||
if ($this->valid_answers==$ans_req) return True;
|
if ($this->valid_answers==$ans_req) return True;
|
||||||
else return False;
|
else return False;
|
||||||
@ -507,7 +509,7 @@ class SyncLib
|
|||||||
The request are sent asynchronously. Some of the URLs can fail
|
The request are sent asynchronously. Some of the URLs can fail
|
||||||
with unknown host, connection errors, or network timeout, but as
|
with unknown host, connection errors, or network timeout, but as
|
||||||
long as one of the URLs given work, data will be returned. If all
|
long as one of the URLs given work, data will be returned. If all
|
||||||
URLs fail, data from some URL that did not match parameter $match
|
URLs fail, data from some URL that did not match parameter $match
|
||||||
(defaults to ^OK) is returned, or if all URLs failed, false.
|
(defaults to ^OK) is returned, or if all URLs failed, false.
|
||||||
*/
|
*/
|
||||||
function retrieveURLasync ($urls, $ans_req=1, $timeout=1.0) {
|
function retrieveURLasync ($urls, $ans_req=1, $timeout=1.0) {
|
||||||
@ -517,26 +519,26 @@ class SyncLib
|
|||||||
foreach ($urls as $id => $url) {
|
foreach ($urls as $id => $url) {
|
||||||
$this->log(LOG_DEBUG, "url in retrieveURLasync is " . $url);
|
$this->log(LOG_DEBUG, "url in retrieveURLasync is " . $url);
|
||||||
$handle = curl_init();
|
$handle = curl_init();
|
||||||
|
|
||||||
curl_setopt($handle, CURLOPT_URL, $url);
|
curl_setopt($handle, CURLOPT_URL, $url);
|
||||||
curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL");
|
curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL");
|
||||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
|
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
|
||||||
curl_setopt($handle, CURLOPT_FAILONERROR, true);
|
curl_setopt($handle, CURLOPT_FAILONERROR, true);
|
||||||
curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);
|
curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);
|
||||||
|
|
||||||
curl_multi_add_handle($mh, $handle);
|
curl_multi_add_handle($mh, $handle);
|
||||||
|
|
||||||
$ch[$handle] = $handle;
|
$ch[$handle] = $handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
$str = false;
|
$str = false;
|
||||||
$ans_count = 0;
|
$ans_count = 0;
|
||||||
$ans_arr = array();
|
$ans_arr = array();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM)
|
while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM)
|
||||||
;
|
;
|
||||||
|
|
||||||
while ($info = curl_multi_info_read($mh)) {
|
while ($info = curl_multi_info_read($mh)) {
|
||||||
debug ("YK-KSM multi", $info);
|
debug ("YK-KSM multi", $info);
|
||||||
if ($info['result'] == CURLE_OK) {
|
if ($info['result'] == CURLE_OK) {
|
||||||
@ -549,27 +551,27 @@ class SyncLib
|
|||||||
$ans_count++;
|
$ans_count++;
|
||||||
$ans_arr[]="url=" . $cinfo['url'] . "\n" . $str;
|
$ans_arr[]="url=" . $cinfo['url'] . "\n" . $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ans_count >= $ans_req) {
|
if ($ans_count >= $ans_req) {
|
||||||
foreach ($ch as $h) {
|
foreach ($ch as $h) {
|
||||||
curl_multi_remove_handle ($mh, $h);
|
curl_multi_remove_handle ($mh, $h);
|
||||||
curl_close ($h);
|
curl_close ($h);
|
||||||
}
|
}
|
||||||
curl_multi_close ($mh);
|
curl_multi_close ($mh);
|
||||||
|
|
||||||
return $ans_arr;
|
return $ans_arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi_remove_handle ($mh, $info['handle']);
|
curl_multi_remove_handle ($mh, $info['handle']);
|
||||||
curl_close ($info['handle']);
|
curl_close ($info['handle']);
|
||||||
unset ($ch[$info['handle']]);
|
unset ($ch[$info['handle']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi_select ($mh);
|
curl_multi_select ($mh);
|
||||||
}
|
}
|
||||||
} while($active);
|
} while($active);
|
||||||
|
|
||||||
|
|
||||||
foreach ($ch as $h) {
|
foreach ($ch as $h) {
|
||||||
curl_multi_remove_handle ($mh, $h);
|
curl_multi_remove_handle ($mh, $h);
|
||||||
curl_close ($h);
|
curl_close ($h);
|
||||||
@ -579,7 +581,7 @@ class SyncLib
|
|||||||
if ($ans_count>0) return $ans_arr;
|
if ($ans_count>0) return $ans_arr;
|
||||||
else return $str;
|
else return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -47,12 +47,12 @@ $myLog->addField('otp', $otp);
|
|||||||
|
|
||||||
if ($protocol_version>=2.0) {
|
if ($protocol_version>=2.0) {
|
||||||
$sl = getHttpVal('sl', '');
|
$sl = getHttpVal('sl', '');
|
||||||
$timeout = getHttpVal('timeout', '');
|
$timeout = getHttpVal('timeout', '');
|
||||||
$nonce = getHttpVal('nonce', '');
|
$nonce = getHttpVal('nonce', '');
|
||||||
|
|
||||||
/* Add nonce to response parameters */
|
/* Add nonce to response parameters */
|
||||||
$extra['nonce']= $nonce;
|
$extra['nonce']= $nonce;
|
||||||
|
|
||||||
/* Nonce is required from protocol 2.0 */
|
/* Nonce is required from protocol 2.0 */
|
||||||
if(!$nonce) {
|
if(!$nonce) {
|
||||||
$myLog->log(LOG_NOTICE, 'Nonce is missing and protocol version >= 2.0');
|
$myLog->log(LOG_NOTICE, 'Nonce is missing and protocol version >= 2.0');
|
||||||
@ -62,15 +62,15 @@ if ($protocol_version>=2.0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Sanity check HTTP parameters
|
/* Sanity check HTTP parameters
|
||||||
|
|
||||||
* otp: one-time password
|
* otp: one-time password
|
||||||
* id: client id
|
* id: client id
|
||||||
* timeout: timeout in seconds to wait for external answers, optional: if absent the server decides
|
* timeout: timeout in seconds to wait for external answers, optional: if absent the server decides
|
||||||
* nonce: random alphanumeric string, 16 to 40 characters long. Must be non-predictable and changing for each request, but need not be cryptographically strong
|
* nonce: random alphanumeric string, 16 to 40 characters long. Must be non-predictable and changing for each request, but need not be cryptographically strong
|
||||||
* sl: "sync level", percentage of external servers that needs to answer (integer 0 to 100), or "fast" or "secure" to use server-configured values
|
* sl: "sync level", percentage of external servers that needs to answer (integer 0 to 100), or "fast" or "secure" to use server-configured values
|
||||||
* h: signature (optional)
|
* h: signature (optional)
|
||||||
* timestamp: requests timestamp/counters in response
|
* timestamp: requests timestamp/counters in response
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ if (isset($nonce) && (strlen($nonce) < 16 || strlen($nonce) > 40)) {
|
|||||||
sendResp(S_MISSING_PARAMETER);
|
sendResp(S_MISSING_PARAMETER);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) {
|
if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) {
|
||||||
$myLog->log(LOG_NOTICE, 'SL is provided but not correct');
|
$myLog->log(LOG_NOTICE, 'SL is provided but not correct');
|
||||||
sendResp(S_MISSING_PARAMETER);
|
sendResp(S_MISSING_PARAMETER);
|
||||||
@ -137,7 +137,7 @@ if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Timestamp parameter is not checked since current protocol says that 1 means request timestamp
|
// NOTE: Timestamp parameter is not checked since current protocol says that 1 means request timestamp
|
||||||
// and anything else is discarded.
|
// and anything else is discarded.
|
||||||
|
|
||||||
//// Get Client info from DB
|
//// Get Client info from DB
|
||||||
//
|
//
|
||||||
@ -150,7 +150,7 @@ if ($client <= 0) {
|
|||||||
|
|
||||||
|
|
||||||
/* Initialize the sync library. Strive to use this instead of custom
|
/* Initialize the sync library. Strive to use this instead of custom
|
||||||
DB requests, custom comparisons etc */
|
DB requests, custom comparisons etc */
|
||||||
$sync = new SyncLib('ykval-verify:synclib');
|
$sync = new SyncLib('ykval-verify:synclib');
|
||||||
$sync->addField('ip', $_SERVER['REMOTE_ADDR']);
|
$sync->addField('ip', $_SERVER['REMOTE_ADDR']);
|
||||||
$sync->addField('otp', $otp);
|
$sync->addField('otp', $otp);
|
||||||
@ -194,11 +194,11 @@ if ($h != '') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to add necessary parameters not available at earlier protocols after signature is computed.
|
/* We need to add necessary parameters not available at earlier protocols after signature is computed.
|
||||||
*/
|
*/
|
||||||
if ($protocol_version<2.0) {
|
if ($protocol_version<2.0) {
|
||||||
/* We need to create a nonce manually here */
|
/* We need to create a nonce manually here */
|
||||||
$nonce = md5(uniqid(rand()));
|
$nonce = md5(uniqid(rand()));
|
||||||
$myLog->log(LOG_INFO, 'protocol version below 2.0. Created nonce ' . $nonce);
|
$myLog->log(LOG_INFO, 'protocol version below 2.0. Created nonce ' . $nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,13 +239,13 @@ if ($localParams['active'] != 1) {
|
|||||||
|
|
||||||
/* Build OTP params */
|
/* Build OTP params */
|
||||||
|
|
||||||
$otpParams=array('modified'=>time(),
|
$otpParams=array('modified'=>time(),
|
||||||
'otp'=>$otp,
|
'otp'=>$otp,
|
||||||
'nonce'=>$nonce,
|
'nonce'=>$nonce,
|
||||||
'yk_publicname'=>$devId,
|
'yk_publicname'=>$devId,
|
||||||
'yk_counter'=>$otpinfo['session_counter'],
|
'yk_counter'=>$otpinfo['session_counter'],
|
||||||
'yk_use'=>$otpinfo['session_use'],
|
'yk_use'=>$otpinfo['session_use'],
|
||||||
'yk_high'=>$otpinfo['high'],
|
'yk_high'=>$otpinfo['high'],
|
||||||
'yk_low'=>$otpinfo['low']);
|
'yk_low'=>$otpinfo['low']);
|
||||||
|
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ if ($sync->countersEqual($localParams, $otpParams) &&
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the OTP counters against local db */
|
/* Check the OTP counters against local db */
|
||||||
if ($sync->countersHigherThanOrEqual($localParams, $otpParams)) {
|
if ($sync->countersHigherThanOrEqual($localParams, $otpParams)) {
|
||||||
$sync->log(LOG_WARNING, 'replayed OTP: Local counters higher');
|
$sync->log(LOG_WARNING, 'replayed OTP: Local counters higher');
|
||||||
$sync->log(LOG_WARNING, 'replayed OTP: Local counters ', $localParams);
|
$sync->log(LOG_WARNING, 'replayed OTP: Local counters ', $localParams);
|
||||||
@ -289,7 +289,7 @@ if ($req_answers>0) {
|
|||||||
$nr_answers=$sync->getNumberOfAnswers();
|
$nr_answers=$sync->getNumberOfAnswers();
|
||||||
$nr_valid_answers=$sync->getNumberOfValidAnswers();
|
$nr_valid_answers=$sync->getNumberOfValidAnswers();
|
||||||
$sl_success_rate=floor(100.0 * $nr_valid_answers / $nr_servers);
|
$sl_success_rate=floor(100.0 * $nr_valid_answers / $nr_servers);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$syncres=true;
|
$syncres=true;
|
||||||
$nr_answers=0;
|
$nr_answers=0;
|
||||||
@ -305,7 +305,7 @@ $myLog->log(LOG_INFO, "ykval-verify:notice:synclevel=" . $sl .
|
|||||||
" timeout=" . $timeout);
|
" timeout=" . $timeout);
|
||||||
|
|
||||||
if($syncres==False) {
|
if($syncres==False) {
|
||||||
/* sync returned false, indicating that
|
/* sync returned false, indicating that
|
||||||
either at least 1 answer marked OTP as invalid or
|
either at least 1 answer marked OTP as invalid or
|
||||||
there were not enough answers */
|
there were not enough answers */
|
||||||
$myLog->log(LOG_WARNING, "ykval-verify:notice:Sync failed");
|
$myLog->log(LOG_WARNING, "ykval-verify:notice:Sync failed");
|
||||||
@ -319,7 +319,7 @@ if($syncres==False) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recreate parameters to make phising test work out
|
/* Recreate parameters to make phising test work out
|
||||||
TODO: use timefunctionality in deltatime library instead */
|
TODO: use timefunctionality in deltatime library instead */
|
||||||
$sessionCounter = $otpParams['yk_counter'];
|
$sessionCounter = $otpParams['yk_counter'];
|
||||||
$sessionUse = $otpParams['yk_use'];
|
$sessionUse = $otpParams['yk_use'];
|
||||||
@ -345,8 +345,8 @@ if ($sessionCounter == $seenSessionCounter && $sessionUse > $seenSessionUse) {
|
|||||||
$elapsed = $now - $lastTime;
|
$elapsed = $now - $lastTime;
|
||||||
$deviation = abs($elapsed - $tsDelta);
|
$deviation = abs($elapsed - $tsDelta);
|
||||||
|
|
||||||
// Time delta server might verify multiple OTPS in a row. In such case validation server doesn't
|
// Time delta server might verify multiple OTPS in a row. In such case validation server doesn't
|
||||||
// have time to tick a whole second and we need to avoid division by zero.
|
// have time to tick a whole second and we need to avoid division by zero.
|
||||||
if ($elapsed != 0) {
|
if ($elapsed != 0) {
|
||||||
$percent = $deviation/$elapsed;
|
$percent = $deviation/$elapsed;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user