1
0
mirror of https://github.com/Yubico/yubikey-val.git synced 2025-02-20 21:54:20 +01:00

Rewritten sync daemon to work in a sequential way. Now called ykval-queue.php

This commit is contained in:
Olov Danielson 2010-01-10 16:46:11 +00:00
parent 851aa21c66
commit 9ede835f5e
6 changed files with 97 additions and 144 deletions

View File

@ -13,11 +13,11 @@ $baseParams['__YKVAL_SYNC_POOL__'] = array("http://1.2.3.4/wsapi/2.0/sync",
"http://3.4.5.6/wsapi/2.0/sync");
# Specify how often the sync daemon awakens
$baseParams['__YKVAL_SYNC_INTERVAL__'] = 60;
$baseParams['__YKVAL_SYNC_INTERVAL__'] = 10;
# Specify how long the sync daemon will wait for response
$baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__'] = 30;
# Specify how old entries in the database should be considered aborted attempts
$baseParams['__YKVAL_SYNC_OLD_LIMIT__'] = 1;
$baseParams['__YKVAL_SYNC_OLD_LIMIT__'] = 10;
# These are settings for the validation server.
$baseParams['__YKVAL_SYNC_FAST_LEVEL__'] = 1;

View File

@ -1,50 +0,0 @@
#!/usr/bin/php -q
<?php
require_once 'ykval-synclib.php';
require_once 'ykval-config.php';
require_once "System/Daemon.php";
$appname="ykval-daemon";
System_Daemon::setOption("appName", $appname);
System_Daemon::setOption("appDescription", "Yubico val-server sync daemon");
System_Daemon::setOption("authorName", "olov@yubico.com");
System_Daemon::setOption("authorEmail", "olov@yubico.com");
System_Daemon::start(); // Spawn Deamon!
$autostart_path = System_Daemon::writeAutoRun();
if ($path){
error_log("Successfully created autostart script at " . $autostart_path);
}
error_log($appname . " started");
$servers=explode(";", $baseParams['__YKVAL_SYNC_POOL__']);
$resources=array();
$descriptors=array();
$pipes=array();
$execstring="php -d error_log='/var/log/apache2/error.log' -f ./app1.php ";
foreach($servers as $server) {
$resources[$server]=proc_open($execstring . $server, $descriptors, $pipes);
}
# Loop forever and resync
while (True) {
foreach($resources as $server=>$resource) {
$res=proc_get_status($resource);
if ($res['running']==True){
System_Daemon::log(System_Daemon::LOG_INFO, "sync server for " . $server . " status=running");
} else {
System_Daemon::log(System_Daemon::LOG_INFO, "sync server for " . $server . " not running. Trying to restart.");
$resources[$server]=proc_open($execstring . $server, $descriptors, $pipes);
}
}
sleep(60);
}
System_Daemon::stop();
?>

View File

@ -349,12 +349,12 @@ or false on failure.
}
if ($rev==1) $query.= " ORDER BY id DESC";
if ($nr!=null) $query.= " LIMIT " . $nr;
error_log("delete query is " . $query);
return $this->query($query, false);
}
public function customQuery($query)
{
error_log("custom query: " . $query);
return $this->query($query, true);
}
/**

45
ykval-queue.php Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/php -q
<?php
require_once 'ykval-synclib.php';
require_once 'ykval-config.php';
require_once "System/Daemon.php";
$appname="ykval-queue";
System_Daemon::setOption("appName", $appname);
System_Daemon::setOption("appDescription", "Yubico val-server sync daemon");
System_Daemon::setOption("authorName", "olov@yubico.com");
System_Daemon::setOption("authorEmail", "olov@yubico.com");
if ($argc==2 && strcmp($argv[1], "install")==0) {
$autostart_path = System_Daemon::writeAutoRun();
if ($autostart_path!=1){
echo "Successfully created start script at " . $autostart_path . "\n";
echo "To start daemon use: /etc/init.d/".$appname." start\n";
exit();
} else {
echo "Start script already created\n";
echo "To start daemon use: /etc/init.d/".$appname." start\n";
exit();
}
}
System_Daemon::start(); // Spawn Deamon!
/* Application start */
$sl = new SyncLib();
# Loop forever and resync
$res==0;
while ($res==0) {
$sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'],
$baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']);
$res=sleep($baseParams['__YKVAL_SYNC_INTERVAL__']);
}
error_log("Stopping " . $appname);
System_Daemon::stop();
?>

View File

@ -1,23 +0,0 @@
<?php
require_once 'ykval-synclib.php';
require_once 'ykval-config.php';
if ($argc==2) $server=$argv[1];
else {
echo "Usage: " . $argv[0] . " server\n";
exit;
}
$sl = new SyncLib();
$resync = $baseParams['__YKVAL_SYNC_INTERVAL__'];
# Loop forever and resync
while (True) {
$sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'], 10);
sleep($baseParams['__YKVAL_SYNC_INTERVAL__']);
}
?>

View File

