diff --git a/ykval-checksum-clients.php b/ykval-checksum-clients.php index b89f19b..67f8085 100755 --- a/ykval-checksum-clients.php +++ b/ykval-checksum-clients.php @@ -29,7 +29,7 @@ $myLog = new Log($logname); $db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); if (!$db->connect()) { diff --git a/ykval-common.php b/ykval-common.php index fdfc0b1..50bb2e0 100644 --- a/ykval-common.php +++ b/ykval-common.php @@ -64,7 +64,7 @@ function debug() { } // Return eg. 2008-11-21T06:11:55Z0711 -// +// function getUTCTimeStamp() { date_default_timezone_set('UTC'); $tiny = substr(microtime(false), 2, 3); @@ -72,7 +72,7 @@ function getUTCTimeStamp() { } # NOTE: When we evolve to using general DB-interface, this functinality -# should be moved there. +# should be moved there. function DbTimeToUnix($db_time) { $unix=strptime($db_time, '%F %H:%M:%S'); @@ -82,14 +82,14 @@ function DbTimeToUnix($db_time) function UnixToDbTime($unix) { return date('Y-m-d H:i:s', $unix); -} +} // Sign a http query string in the array of key-value pairs // return b64 encoded hmac hash function sign($a, $apiKey) { ksort($a); $qs = urldecode(http_build_query($a)); - + // the TRUE at the end states we want the raw value, not hexadecimal form $hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true); $hmac = base64_encode($hmac); @@ -97,7 +97,7 @@ function sign($a, $apiKey) { debug('SIGN: ' . $qs . ' H=' . $hmac); return $hmac; - + } // sign an array of query string function hex2b64 ($hex_str) { @@ -115,7 +115,7 @@ function modhex2b64 ($modhex_str) { // The request are sent asynchronously. Some of the URLs can fail // with unknown host, connection errors, or network timeout, but as // 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. function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) { $mh = curl_multi_init(); @@ -165,11 +165,11 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) { curl_close ($h); } curl_multi_close ($mh); - + if ($ans_count==1) return $ans_arr[0]; else return $ans_arr; } - + curl_multi_remove_handle ($mh, $info['handle']); curl_close ($info['handle']); unset ($ch[$info['handle']]); diff --git a/ykval-config.php b/ykval-config.php index fda083a..4a98ead 100644 --- a/ykval-config.php +++ b/ykval-config.php @@ -8,13 +8,13 @@ $baseParams['__YKVAL_DB_PW__'] = 'lab'; $baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); # For the validation server sync -$baseParams['__YKVAL_SYNC_POOL__'] = array("http://api2.example.com/wsapi/2.0/sync", - "http://api3.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://api4.example.com/wsapi/2.0/sync"); # An array of IP addresses allowed to issue sync requests # NOTE: You must use IP addresses here. -$baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array("1.2.3.4", - "2.3.4.5", +$baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array("1.2.3.4", + "2.3.4.5", "3.4.5.6"); # Specify how often the sync daemon awakens diff --git a/ykval-db.php b/ykval-db.php index 4260489..7d9d7e7 100644 --- a/ykval-db.php +++ b/ykval-db.php @@ -18,7 +18,7 @@ class Db * @param string $user Database user * @param string $pwd Database password * @param string $name Database table name - * @return void + * @return void * */ 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) * - * @param string $updated Database timestamp + * @param string $updated Database timestamp * @return int Timestamp in unixtime format * */ @@ -53,7 +53,7 @@ class Db /** * 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 * @return int Deltatime (s) * @@ -73,7 +73,7 @@ class Db { $this->dbh=NULL; } - + /** * function to check if database is connected * @@ -109,7 +109,7 @@ class Db } if($this->isConnected()) { $this->myLog->log(LOG_DEBUG, 'DB query is: ' . $query); - + try { $this->result = $this->dbh->query($query); } catch (PDOException $e) { @@ -154,8 +154,8 @@ class Db $query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "'"; // Insert UPDATE statement at beginning - $query = "UPDATE " . $table . " SET " . $query; - + $query = "UPDATE " . $table . " SET " . $query; + return $this->query($query, false); } @@ -199,11 +199,11 @@ class Db $query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "' and " . $condition; // Insert UPDATE statement at beginning - $query = "UPDATE " . $table . " SET " . $query; + $query = "UPDATE " . $table . " SET " . $query; return $this->query($query, false); } - + /** * 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 $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 array $where Array with column=>values to select rows by @@ -295,7 +295,7 @@ or false on failure. $query.= " *"; } $query.= " FROM " . $table; - if ($where!=null){ + if ($where!=null){ foreach ($where as $key=>$value) { if ($key!=null) { if ($value!=null) $match.= " ". $key . " = '" . $value . "' and"; @@ -311,12 +311,12 @@ or false on failure. $result = $this->query($query, true); if (!$result) return false; - + if ($nr==1) { $row = $result->fetch(PDO::FETCH_ASSOC); $result->closeCursor(); return $row; - } + } else { $collection=array(); 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 array $where Array with column=>values to select rows by @@ -343,7 +343,7 @@ or false on failure. { $query="DELETE"; $query.= " FROM " . $table; - if ($where!=null){ + if ($where!=null){ $query.= " WHERE"; foreach ($where as $key=>$value) { $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 - * @return mixed + * @return mixed * */ 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. * */ public function rowCount() { - if($this->result) { + if($this->result) { $count=count($this->result->fetchAll()); $this->result->closeCursor(); return $count; @@ -387,8 +387,8 @@ or false on failure. } /** - * helper function used to get rows from Db table in reversed order. - * defaults to obtaining 1 row. + * helper function used to get rows from Db table in reversed order. + * defaults to obtaining 1 row. * * @param string $table Database table to update row in * @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. - * defaults to obtaining 1 row. + * helper function used to get rows from Db table in standard order. + * defaults to obtaining 1 row. * * @param string $table Database table to update row in * @param string $key Column to select rows by @@ -417,7 +417,7 @@ or false on failure. { return Db::findBy($table, $key, $value, $nr); } - + } diff --git a/ykval-export-clients.php b/ykval-export-clients.php index f0b8a2d..cf3b5fb 100755 --- a/ykval-export-clients.php +++ b/ykval-export-clients.php @@ -13,13 +13,13 @@ $myLog = new Log($logname); $db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); if (!$db->connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); exit(1); - } + } $result = $db->customQuery("select id, active, created, secret, email, notes, otp from clients order by id"); while($row = $result->fetch(PDO::FETCH_ASSOC)){ diff --git a/ykval-export.php b/ykval-export.php index ede2c1c..8d25a1d 100755 --- a/ykval-export.php +++ b/ykval-export.php @@ -13,13 +13,13 @@ $myLog = new Log($logname); $db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); if (!$db->connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); 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"); while($row = $result->fetch(PDO::FETCH_ASSOC)){ diff --git a/ykval-import-clients.php b/ykval-import-clients.php index abc525a..3141175 100755 --- a/ykval-import-clients.php +++ b/ykval-import-clients.php @@ -13,26 +13,26 @@ $myLog = new Log($logname); $db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); if (!$db->connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); error_log("Could not connect to database"); exit(1); - } + } while ($res=fgetcsv(STDIN, 0, "\t")) { - $params=array("id"=>$res[0], - "active"=>$res[1], - "created"=>$res[2], - "secret"=>$res[3], - "email"=>$res[4], - "notes"=>$res[5], + $params=array("id"=>$res[0], + "active"=>$res[1], + "created"=>$res[2], + "secret"=>$res[3], + "email"=>$res[4], + "notes"=>$res[5], "otp"=>$res[6]); - - + + $query="SELECT * FROM clients WHERE id='" . $params['id'] . "'"; $result=$db->customQuery($query); if(!$result->fetch(PDO::FETCH_ASSOC)) { @@ -46,7 +46,7 @@ while ($res=fgetcsv(STDIN, 0, "\t")) { "'" . $params['email'] . "'," . "'" . $params['notes'] . "'," . "'" . $params['otp'] . "')"; - + if(!$db->customQuery($query)){ $myLog->log(LOG_ERR, "Failed to insert new client with query " . $query); error_log("Failed to insert new client with query " . $query); diff --git a/ykval-import.php b/ykval-import.php index 185ec51..49d696f 100755 --- a/ykval-import.php +++ b/ykval-import.php @@ -13,29 +13,29 @@ $myLog = new Log($logname); $db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); if (!$db->connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); error_log("Could not connect to database"); exit(1); - } + } while ($res=fgetcsv(STDIN, 0, "\t")) { - $params=array("active"=>$res[0], - "created"=>$res[1], - "modified"=>$res[2], - "yk_publicname"=>$res[3], - "yk_counter"=>$res[4], - "yk_use"=>$res[5], - "yk_low"=>$res[6], - "yk_high"=>$res[7], + $params=array("active"=>$res[0], + "created"=>$res[1], + "modified"=>$res[2], + "yk_publicname"=>$res[3], + "yk_counter"=>$res[4], + "yk_use"=>$res[5], + "yk_low"=>$res[6], + "yk_high"=>$res[7], "nonce"=>$res[8], "notes"=>$res[9]); - - + + $query="SELECT * FROM yubikeys WHERE yk_publicname='" . $params['yk_publicname'] . "'"; $result=$db->customQuery($query); if($result->fetch(PDO::FETCH_ASSOC)) { @@ -52,13 +52,13 @@ while ($res=fgetcsv(STDIN, 0, "\t")) { "WHERE yk_publicname='" . $params['yk_publicname'] . "' AND " . "(".$params['yk_counter'].">yk_counter or (".$params['yk_counter']."=yk_counter and " . $params['yk_use'] . ">yk_use))"; - + if(!$db->customQuery($query)) { $myLog->log(LOG_ERR, "Failed to update yk_publicname with query " . $query); error_log("Failed to update yk_publicname with query " . $query); exit(1); } - + } else { // We didn't have the yk_publicname in database so we need to do insert instead $query="INSERT INTO yubikeys " . @@ -73,7 +73,7 @@ while ($res=fgetcsv(STDIN, 0, "\t")) { "'" . $params['yk_high'] . "'," . "'" . $params['nonce'] . "'," . "'" . $params['notes'] . "')"; - + if(!$db->customQuery($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); diff --git a/ykval-log.php b/ykval-log.php index a806400..154735a 100644 --- a/ykval-log.php +++ b/ykval-log.php @@ -2,29 +2,29 @@ class Log { - + function __construct($name='ykval') { $this->name=$name; $this->fields=array(); - $this->LOG_LEVELS = array(LOG_EMERG=>'LOG_EMERG', - LOG_ALERT=>'LOG_ALERT', - LOG_CRIT=>'LOG_CRIT', - LOG_ERR=>'LOG_ERR', - LOG_WARNING=>'LOG_WARNING', - LOG_NOTICE=>'LOG_NOTICE', - LOG_INFO=>'LOG_INFO', + $this->LOG_LEVELS = array(LOG_EMERG=>'LOG_EMERG', + LOG_ALERT=>'LOG_ALERT', + LOG_CRIT=>'LOG_CRIT', + LOG_ERR=>'LOG_ERR', + LOG_WARNING=>'LOG_WARNING', + LOG_NOTICE=>'LOG_NOTICE', + LOG_INFO=>'LOG_INFO', LOG_DEBUG=>'LOG_DEBUG'); - + openlog("ykval", LOG_PID, LOG_LOCAL0); } - - function addField($name, $value) + + function addField($name, $value) { $this->fields[$name]=$value; } - + function log($priority, $message, $arr=null){ if (is_array($arr)) { foreach($arr as $key=>$value){ @@ -36,13 +36,13 @@ class Log foreach ($this->fields as $field=>$value) { $msg_fields .= "[" . $value . "] "; } - syslog($priority, + syslog($priority, $this->LOG_LEVELS[$priority] . ':' . - $this->name . ':' . - $msg_fields . + $this->name . ':' . + $msg_fields . $message); } - + } ?> diff --git a/ykval-ping.php b/ykval-ping.php index 186a382..f57744f 100644 --- a/ykval-ping.php +++ b/ykval-ping.php @@ -1,4 +1,4 @@ -reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'], + $sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'], $baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']); $res=sleep($baseParams['__YKVAL_SYNC_INTERVAL__']); } diff --git a/ykval-revoke.php b/ykval-revoke.php index e39b7b1..b1496df 100644 --- a/ykval-revoke.php +++ b/ykval-revoke.php @@ -26,7 +26,7 @@ if ($do != "enable" && $do != "disable") { $db = new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], 'ykval-revoke:db'); if (!$db->connect()) { logdie("ERROR Database connect error"); diff --git a/ykval-sync.php b/ykval-sync.php index 155747d..8e6e47b 100644 --- a/ykval-sync.php +++ b/ykval-sync.php @@ -20,7 +20,7 @@ if (! $sync->isConnected()) { exit; } -# +# # Verify that request comes from valid server # @@ -77,7 +77,7 @@ $myLog->addField('otp', $syncParams['otp']); $sync->addField('otp', $syncParams['otp']); # -# Verify correctness of input parameters +# Verify correctness of input parameters # foreach (array('modified') as $param) { @@ -119,14 +119,14 @@ if ($localParams['active'] != 1) { /* Conditional update local database */ -$sync->updateDbCounters($syncParams); +$sync->updateDbCounters($syncParams); $myLog->log(LOG_DEBUG, 'Local params ' , $localParams); $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 # @@ -143,7 +143,7 @@ if ($sync->countersEqual($localParams, $syncParams)) { $syncParams['nonce']==$localParams['nonce']) { $myLog->log(LOG_NOTICE, 'Sync request unnessecarily sent'); } - + if ($syncParams['modified']!=$localParams['modified'] && $syncParams['nonce']==$localParams['nonce']) { $deltaModified = $syncParams['modified'] - $localParams['modified']; @@ -156,7 +156,7 @@ if ($sync->countersEqual($localParams, $syncParams)) { } - + $extra=array('modified'=>$localParams['modified'], 'nonce'=>$localParams['nonce'], 'yk_publicname'=>$yk_publicname, diff --git a/ykval-synclib.php b/ykval-synclib.php index 30834d7..11b2be8 100644 --- a/ykval-synclib.php +++ b/ykval-synclib.php @@ -19,10 +19,10 @@ class SyncLib $this->db=new Db($baseParams['__YKVAL_DB_DSN__'], $baseParams['__YKVAL_DB_USER__'], $baseParams['__YKVAL_DB_PW__'], - $baseParams['__YKVAL_DB_OPTIONS__'], + $baseParams['__YKVAL_DB_OPTIONS__'], $logname . ':db'); $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); } - function isConnected() + function isConnected() { return $this->isConnected; } @@ -42,11 +42,11 @@ class SyncLib $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); } - + function UnixToDbTime($unix) { return date('Y-m-d H:i:s', $unix); - } + } function getServer($index) { @@ -91,11 +91,11 @@ class SyncLib return $out[0]; } - public function localParamsFromInfoString($info) + public function localParamsFromInfoString($info) { $out=explode(",", $info); parse_str($out[1], $params); - return array('yk_counter'=>$params['local_counter'], + return array('yk_counter'=>$params['local_counter'], 'yk_use'=>$params['local_use']); } @@ -105,14 +105,14 @@ class SyncLib $info=$this->createInfoString($otpParams, $localParams); $this->otpParams = $otpParams; $this->localParams = $localParams; - + $queued=time(); $res=True; foreach ($this->syncServers as $server) { - + if(! $this->db->save('queue', array('queued'=>$queued, - 'modified'=>$otpParams['modified'], - 'otp'=>$otpParams['otp'], + 'modified'=>$otpParams['modified'], + 'otp'=>$otpParams['otp'], 'server'=>$server, 'server_nonce'=>$this->server_nonce, 'info'=>$info))) $res=False; @@ -132,9 +132,9 @@ class SyncLib if ($params) $logMsg .= ' modified=' . $params['modified'] . ' nonce=' . $params['nonce'] . ' yk_publicname=' . $params['yk_publicname'] . - ' yk_counter=' . $params['yk_counter'] . - ' yk_use=' . $params['yk_use'] . - ' yk_high=' . $params['yk_high'] . + ' yk_counter=' . $params['yk_counter'] . + ' yk_use=' . $params['yk_use'] . + ' yk_high=' . $params['yk_high'] . ' yk_low=' . $params['yk_low']; if ($this->myLog) $this->myLog->log($priority, $logMsg); else error_log("Warning: myLog uninitialized in ykval-synclib.php. Message is " . $logMsg); @@ -147,7 +147,7 @@ class SyncLib if (!$res) { $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(), 'modified'=>-1, 'yk_publicname'=>$yk_publicname, @@ -164,11 +164,11 @@ class SyncLib 'nonce'=>$res['nonce'], 'active'=>$res['active'], 'yk_publicname'=>$yk_publicname, - 'yk_counter'=>$res['yk_counter'], + 'yk_counter'=>$res['yk_counter'], 'yk_use'=>$res['yk_use'], 'yk_high'=>$res['yk_high'], 'yk_low'=>$res['yk_low']); - + $this->log(LOG_INFO, "yubikey found in db ", $localParams); return $localParams; } else { @@ -230,18 +230,18 @@ class SyncLib if (isset($params['yk_publicname'])) { $condition='('.$params['yk_counter'].'>yk_counter or ('.$params['yk_counter'].'=yk_counter and ' . $params['yk_use'] . '>yk_use))' ; - if(! $this->db->conditionalUpdateBy('yubikeys', 'yk_publicname', $params['yk_publicname'], - array('modified'=>$params['modified'], - 'yk_counter'=>$params['yk_counter'], + if(! $this->db->conditionalUpdateBy('yubikeys', 'yk_publicname', $params['yk_publicname'], + array('modified'=>$params['modified'], + 'yk_counter'=>$params['yk_counter'], 'yk_use'=>$params['yk_use'], 'yk_low'=>$params['yk_low'], - 'yk_high'=>$params['yk_high'], - 'nonce'=>$params['nonce']), + 'yk_high'=>$params['yk_high'], + 'nonce'=>$params['nonce']), $condition)) { $this->log(LOG_CRIT, 'failed to update internal DB with new counters'); return false; - } else + } else { if ($this->db->rowCount()>0) $this->log(LOG_INFO, "updated database ", $params); else $this->log(LOG_INFO, 'database not updated', $params); @@ -249,7 +249,7 @@ class SyncLib } } else return false; } - + public function countersHigherThan($p1, $p2) { if ($p1['yk_counter'] > $p2['yk_counter'] || @@ -257,7 +257,7 @@ class SyncLib $p1['yk_use'] > $p2['yk_use'])) return true; else return false; } - + public function countersHigherThanOrEqual($p1, $p2) { 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']); } - public function deleteQueueEntry($answer) + public function deleteQueueEntry($answer) { preg_match('/url=(.*)\?/', $answer, $out); $server=$out[1]; - $this->log(LOG_INFO, "deleting server=" . $server . + $this->log(LOG_INFO, "deleting server=" . $server . " modified=" . $this->otpParams['modified'] . " server_nonce=" . $this->server_nonce); - $this->db->deleteByMultiple('queue', + $this->db->deleteByMultiple('queue', array("modified"=>$this->otpParams['modified'], - "server_nonce"=>$this->server_nonce, + "server_nonce"=>$this->server_nonce, 'server'=>$server)); } @@ -290,19 +290,19 @@ class SyncLib /* Loop over all unique servers in queue */ $queued_limit=time()-$older_than; $res=$this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null"); - + foreach ($res as $my_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'] . "'"); - + while ($entry=$res->fetch(PDO::FETCH_ASSOC)) { $this->log(LOG_INFO, "server=" . $entry['server'] . " , info=" . $entry['info']); - $url=$entry['server'] . + $url=$entry['server'] . "?otp=" . $entry['otp'] . "&modified=" . $entry['modified'] . "&" . $this->otpPartFromInfoString($entry['info']); - - + + /* Send out sync request */ $this->log(LOG_DEBUG, 'url is ' . $url); $ch = curl_init($url); @@ -313,100 +313,100 @@ class SyncLib curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $response = curl_exec($ch); curl_close($ch); - + if ($response==False) { $this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $my_server['server']); break; } - + if (preg_match("/status=OK/", $response)) { $resParams=$this->parseParamsFromMultiLineString($response); $this->log(LOG_DEBUG, "response contains ", $resParams); - + /* Update database counters */ $this->updateDbCounters($resParams); - + /* Retrieve info from entry info string */ - + $validationParams=$this->localParamsFromInfoString($entry['info']); $otpParams=$this->otpParamsFromInfoString($entry['info']); $localParams=$this->getLocalParams($otpParams['yk_publicname']); $this->log(LOG_DEBUG, "validation params: ", $validationParams); $this->log(LOG_DEBUG, "OTP params: ", $otpParams); - - /* Check for warnings */ + + /* Check for warnings */ if ($this->countersHigherThan($validationParams, $resParams)) { $this->log(LOG_NOTICE, "Remote server out of sync compared to counters at validation request time. "); } - + if ($this->countersHigherThan($resParams, $validationParams)) { $this->log(LOG_NOTICE, "Local server out of sync compared to counters at validation request time. "); } - + if ($this->countersHigherThan($localParams, $resParams)) { $this->log(LOG_WARNING, "Remote server out of sync compared to current local counters. "); } - + if ($this->countersHigherThan($resParams, $localParams)) { $this->log(LOG_WARNING, "Local server out of sync compared to current local counters. Local server updated. "); } - + 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. "); - } + } elseif ($this->countersEqual($resParams, $otpParams) && $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."); } - + /* Deletion */ $this->log(LOG_INFO, 'deleting queue entry with modified=' . $entry['modified'] . ' server_nonce=' . $entry['server_nonce'] . ' server=' . $entry['server']); - $this->db->deleteByMultiple('queue', + $this->db->deleteByMultiple('queue', array("modified"=>$entry['modified'], - "server_nonce"=>$entry['server_nonce'], + "server_nonce"=>$entry['server_nonce'], 'server'=>$entry['server'])); } - + } /* End of loop over each queue entry for a server */ $res->closeCursor(); } /* End of loop over each distinct server in queue */ return true; } - - public function sync($ans_req, $timeout=1) + + public function sync($ans_req, $timeout=1) { /* Construct URLs */ - + $urls=array(); $res=$this->db->findByMultiple('queue', array("modified"=>$this->otpParams['modified'], "server_nonce"=>$this->server_nonce)); foreach ($res as $row) { - $urls[]=$row['server'] . + $urls[]=$row['server'] . "?otp=" . $row['otp'] . "&modified=" . $row['modified'] . "&" . $this->otpPartFromInfoString($row['info']); } - + /* Send out requests */ $ans_arr=$this->retrieveURLasync($urls, $ans_req, $timeout); - + 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(); } - + /* Parse responses */ $localParams = $this->localParams; - + $this->answers = count($ans_arr); $this->valid_answers = 0; foreach ($ans_arr as $answer){ @@ -417,71 +417,71 @@ class SyncLib $this->log(LOG_DEBUG, "OTP contains " , $this->otpParams); /* Update internal DB (conditional) */ - + $this->updateDbCounters($resParams); - - - /* Check for warnings + + + /* Check for warnings See http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol - + 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)) { $this->log(LOG_NOTICE, "Remote server out of sync"); } - + if ($this->countersHigherThan($resParams, $localParams)) { $this->log(LOG_NOTICE, "Local server out of sync"); } - - if ($this->CountersEqual($resParams, $localParams) && + + if ($this->CountersEqual($resParams, $localParams) && $resParams['nonce']!=$localParams['nonce']) { $this->log(LOG_NOTICE, "Servers out of sync. Nonce differs. "); } - - if ($this->CountersEqual($resParams, $localParams) && + + if ($this->CountersEqual($resParams, $localParams) && $resParams['modified']!=$localParams['modified']) { $this->log(LOG_NOTICE, "Servers out of sync. Modified differs. "); } - + if ($this->countersHigherThan($resParams, $this->otpParams)){ $this->log(LOG_WARNING, 'OTP is replayed. Sync response counters higher than OTP counters.'); - } + } elseif ($this->countersEqual($resParams, $this->otpParams) && $resParams['nonce']!=$this->otpParams['nonce']) { $this->log(LOG_WARNING, 'OTP is replayed. Sync response counters equal to OTP counters and nonce differs.'); } else { - + /* The answer is ok since a REPLAY was not indicated */ - + $this->valid_answers++; } - - - - + + + + /* Delete entry from table */ $this->deleteQueueEntry($answer); - - + + } - - /* + + /* NULL queued_time for remaining entries in queue, to allow 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. - Since we only obtain the required amount of answers from - retrieveAsync this indicates that all answers were actually valid. + $this->db->updateBy('queue', 'server_nonce', $this->server_nonce, + array('queued'=>NULL)); + + + + /* 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. */ if ($this->valid_answers==$ans_req) return True; else return False; @@ -506,7 +506,7 @@ class SyncLib The request are sent asynchronously. Some of the URLs can fail with unknown host, connection errors, or network timeout, but as 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. */ function retrieveURLasync ($urls, $ans_req=1, $timeout=1.0) { @@ -516,26 +516,26 @@ class SyncLib foreach ($urls as $id => $url) { $this->log(LOG_DEBUG, "url in retrieveURLasync is " . $url); $handle = curl_init(); - + curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL"); curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($handle, CURLOPT_FAILONERROR, true); curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); - + curl_multi_add_handle($mh, $handle); - + $ch[$handle] = $handle; } - + $str = false; $ans_count = 0; $ans_arr = array(); - + do { while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM) ; - + while ($info = curl_multi_info_read($mh)) { debug ("YK-KSM multi", $info); if ($info['result'] == CURLE_OK) { @@ -548,27 +548,27 @@ class SyncLib $ans_count++; $ans_arr[]="url=" . $cinfo['url'] . "\n" . $str; } - + if ($ans_count >= $ans_req) { foreach ($ch as $h) { curl_multi_remove_handle ($mh, $h); curl_close ($h); } curl_multi_close ($mh); - + return $ans_arr; } - + curl_multi_remove_handle ($mh, $info['handle']); curl_close ($info['handle']); unset ($ch[$info['handle']]); } - + curl_multi_select ($mh); } } while($active); - + foreach ($ch as $h) { curl_multi_remove_handle ($mh, $h); curl_close ($h); @@ -578,7 +578,7 @@ class SyncLib if ($ans_count>0) return $ans_arr; else return $str; } - + } ?> diff --git a/ykval-verify.php b/ykval-verify.php index 8f66ef9..21516c6 100644 --- a/ykval-verify.php +++ b/ykval-verify.php @@ -47,12 +47,12 @@ $myLog->addField('otp', $otp); if ($protocol_version>=2.0) { $sl = getHttpVal('sl', ''); - $timeout = getHttpVal('timeout', ''); + $timeout = getHttpVal('timeout', ''); $nonce = getHttpVal('nonce', ''); /* Add nonce to response parameters */ $extra['nonce']= $nonce; - + /* Nonce is required from protocol 2.0 */ if(!$nonce) { $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 - * id: client id - * 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 - * 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) - * timestamp: requests timestamp/counters in response + * otp: one-time password + * id: client id + * 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 + * 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) + * timestamp: requests timestamp/counters in response */ @@ -129,7 +129,7 @@ if (isset($nonce) && (strlen($nonce) < 16 || strlen($nonce) > 40)) { sendResp(S_MISSING_PARAMETER); exit; } - + if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) { $myLog->log(LOG_NOTICE, 'SL is provided but not correct'); 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 -// and anything else is discarded. +// and anything else is discarded. //// Get Client info from DB // @@ -150,7 +150,7 @@ if ($client <= 0) { /* 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->addField('ip', $_SERVER['REMOTE_ADDR']); $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) { /* 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); } @@ -239,13 +239,13 @@ if ($localParams['active'] != 1) { /* Build OTP params */ -$otpParams=array('modified'=>time(), - 'otp'=>$otp, +$otpParams=array('modified'=>time(), + 'otp'=>$otp, 'nonce'=>$nonce, - 'yk_publicname'=>$devId, - 'yk_counter'=>$otpinfo['session_counter'], - 'yk_use'=>$otpinfo['session_use'], - 'yk_high'=>$otpinfo['high'], + 'yk_publicname'=>$devId, + 'yk_counter'=>$otpinfo['session_counter'], + 'yk_use'=>$otpinfo['session_use'], + 'yk_high'=>$otpinfo['high'], 'yk_low'=>$otpinfo['low']); @@ -257,7 +257,7 @@ if ($sync->countersEqual($localParams, $otpParams) && exit; } -/* Check the OTP counters against local db */ +/* Check the OTP counters against local db */ if ($sync->countersHigherThanOrEqual($localParams, $otpParams)) { $sync->log(LOG_WARNING, 'replayed OTP: Local counters higher'); $sync->log(LOG_WARNING, 'replayed OTP: Local counters ', $localParams); @@ -289,7 +289,7 @@ if ($req_answers>0) { $nr_answers=$sync->getNumberOfAnswers(); $nr_valid_answers=$sync->getNumberOfValidAnswers(); $sl_success_rate=floor(100.0 * $nr_valid_answers / $nr_servers); - + } else { $syncres=true; $nr_answers=0; @@ -305,7 +305,7 @@ $myLog->log(LOG_INFO, "ykval-verify:notice:synclevel=" . $sl . " timeout=" . $timeout); if($syncres==False) { - /* sync returned false, indicating that + /* sync returned false, indicating that either at least 1 answer marked OTP as invalid or there were not enough answers */ $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 */ $sessionCounter = $otpParams['yk_counter']; $sessionUse = $otpParams['yk_use']; @@ -345,8 +345,8 @@ if ($sessionCounter == $seenSessionCounter && $sessionUse > $seenSessionUse) { $elapsed = $now - $lastTime; $deviation = abs($elapsed - $tsDelta); - // 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. + // 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. if ($elapsed != 0) { $percent = $deviation/$elapsed; } else {