@ -241,95 +241,74 @@ class SyncLib
preg_match('/url=(.*)\?/', $answer, $out);
$server=$out[1];
debug("server=" . $server);
debug("deleting server=" . $server);
debug("modified=" . $this->otpParams['modified']);
debug("random_key=" . $this->random_key);
$this->db->deleteByMultiple('queue',
array("modified"=>$this->otpParams['modified'],
"random_key"=>$this->random_key,
'server'=>$server));
}
public function reSync($older_than=10, $timeout)
public function reSync($older_than=60, $timeout)
{
$this->log('notice', 'starting resync');
/* Loop over all unique servers in queue */
$res=$this->db->customQuery("select distinct server from queue WHERE (queued_time < DATE_SUB(now(), INTERVAL " . $older_than . " MINUTE) or queued_time is null)");
error_log("found " . mysql_num_rows($res) . " unique servers");
return true;
$queued_limit=time()-$older_than;
$res=$this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null");
error_log("found " . $res->rowCount() . " unique servers");
$urls=array();
# TODO: move statement to DB class, this looks grotesque
$res=$this->db->customQuery("select * from queue WHERE (queued_time < DATE_SUB(now(), INTERVAL " . $older_than . " MINUTE) or queued_time is null) and server='" . $server . "'");
$this->log('notice', "found " . mysql_num_rows($res) . " old queue entries");
$collection=array();
while($row = mysql_fetch_array($res, MYSQL_ASSOC)) {
$collection[]=$row;
}
foreach ($collection as $row) {
$this->log('notice', "server=" . $row['server'] . " , info=" . $row['info']);
foreach ($res as $my_server) {
error_log("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'] . "'");
error_log("found " . $res->rowCount() . " queue entries");
$urls[]=$row['server'] .
"?otp=" . $row['otp'] .
"&modified=" . $row['modified'] .
"&" . $this->otpPartFromInfoString($row['info']);
}
while ($entry=$res->fetch(PDO::FETCH_ASSOC)) {
$this->log('notice', "server=" . $entry['server'] . " , info=" . $entry['info']);
$url=$entry['server'] .
"?otp=" . $entry['otp'] .
"&modified=" . $entry['modified'] .
"&" . $this->otpPartFromInfoString($entry['info']);
/* Send out until no URL's left, or a timeout */
foreach($urls as $url) {
$ch = curl_init($this->url);
curl_setopt($ch, CURLOPT_USERAGENT, "YK-VAL");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
$response = curl_exec($ch);
curl_close($ch);
/* Send out sync request */
$this->log('notice', 'url is ' . $url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, "YK-VAL");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
$response = curl_exec($ch);
curl_close($ch);
if ($response==False) {
$this->log('warning', 'Timeout. Stopping queue resync at the moment');
return false;
}
if ($response==False) {
$this->log('warning', 'Timeout. Stopping queue resync for server ' . $my_server['server']);
break;
}
if (preg_match("/^OK/", $respone)) {
if (preg_match("/status=OK/", $response)) {
$resParams=$this->parseParamsFromMultiLineString($response);
$this->log("notice", "response contains ", $resParams);
/* Update database counters */
$this->updateDbCounters($resParams);
$resParams=$this->parseParamsFromMultiLineString($response);
$this->log("notice", "response contains ", $resParams);
/* Update database counters */
$this->updateDbCounters($resParams);
/* Warnings and deletion */
preg_match("/url=(.*)\?.*otp=([[:alpha:]]*)/", $answer, $out);
$server=$out[1];
$otp=$out[2];
$this->log('notice', 'Searching for entry with' .
' server=' . $server .
' otp=' . $otp);
$entries=$this->db->findByMultiple('queue',
array('server'=>$server,
'otp'=>$otp));
$this->log('notice', 'found ' . count($entries) . ' entries');
if (count($entries)>1) $this->log('warning', 'Multiple queue entries with the same OTP. We could have an OTP replay attempt in the system');
foreach($entries as $entry) {
/* Warnings */
/* Retrieve info from entry info string */
$localParams=$this->localParamsFromInfoString($entry['info']);
$otpParams=$this->otpParamsFromInfoString($entry['info']);
/* Check for warnings
If received sync response have lower counters than locally saved
last counters (indicating that remote server wasn't synced)
If received sync response have lower counters than locally saved
last counters (indicating that remote server wasn't synced)
*/
if ($this->countersHigherThan($localParams, $resParams)) {
$this->log("warning", "queued:Remote server out of sync, local counters ", $localParams);
$this->log("warning", "queued:Remote server out of sync, remote counters ", $resParams);
}
/* If received sync response have higher counters than locally saved
last counters (indicating that local server wasn't synced)
*/
@ -337,7 +316,7 @@ class SyncLib
$this->log("warning", "queued:Local server out of sync, local counters ", $localParams);
$this->log("warning", "queued:Local server out of sync, remote counters ", $resParams);
}
if ($this->countersHigherThan($resParams, $otpParams) ||
($this->countersEqual($resParams, $otpParams) &&
$resParams['nonce']!=$otpParams['nonce'])) {
@ -354,10 +333,12 @@ class SyncLib
$this->log('notice', 'deleting queue entry with id=' . $entry['id']);
$this->db->deleteByMultiple('queue', array('id'=>$entry['id']));
}
}
}
} /* End of loop over each queue entry for a server */
} /* End of loop over each distinct server in queue */
return true;
}
public function sync($ans_req, $timeout=1)
{
/*