yubikey-val-2.38/0000755000175000017500000000000012726004025012321 5ustar jeanjeanyubikey-val-2.38/ykval-import0000755000175000017500000001033112726004025014703 0ustar jeanjean#!/usr/bin/php connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); error_log("Could not connect to database"); exit(1); } while ($res=fgetcsv(STDIN, 0, ",")) { if ($res[0]===null || strpos($res[0], '#')===0) continue; $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] ); # FIXME # INSERT first, if duplicate error, UPDATE. $query="SELECT * FROM yubikeys WHERE yk_publicname='" . $params['yk_publicname'] . "'"; $result=$db->customQuery($query); if ($db->rowCount($result)) { $query="UPDATE yubikeys SET " . "active='" . $params["active"] . "' " . ",created='" . $params["created"] . "' " . ",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"] . "' " . ",notes='" . $params["notes"] . "' " . "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 " . "(active,created,modified,yk_publicname,yk_counter,yk_use,yk_low,yk_high,nonce,notes) VALUES " . "('" . $params["active"] . "', " . "'" . $params['created'] . "'," . "'" . $params['modified'] . "'," . "'" . $params['yk_publicname'] . "'," . "'" . $params['yk_counter'] . "'," . "'" . $params['yk_use'] . "'," . "'" . $params['yk_low'] . "'," . "'" . $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); exit(1); } } $db->closeCursor($result); } $myLog->log(LOG_NOTICE, "Successfully imported yubikeys to database"); echo "Successfully imported yubikeys to database\n"; yubikey-val-2.38/README0000644000175000017500000000205612726004025013204 0ustar jeanjean== YubiKey OTP Validation Server == The YubiKey Validation Server (YK-VAL) is a server that validates Yubikey One-Time Passwords (OTPs). YK-VAL is written in PHP, for use behind web servers such as Apache. General ------- The server implements the Yubico API protocol as defined in doc/ValidationProtocol* and further documentation is also available in the doc/ subdirectory. This server talks to a KSM service for decrypting the OTPs, to avoid storing any AES keys on the validation server. One implementation of this service is the https://developers.yubico.com/yubikey-ksm[YubiKey-KSM], and another implementation using the YubiHSM hardware is https://developers.yubico.com/python-pyhsm[PyHSM]. Note that version 1.x is a minimal centralized server. Version 2.x is a replicated system that uses multiple machines. License ------- The project is licensed under a BSD license. See the file COPYING for exact wording. For any copyright year range specified as YYYY-ZZZZ in this package note that the range specifies every single year in that closed interval. yubikey-val-2.38/ykval-munin-ksmresponses.pl0000755000175000017500000000503612726004025017671 0ustar jeanjean#!/usr/bin/perl #%# family=auto #%# capabilities=autoconf # Copyright (c) 2012-2015 Yubico AB # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; use Env qw/YKVAL_LOGFILE YKVAL_KSMS/; my @ksms = split(/ /, $YKVAL_KSMS); die "YKVAL_KSMS has to be set with the hostnames of any ksms used." unless @ksms; my $logfile = $YKVAL_LOGFILE; $logfile = "/var/log/syslog" unless $logfile; if(@ARGV > 0) { if($ARGV[0] eq "autoconf") { print "yes\n"; exit 0; } elsif($ARGV[0] eq "config") { print "multigraph ykval_ksmresponses\n"; print "graph_title YK-VAL KSM responses\n"; print "graph_vlabel responses\n"; print "graph_category ykval\n"; foreach my $ksm (@ksms) { print "${ksm}.label ${ksm}\n"; print "${ksm}.type DERIVE\n"; print "${ksm}.info Responses\n"; print "${ksm}.min 0\n"; print "${ksm}.draw LINE1\n"; } exit 0 } print "unknown command '${ARGV[0]}'\n"; exit 1 } my %responses = map { $_ => 0 } @ksms; my $reg = qr/url=https?:\/\/([a-z0-9A-Z_-]+)\./; open (my $file, "-|", "grep 'YK-KSM errno/error: 0/' $logfile"); while(<$file>) { next unless /$reg/; $responses{$1}++; } close $file; print "multigraph ykval_ksmresponses\n"; foreach my $ksm (@ksms) { print "${ksm}.value ${responses{$ksm}}\n"; } exit 0 yubikey-val-2.38/ykval-db.php0000644000175000017500000001761012726004025014550 0ustar jeanjeanmyLog->addField($name, $value); } /** * function to convert Db timestamps to unixtime(s) * * @param string $updated Database timestamp * @return int Timestamp in unixtime format * */ public function timestampToTime($updated) { $stamp=strptime($updated, '%F %H:%M:%S'); return mktime($stamp[tm_hour], $stamp[tm_min], $stamp[tm_sec], $stamp[tm_mon]+1, $stamp[tm_mday], $stamp[tm_year]); } /** * function to compute delta (s) between 2 Db timestamps * * @param string $first Database timestamp 1 * @param string $second Database timestamp 2 * @return int Deltatime (s) * */ public function timestampDeltaTime($first, $second) { return Db::timestampToTime($second) - Db::timestampToTime($first); } /** * function to disconnect from database * * @return boolean True on success, otherwise false. * */ public function disconnect() { $this->dbh=NULL; } /** * function to check if database is connected * * @return boolean True if connected, otherwise false. * */ public function isConnected() { if ($this->dbh!=NULL) return True; else return False; } /** * function to update row in database by a where condition * * @param string $table Database table to update row in * @param int $id Id on row to update * @param array $values Array with key=>values to update * @return boolean True on success, otherwise false. * */ public function updateBy($table, $k, $v, $values) { $query = ""; foreach ($values as $key=>$value){ if (!is_null($value)) $query .= ' ' . $key . "='" . $value . "',"; else $query .= ' ' . $key . '=NULL,'; } if (! $query) { $this->myLog->log(LOG_DEBUG, "no values to set in query. Not updating DB"); return true; } $query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "'"; // Insert UPDATE statement at beginning $query = "UPDATE " . $table . " SET " . $query; return $this->query($query, false); } /** * function to update row in database * * @param string $table Database table to update row in * @param int $id Id on row to update * @param array $values Array with key=>values to update * @return boolean True on success, otherwise false. * */ public function update($table, $id, $values) { return $this->updateBy($table, 'id', $id, $values); } /** * function to update row in database based on a condition * * @param string $table Database table to update row in * @param string $k Column to select row on * @param string $v Value to select row on * @param array $values Array with key=>values to update * @param string $condition conditional statement * @return boolean True on success, otherwise false. * */ public function conditionalUpdateBy($table, $k, $v, $values, $condition) { $query = ""; /* quiet the PHP Notice */ foreach ($values as $key=>$value){ $query = $query . " " . $key . "='" . $value . "',"; } if (! $query) { $this->myLog->log(LOG_DEBUG, "no values to set in query. Not updating DB"); return true; } $query = rtrim($query, ",") . " WHERE " . $k . " = '" . $v . "' and " . $condition; // Insert UPDATE statement at beginning $query = "UPDATE " . $table . " SET " . $query; return $this->query($query, false); } /** * Function to update row in database based on a condition. * An ID value is passed to select the appropriate column * * @param string $table Database table to update row in * @param int $id Id on row to update * @param array $values Array with key=>values to update * @param string $condition conditional statement * @return boolean True on success, otherwise false. * */ public function conditionalUpdate($table, $id, $values, $condition) { return $this->conditionalUpdateBy($table, 'id', $id, $values, $condition); } /** * function to insert new row in database * * @param string $table Database table to update row in * @param array $values Array with key=>values to update * @return boolean True on success, otherwise false. * */ public function save($table, $values) { $query= 'INSERT INTO ' . $table . " ("; foreach ($values as $key=>$value){ if (!is_null($value)) $query = $query . $key . ","; } $query = rtrim($query, ",") . ') VALUES ('; foreach ($values as $key=>$value){ if (!is_null($value)) $query = $query . "'" . $value . "',"; } $query = rtrim($query, ","); $query = $query . ")"; return $this->query($query, false); } /** * helper function to collect last row[s] in database * * @param string $table Database table to update row in * @param int $nr Number of rows to collect. NULL=>inifinity. DEFAULT=1. * @return mixed Array with values from Db row or 2d-array with multiple rows or false on failure. * */ public function last($table, $nr=1) { return Db::findBy($table, null, null, $nr, 1); } /** * 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 * @param string $value Value to select rows by * @param int $nr Number of rows to collect. NULL=>inifinity. Default=NULL. * @param int $rev rev=1 indicates order should be reversed. Default=NULL. * @return mixed Array with values from Db row or 2d-array with multiple rows * */ public function findBy($table, $key, $value, $nr=null, $rev=null) { return $this->findByMultiple($table, array($key=>$value), $nr, $rev); } /** * Function to do a custom query on database connection * * @param string $query Database query * @return mixed * */ public function customQuery($query) { return $this->query($query, true); } } yubikey-val-2.38/ykval-gen-clients0000755000175000017500000001012712726004025015604 0ustar jeanjean#!/usr/bin/php connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); error_log("Could not connect to database"); exit(1); } $count=1; if($last_arg = intval(array_pop($argv))) { $count = $last_arg; } $result = $db->customQuery("SELECT id FROM clients ORDER BY id DESC LIMIT 1"); $row = $db->fetchArray($result); $db->closeCursor($result); if($row) { $next_id = $row['id']+1; } else { $next_id = 1; } $random = array_key_exists('urandom', $options) ? "/dev/urandom" : "/dev/random"; $fh = fopen($random, "r"); if(!$fh) { die("cannot open ".$random); } for ($i=0; $i<$count; $i++) { $client_id = $next_id++; if (!($rnd = fread ($fh, 20))) { die("cannot read from ".$random); } $secret = base64_encode($rnd); $params = array( "id" => $client_id, "active" => 1, "created" => time(), "secret" => $secret, "email" => array_key_exists('email', $options) ? $options['email'] : '', "notes" => array_key_exists('notes', $options) ? $options['notes'] : '', "otp" => array_key_exists('otp', $options) ? $options['otp'] : '' ); $query="INSERT INTO clients " . "(id,active,created,secret,email,notes,otp) VALUES " . "('" . $params["id"] . "', " . "'" . $params["active"] . "', " . "'" . $params['created'] . "'," . "'" . $params['secret'] . "'," . "'" . $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); exit(1); } echo $client_id.",".$secret."\n"; } fclose($fh); $myLog->log(LOG_NOTICE, "Successfully inserted generated clients into database"); yubikey-val-2.38/ykval-export-clients0000755000175000017500000000421612726004025016356 0ustar jeanjean#!/usr/bin/php 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 = $db->fetchArray($result)) { echo $row['id'] . "," . (int)$row['active'] . "," . $row['created'] . "," . $row['secret'] . "," . $row['email'] . "," . $row['notes'] . "," . $row['otp'] . "\n"; } $db->closeCursor($result); $db->disconnect(); $result=null; $db=null; yubikey-val-2.38/ykval-revoke.php0000644000175000017500000000514112726004025015452 0ustar jeanjeanaddField('ip', $_SERVER['REMOTE_ADDR']); if (!in_array ($_SERVER["REMOTE_ADDR"], $baseParams['__YKREV_IPS__'])) { logdie($myLog, "ERROR Authorization failed (logged ". $_SERVER["REMOTE_ADDR"] .")"); } # Parse input $yk = $_REQUEST["yk"]; $do = $_REQUEST["do"]; if (!$yk || !$do) { logdie($myLog, "ERROR Missing parameter"); } if (!preg_match("/^([cbdefghijklnrtuv]{0,16})$/", $yk)) { logdie($myLog, "ERROR Unknown yk value: $yk"); } if ($do != "enable" && $do != "disable") { logdie($myLog, "ERROR Unknown do value: $do"); } # Connect to db $db = Db::GetDatabaseHandle($baseParams, 'ykval-revoke'); if (!$db->connect()) { logdie($myLog, "ERROR Database connect error"); } # Check if key exists $r = $db->findBy('yubikeys', 'yk_publicname', $yk, 1); if (!$r) { logdie($myLog, "ERROR Unknown yubikey: $yk"); } # Enable/Disable the yubikey if (!$db->updateBy('yubikeys', 'yk_publicname', $yk, array('active'=>($do == "enable" ? "1" : "0")))) { logdie($myLog, "ERROR Could not $do for $yk (rows $rows)"); } # We are done logdie($myLog, "OK Processed $yk with $do"); yubikey-val-2.38/ykval-import.10000644000175000017500000000436512726004025015051 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-import "1" "January 2013" "yubico-val" .SH NAME ykval-import - Imports Yubikey Info data into the yubikey-val server. .SH SYNOPSIS .B ykval-import .SH DESCRIPTION Reads yubikey-val Yubikey Info data from stdin and imports it into the yubikey-val servers database. The data should previously have been exported using ykval-export. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-import bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-export (1) The .URL "https://developers.yubico.com/yubikey-val/doc/YubiKeyInfoFormat.html" "YubiKey Info data format" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-synchronize0000755000175000017500000000435712726004025015757 0ustar jeanjean#!/usr/bin/php addField('ip', $_SERVER['REMOTE_ADDR']); if (!in_array ($_SERVER["REMOTE_ADDR"], $baseParams['__YKRESYNC_IPS__'])) { logdie($myLog, "ERROR Authorization failed (logged ". $_SERVER["REMOTE_ADDR"] .")"); } # Parse input $yk = $_REQUEST["yk"]; if (!$yk) { logdie($myLog, "ERROR Missing parameter"); } if (!($yk == "all" || preg_match("/^([cbdefghijklnrtuv]{0,16})$/", $yk))) { logdie($myLog, "ERROR Unknown yk value: $yk"); } $myLog->addField('yk', $yk); # Connect to db $db = Db::GetDatabaseHandle($baseParams, 'ykval-resync'); if (!$db->connect()) { logdie($myLog, 'ERROR Database connect error (1)'); } if($yk == "all") { # Get all keys $res = $db->customQuery("SELECT yk_publicname FROM yubikeys WHERE active = true"); while($r = $db->fetchArray($res)) { $yubikeys[] = $r['yk_publicname']; } $db->closeCursor($res); } else { # Check if key exists $r = $db->findBy('yubikeys', 'yk_publicname', $yk, 1); if (!$r) { logdie($myLog, "ERROR Unknown yubikey: $yk"); } $yubikeys = array($yk); } /* Initialize the sync library. */ $sync = new SyncLib('ykval-resync:synclib'); $sync->addField('ip', $_SERVER['REMOTE_ADDR']); $sync->addField('yk', $yk); if (! $sync->isConnected()) { logdie($myLog, 'ERROR Database connect error (2)'); } foreach($yubikeys as $key) { if (($localParams = $sync->getLocalParams($key)) === FALSE) { logdie($myLog, 'ERROR Invalid Yubikey ' . $key); } $localParams['otp'] = $key . str_repeat('c', 32); // Fake an OTP, only used for logging. $myLog->log(LOG_DEBUG, "Auth data:", $localParams); /* Queue sync request */ if (!$sync->queue($localParams, $localParams)) { logdie($myLog, 'ERROR Failed resync'); } } # We are done logdie($myLog, "OK Initiated resync of $yk"); yubikey-val-2.38/ykval-export.10000644000175000017500000000434512726004025015056 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-export "1" "January 2013" "yubico-val" .SH NAME ykval-export - Exports Yubikey Info data from the yubikey-val server. .SH SYNOPSIS .B ykval-export .SH DESCRIPTION Outputs comma separated values containing YubiKey Info formatted data from the yubikey-val database. This data can later be imported using ykval-import. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-export bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-import (1) The .URL "https://developers.yubico.com/yubikey-val/doc/YubiKeyInfoFormat.html" "YubiKey Info data format" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-checksum-deactivated0000755000175000017500000000507112726004025017453 0ustar jeanjean#!/usr/bin/php connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); exit(1); } $everything = ""; $result=$db->customQuery("SELECT yk_publicname, yk_counter, yk_use ". "FROM yubikeys WHERE active = false ". "ORDER BY yk_publicname"); while($row = $result->fetch(PDO::FETCH_ASSOC)) { $everything .= $row['yk_publicname'] . "\t" . $row['yk_counter'] . "\t" . $row['yk_use'] . "\n"; } $hash = sha1 ($everything); if ($verbose) { print $everything; } print substr ($hash, 0, 10) . "\n"; $result=null; $db=null; yubikey-val-2.38/ykval-checksum-clients.10000644000175000017500000000450612726004025016775 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-checksum-clients "1" "January 2013" "yubico-val" .SH NAME ykval-checksum-clients - Calculate a checksum of all Client Info data. .SH SYNOPSIS .B ykval-checksum-clients .SH DESCRIPTION Calculates a checksum using the id, active, and secret fields of all Client Info data in the yubikey-val server database. This checksum can be used to easily compare the state of clients in two yubikey-val servers in the same sync pool. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-checksum-clients bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-checksum-deactivated (1) The .URL "https://github.com/Yubico/yubikey-val" "yubikey-val home page" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-log.php0000644000175000017500000000460712726004025014746 0ustar jeanjean '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', ); private $fields = array(); public function __construct ($name = 'ykval') { $this->name = $name; openlog('ykval', LOG_PID, LOG_LOCAL0); } public function addField ($name, $value) { $this->fields[$name] = $value; } public function log ($priority, $message, $extra = NULL) { $prefix = ''; foreach ($this->fields as $val) $prefix .= "[$val] "; $suffix = ''; if (is_array($extra)) { foreach($extra as $key => $value) { if (is_array($value)) { $value = implode(':', $value); } $suffix .= " $key=$value "; } } $message = $prefix . $message . $suffix; $message = implode(':', array( $this->log_levels[$priority], $this->name, $message )); syslog($priority, $message); } } yubikey-val-2.38/ykval-export-clients.10000644000175000017500000000441512726004025016513 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-export-clients "1" "January 2013" "yubico-val" .SH NAME ykval-export-clients - Exports Client Info data from the yubikey-val server. .SH SYNOPSIS .B ykval-export-clients .SH DESCRIPTION Outputs a comma separated value file containing all Client Info from the yubikey-val database. This data can later be imported using ykval-import-clients. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-export-clients bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-import-clients (1) The .URL "https://developers.yubico.com/yubikey-val/doc/ClientInfoFormat.html" "Client Info data format" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/Makefile0000644000175000017500000001737312726004025013774 0ustar jeanjean# Copyright (c) 2009-2015 Yubico AB # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. VERSION = 2.38 PACKAGE = yubikey-val CODE = COPYING Makefile NEWS README ykval-checksum-clients \ ykval-common.php ykval-config.php ykval-db.php ykval-db.sql \ ykval-export ykval-import ykval-log.php ykval-log-verify.php ykval-ping.php \ ykval-queue ykval-revoke.php ykval-synclib.php \ ykval-sync.php ykval-verify.php ykval-export-clients \ ykval-import-clients ykval-db-oci.php ykval-db-pdo.php \ ykval-db.oracle.sql ykval-resync.php ykval-checksum-deactivated \ ykval-synchronize ykval-gen-clients MANS = ykval-queue.1 ykval-import.1 ykval-export.1 \ ykval-import-clients.1 ykval-export-clients.1 \ ykval-checksum-clients.1 ykval-checksum-deactivated.1 \ ykval-synchronize.1 ykval-gen-clients.1 ykval-nagios-queuelength.1 MUNIN = ykval-munin-ksmlatency.php ykval-munin-vallatency.php \ ykval-munin-queuelength.php ykval-munin-responses.pl \ ykval-munin-yubikeystats.php ykval-munin-ksmresponses.pl NAGIOS= ykval-nagios-queuelength.php DOCS = doc/Generating_Clients.adoc doc/Getting_Started_Writing_Clients.adoc \ doc/Import_Export_Data.adoc doc/Installation.adoc doc/Make_Release.adoc \ doc/Munin_Probes.adoc doc/Revocation_Service.adoc \ doc/Server_Replication_Protocol.adoc doc/Sync_Monitor.adoc \ doc/Troubleshooting.adoc doc/Validation_Protocol_V2.0.adoc \ doc/Validation_Server_Algorithm.adoc doc/YubiKey_Info_Format.adoc all: @echo "Try 'make install' or 'make symlink'." @echo "Docs: https://developers.yubico.com/yubikey-val/doc/Installation.html" @exit 1 # Installation rules. etcprefix = /etc/yubico/val sbinprefix = /usr/sbin phpprefix = /usr/share/yubikey-val docprefix = /usr/share/doc/yubikey-val manprefix = /usr/share/man/man1 muninprefix = /usr/share/munin/plugins wwwgroup = www-data install: install -D --mode 644 ykval-verify.php $(DESTDIR)$(phpprefix)/ykval-verify.php install -D --mode 644 ykval-common.php $(DESTDIR)$(phpprefix)/ykval-common.php install -D --mode 644 ykval-synclib.php $(DESTDIR)$(phpprefix)/ykval-synclib.php install -D --mode 644 ykval-sync.php $(DESTDIR)$(phpprefix)/ykval-sync.php install -D --mode 644 ykval-resync.php $(DESTDIR)$(phpprefix)/ykval-resync.php install -D --mode 644 ykval-db.php $(DESTDIR)$(phpprefix)/ykval-db.php install -D --mode 644 ykval-db-pdo.php $(DESTDIR)$(phpprefix)/ykval-db-pdo.php install -D --mode 644 ykval-db-oci.php $(DESTDIR)$(phpprefix)/ykval-db-oci.php install -D --mode 644 ykval-log.php $(DESTDIR)$(phpprefix)/ykval-log.php install -D --mode 644 ykval-log-verify.php $(DESTDIR)$(phpprefix)/ykval-log-verify.php install -D ykval-queue $(DESTDIR)$(sbinprefix)/ykval-queue install -D ykval-synchronize $(DESTDIR)$(sbinprefix)/ykval-synchronize install -D ykval-export $(DESTDIR)$(sbinprefix)/ykval-export install -D ykval-import $(DESTDIR)$(sbinprefix)/ykval-import install -D ykval-gen-clients $(DESTDIR)$(sbinprefix)/ykval-gen-clients install -D ykval-export-clients $(DESTDIR)$(sbinprefix)/ykval-export-clients install -D ykval-import-clients $(DESTDIR)$(sbinprefix)/ykval-import-clients install -D ykval-checksum-clients $(DESTDIR)$(sbinprefix)/ykval-checksum-clients install -D ykval-checksum-deactivated $(DESTDIR)$(sbinprefix)/ykval-checksum-deactivated install -D ykval-nagios-queuelength.php $(DESTDIR)$(sbinprefix)/ykval-nagios-queuelength install -D ykval-queue.1 $(DESTDIR)$(manprefix)/ykval-queue.1 install -D ykval-synchronize.1 $(DESTDIR)$(manprefix)/ykval-synchronize.1 install -D ykval-import.1 $(DESTDIR)$(manprefix)/ykval-import.1 install -D ykval-export.1 $(DESTDIR)$(manprefix)/ykval-export.1 install -D ykval-gen-clients.1 $(DESTDIR)$(manprefix)/ykval-gen-clients.1 install -D ykval-import-clients.1 $(DESTDIR)$(manprefix)/ykval-import-clients.1 install -D ykval-export-clients.1 $(DESTDIR)$(manprefix)/ykval-export-clients.1 install -D ykval-checksum-clients.1 $(DESTDIR)$(manprefix)/ykval-checksum-clients.1 install -D ykval-checksum-deactivated.1 $(DESTDIR)$(manprefix)/ykval-checksum-deactivated.1 install -D ykval-munin-ksmlatency.php $(DESTDIR)$(muninprefix)/ykval_ksmlatency install -D ykval-munin-vallatency.php $(DESTDIR)$(muninprefix)/ykval_vallatency install -D ykval-munin-queuelength.php $(DESTDIR)$(muninprefix)/ykval_queuelength install -D ykval-munin-responses.pl $(DESTDIR)$(muninprefix)/ykval_responses install -D ykval-munin-ksmresponses.pl $(DESTDIR)$(muninprefix)/ykval_ksmresponses install -D ykval-munin-yubikeystats.php $(DESTDIR)$(muninprefix)/ykval_yubikeystats install -D --backup --mode 640 --group $(wwwgroup) ykval-config.php $(DESTDIR)$(etcprefix)/ykval-config.php install -D --mode 644 ykval-db.sql $(DESTDIR)$(docprefix)/ykval-db.sql install -D --mode 644 ykval-db.oracle.sql $(DESTDIR)$(docprefix)/ykval-db.oracle.sql install -D --mode 644 $(DOCS) $(DESTDIR)$(docprefix)/ wwwprefix = /var/www/wsapi symlink: install -d $(DESTDIR)$(wwwprefix)/2.0 ln -sf $(phpprefix)/ykval-verify.php $(DESTDIR)$(wwwprefix)/2.0/verify.php ln -sf $(phpprefix)/ykval-sync.php $(DESTDIR)$(wwwprefix)/2.0/sync.php ln -sf $(phpprefix)/ykval-resync.php $(DESTDIR)$(wwwprefix)/2.0/resync.php ln -sf 2.0/verify.php $(DESTDIR)$(wwwprefix)/verify.php revoke: install -D --mode 644 ykval-revoke.php $(DESTDIR)$(phpprefix)/ykval-revoke.php ln -sf $(phpprefix)/ykval-revoke.php $(DESTDIR)$(wwwprefix)/revoke.php # Maintainer rules. PROJECT = $(PACKAGE) $(PACKAGE)-$(VERSION).tgz: $(FILES) mkdir $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION)/doc cp $(CODE) $(MANS) $(MUNIN) $(NAGIOS) $(PACKAGE)-$(VERSION)/ cp $(DOCS) $(PACKAGE)-$(VERSION)/doc/ git2cl > $(PACKAGE)-$(VERSION)/ChangeLog tar cfz $(PACKAGE)-$(VERSION).tgz $(PACKAGE)-$(VERSION) rm -rf $(PACKAGE)-$(VERSION) dist: $(PACKAGE)-$(VERSION).tgz clean: rm -f *~ rm -rf $(PACKAGE)-$(VERSION) release: dist @if test -z "$(KEYID)"; then \ echo "Try this instead:"; \ echo " make release KEYID=[PGPKEYID]"; \ echo "For example:"; \ echo " make release KEYID=2117364A"; \ exit 1; \ fi @head -1 NEWS | grep -q "Version $(VERSION) (released `date -I`)" || \ (echo 'error: You need to update date/version in NEWS'; exit 1) @if test ! -d "$(YUBICO_GITHUB_REPO)"; then \ echo "yubico.github.com repo not found!"; \ echo "Make sure that YUBICO_GITHUB_REPO is set"; \ exit 1; \ fi gpg --detach-sign --default-key $(KEYID) $(PACKAGE)-$(VERSION).tgz gpg --verify $(PACKAGE)-$(VERSION).tgz.sig git tag -u $(KEYID) -m $(VERSION) $(PACKAGE)-$(VERSION) @echo "Release created and tagged, remember to git push && git push --tags" $(YUBICO_GITHUB_REPO)/publish $(PROJECT) $(VERSION) $(PACKAGE)-$(VERSION).tgz* yubikey-val-2.38/ykval-db.oracle.sql0000644000175000017500000000161612726004025016023 0ustar jeanjean-- I created a new sql file because oracle does not allow boolean type -- so I used the type NUMBER(1) which is pretty similar CREATE TABLE clients ( id INT NOT NULL, active NUMBER(1) DEFAULT 1, created INT NOT NULL, secret VARCHAR(60) DEFAULT '', email VARCHAR(255), notes VARCHAR(100) DEFAULT '', otp VARCHAR(100) DEFAULT '', PRIMARY KEY (id) ); CREATE TABLE yubikeys ( active NUMBER(1) DEFAULT 1, created INT NOT NULL, modified INT NOT NULL, yk_publicname VARCHAR(16) NOT NULL, yk_counter INT NOT NULL, yk_use INT NOT NULL, yk_low INT NOT NULL, yk_high INT NOT NULL, nonce VARCHAR(40) DEFAULT '', notes VARCHAR(100) DEFAULT '', PRIMARY KEY (yk_publicname) ); CREATE TABLE queue ( queued INT DEFAULT NULL, modified INT DEFAULT NULL, server_nonce VARCHAR(32) NOT NULL, otp VARCHAR(100) NOT NULL, server VARCHAR(100) NOT NULL, info VARCHAR(256) NOT NULL ); yubikey-val-2.38/COPYING0000644000175000017500000000245112726004025013356 0ustar jeanjeanCopyright (c) 2006-2015 Yubico AB All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. yubikey-val-2.38/ykval-import-clients.10000644000175000017500000000443112726004025016502 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-import-clients "1" "January 2013" "yubico-val" .SH NAME ykval-import-clients - Imports Yubikey client data into the yubikey-val server. .SH SYNOPSIS .B ykval-import-clients .SH DESCRIPTION Reads yubikey-val Client Info data from stdin and imports it into the yubikey-val servers database. Use ykval-export-clients to export data into a suitable format. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-import-clients bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-export-clients (1) The .URL "https://developers.yubico.com/yubikey-val/doc/ClientInfoFormat.html" "Client Info data format" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-munin-ksmlatency.php0000755000175000017500000000531312726004025017461 0ustar jeanjean#!/usr/bin/php PDO::ERRMODE_EXCEPTION); // for the validation server sync $baseParams['__YKVAL_SYNC_POOL__'] = array( // "https://api2.example.com/wsapi/2.0/sync", // "https://api3.example.com/wsapi/2.0/sync", // "https://api4.example.com/wsapi/2.0/sync", ); /** * An array of IP addresses which are allowed to issue sync requests to us. * * NOTE: You must use IP addresses here. Hostnames will be ignored! * Both IPv4 and IPv6 are supported. */ $baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array( // "1.2.3.4", // "2.3.4.5", // "3.4.5.6", // "fc00:aaaa::", // "fc00:bbbb::", // "fc00:cccc::", ); // An array of IP addresses allowed to issue YubiKey activation/deactivation // requests through ykval-revoke.php. NOTE: You must use IP addresses here. $baseParams['__YKREV_IPS__'] = array(/*"127.0.0.1"*/); // An array of IP addresses allowed to issue database resync requests through // ykval-resync.php. NOTE: You must use IP addresses here. // $baseParams['__YKRESYNC_IPS__'] = array("127.0.0.1"); // Use the same as for issuing sync requests: $baseParams['__YKRESYNC_IPS__'] = $baseParams['__YKVAL_ALLOWED_SYNC_POOL__']; // Specify how often the sync daemon awakens $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__'] = 10; // These are settings for the validation server. $baseParams['__YKVAL_SYNC_FAST_LEVEL__'] = 1; $baseParams['__YKVAL_SYNC_SECURE_LEVEL__'] = 40; $baseParams['__YKVAL_SYNC_DEFAULT_LEVEL__'] = 60; $baseParams['__YKVAL_SYNC_DEFAULT_TIMEOUT__'] = 1; // A key -> value array with curl options to set // when calling URLs defined in __YKVAL_SYNC_POOL__ $baseParams['__YKVAL_SYNC_CURL_OPTS__'] = array( //CURLOPT_PROTOCOLS => CURLPROTO_HTTP, ); // A key -> value array with curl options to set // when calling URLs returned by otp2ksmurls() $baseParams['__YKVAL_KSM_CURL_OPTS__'] = array( //CURLOPT_PROTOCOLS => CURLPROTO_HTTP, ); // Returns an array of YK-KSM URLs for decrypting $otp for $client. // The URLs must be fully qualified, i.e., containing the OTP itself. function otp2ksmurls ($otp, $client) { //if ($client == 42) { // return array("https://another-ykksm.example.com/wsapi/decrypt?otp=$otp"); //} //if (preg_match("/^dteffujehknh/", $otp)) { // return array("https://different-ykksm.example.com/wsapi/decrypt?otp=$otp"); //} return array( // "https://ykksm1.example.com/wsapi/decrypt?otp=$otp", // "https://ykksm2.example.com/wsapi/decrypt?otp=$otp", "http://127.0.0.1:80/wsapi/decrypt?otp=$otp", "http://127.0.0.1:8002/wsapi/decrypt?otp=$otp", ); } /** * Uncomment to log verify requests just before replying to client. * * Available variables: * %time_start% * %time_end% * %time_taken% * %ip% * %client% * %public_id% * %otp% * %status% * %nonce% * %signed% * %counter% * %low% * %high% * %use% * %tls% * %protocol% * %sl% * %timeout% * * If a value is malformed or not available, * a dash '-' is written instead. */ //$baseParams['__YKVAL_VERIFY_LOGFORMAT__'] = '[%time_start%] [%time_taken%] [%ip%] [%tls%] [%protocol%] [%status%] [%client%] [%public_id%] [%otp%] [%sl%] [%timeout%] [%nonce%] [%signed%] [%counter%] [%low%] [%high%] [%use%]'; yubikey-val-2.38/ykval-munin-vallatency.php0000755000175000017500000000527712726004025017462 0ustar jeanjean#!/usr/bin/php 0) { echo "yes\n"; exit(0); } echo "no (sync pool not configured)\n"; exit(0); } if (($endpoints = endpoints($urls)) === FALSE) { echo "Cannot parse URLs from sync pool list\n"; exit(1); } if ($argc == 2 && strcmp($argv[1], 'config') == 0) { echo "multigraph ykval_vallatency\n"; echo "graph_title VAL latency\n"; echo "graph_vlabel Average VAL Latency (seconds)\n"; echo "graph_category ykval\n"; echo "graph_width 400\n"; foreach ($endpoints as $endpoint) { list($internal, $label, $url) = $endpoint; echo "${internal}_avgwait.label ${label}\n"; echo "${internal}_avgwait.type GAUGE\n"; echo "${internal}_avgwait.info Average VAL round-trip latency\n"; echo "${internal}_avgwait.min 0\n"; echo "${internal}_avgwait.draw LINE1\n"; } exit(0); } echo "multigraph ykval_vallatency\n"; foreach ($endpoints as $endpoint) { list ($internal, $label, $url) = $endpoint; if (($total_time = total_time($url)) === FALSE) $total_time = 'error'; echo "${internal}_avgwait.value ${total_time}\n"; } exit(0); yubikey-val-2.38/ykval-munin-responses.pl0000755000175000017500000000507612726004025017162 0ustar jeanjean#!/usr/bin/perl #%# family=auto #%# capabilities=autoconf # Copyright (c) 2012-2015 Yubico AB # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; use Env qw/YKVAL_LOGFILE/; my @types = qw/OK BAD_OTP MISSING_PARAMETER BACKEND_ERROR BAD_SIGNATURE DELAYED_OTP NO_SUCH_CLIENT NOT_ENOUGH_ANSWERS REPLAYED_REQUEST REPLAYED_OTP OPERATION_NOT_ALLOWED/; my $logfile = $YKVAL_LOGFILE; $logfile = "/var/log/syslog" unless $logfile; if(@ARGV > 0) { if($ARGV[0] eq "autoconf") { print "yes\n"; exit 0; } elsif($ARGV[0] eq "config") { print "multigraph ykval_responses\n"; print "graph_title YK-VAL response types\n"; print "graph_vlabel responses\n"; print "graph_category ykval\n"; foreach my $type (@types) { print "${type}.label ${type}\n"; print "${type}.type DERIVE\n"; print "${type}.info Responses\n"; print "${type}.min 0\n"; print "${type}.draw LINE1\n"; } exit 0 } print "unknown command '${ARGV[0]}'\n"; exit 1 } my %statuses = map { $_ => 0 } @types; my $reg = qr/status=([A-Z_]+)/; open (my $file, "-|", "grep 'ykval-verify.*Response' $logfile"); while(<$file>) { next unless /$reg/; $statuses{$1}++; } close $file; print "multigraph ykval_responses\n"; foreach my $type (@types) { print "${type}.value ${statuses{$type}}\n"; } exit 0 yubikey-val-2.38/ykval-import-clients0000755000175000017500000000570712726004025016355 0ustar jeanjean#!/usr/bin/php connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); error_log("Could not connect to database"); exit(1); } while ($res=fgetcsv(STDIN, 0, ",")) { if($res[0]===null || strpos($res[0], '#')===0) continue; $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($db->rowCount($result) == 0) { // We didn't have the id in database so we need to do insert instead $query="INSERT INTO clients " . "(id,active,created,secret,email,notes,otp) VALUES " . "('" . $params["id"] . "', " . "'" . $params["active"] . "', " . "'" . $params['created'] . "'," . "'" . $params['secret'] . "'," . "'" . $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); exit(1); } } $db->closeCursor($result); } $myLog->log(LOG_NOTICE, "Successfully imported clients to database"); echo "Successfully imported clients to database\n"; yubikey-val-2.38/ykval-queue0000755000175000017500000000426612726004025014527 0ustar jeanjean#!/usr/bin/php getNumberOfServers() === 0 && $sl->getQueueLength() === 0) { $sl->log(LOG_NOTICE, 'server sync pool is empty and sync queue is also empty.'); $sl->log(LOG_NOTICE, 'configuration looks like a single node setup.'); $sl->log(LOG_NOTICE, 'ykval-queue daemon terminating.'); exit(0); } # Loop forever and resync do { $sl->reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'], $baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']); } while(sleep($baseParams['__YKVAL_SYNC_INTERVAL__'])==0); yubikey-val-2.38/ykval-nagios-queuelength.10000644000175000017500000000433612726004025017341 0ustar jeanjean.\" Copyright (c) 2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-nagios-queuelength "1" "February 2015" "yubico-val" .SH NAME ykval-nagios-queuelength - Check the current sync queuelength for the yubikey-val server. .SH SYNOPSIS .B ykval-nagios-queuelength .SH DESCRIPTION Checks the length of the current yubikey-val queuelength. Made to be used with the service nrpe and nagios. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-nagios-queuelength bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" The .URL "https://developers.yubico.com/yubikey-val/Server_Replication_Protocol.html" "Server Replication Protocol" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ChangeLog0000644000175000017500000033214412726004025014102 0ustar jeanjean2016-06-08 Jean Paul Galea * NEWS: NEWS for 2.38 2016-06-08 Jean Paul Galea * ykval-common.php: Silence php notice. - cast curl handle to integer prior to using it as an array key. 2016-05-17 Jean Paul Galea * Makefile, NEWS: Bump versions. 2016-05-17 Jean Paul Galea * NEWS: NEWS for 2.37 2016-05-17 Jean Paul Galea * ykval-verify.php: Refactor. 2016-05-17 Jean Paul Galea * ykval-verify.php: Refactor. - unset temporary variable. 2016-05-17 Jean Paul Galea * ykval-verify.php: Fix. - $request was never set if both $_POST and $_GET are empty! 2016-05-16 Jean Paul Galea * Makefile, NEWS: Bump versions. 2016-05-16 Jean Paul Galea * NEWS: NEWS for 2.36 2016-05-09 Klas Lindfors * : Merge pull request #39 from paulmenzel/grant-insert-and-update-rights-to-db-user-ykval_verifier doc/Installation: Grant insert and update rights to `ykval_verifier` 2016-04-29 Klas Lindfors * .travis.yml: add php 7.0 for travis 2016-04-29 Klas Lindfors * ykval-common.php, ykval-sync.php, ykval-verify.php: make getHttpVal() take the array to extract from refactor so verify early finds out which of $_GET and $_POST to use and then stick to using only that for the entire flow. sync only works with GET anyways so use $_GET directly. 2016-04-29 Klas Lindfors * ykval-synclib.php: use strtok() instead of explode() since we only care about first element 2016-04-29 Klas Lindfors * ykval-synclib.php: use different syntax to caputer first element of explode() call apparently not supported in 5.3 to get first element directly 2016-04-29 Klas Lindfors * ykval-synclib.php: rework re-sync to not use CURLOPT_PRIVATE relates #41 2016-04-19 Klas Lindfors * Makefile, NEWS: bump version 2016-04-19 Klas Lindfors * NEWS: news for 2.35 2016-04-19 Klas Lindfors * Makefile: add ykval-log-verify.php to the install target 2016-04-19 Jean Paul Galea * Makefile, NEWS: Bump versions. 2016-04-18 Jean Paul Galea * Makefile, NEWS: NEWS for 2.34 2016-04-18 Jean Paul Galea * ykval-log-verify.php, ykval-verify.php: Fix issue with $baseParam value. - introduced recently in these log format changes. - require_once 'ykval-config.php in logformat() did not import, because it takes place in ykval-verify.php. - hence logformat() did not have $baseParams in scope, so we never write the log line. - refactor and set format outside the class itself. 2016-04-18 Jean Paul Galea * ykval-config.php, ykval-log-verify.php, ykval-verify.php: Add sl and timeout to request log variables. 2016-04-18 Jean Paul Galea * ykval-verify.php: Make it clear that default will be a string digit. - since getHttpVal casts to string anyway. 2016-04-18 Jean Paul Galea * ykval-verify.php: Avoid ambiguity with client id. - getHttpVal always returns a string, so always treat $client as a string in other checks. 2016-04-18 Jean Paul Galea * ykval-config.php, ykval-log-verify.php, ykval-verify.php: Add tls and protocol variables to request log. 2016-04-18 Jean Paul Galea * ykval-verify.php: Rename variable. 2016-04-18 Jean Paul Galea * ykval-log-verify.php: Fix syntax errors introduced in previous commit. 2016-04-18 Jean Paul Galea * ykval-common.php, ykval-config.php, ykval-log-verify.php, ykval-log.php, ykval-verify.php: Add a verify request log line. - Traditionally we wrote two lines for each ykval-verify.php call, 'Request:' and 'Response:'. - This commit allows us to log both request/response values in a single line. - For backward compatibility, the old logging is kept in place. - To write this line to syslog, __YKVAL_VERIFY_LOGFORMAT__ needs to be set. 2016-03-14 Klas Lindfors * ykval-synclib.php: limit how many queued entries we get on each run if there's more than 1000 queued we will get another 1000 on the next run. 2016-03-07 Klas Lindfors * ykval-synclib.php: put building syncurl in a function 2016-03-07 Klas Lindfors * ykval-synclib.php: implement paralell syncing with curl_multi 2016-02-08 Paul Menzel * doc/Installation.adoc: doc/Installation: Grant insert and update rights to ykval_verifier Currently, when following the installation instructions, the scripts adding clients to the database don’t work as the user `ykval_verifier` does not have any insert rights for the table `clients`. ``` LOG_DEBUG:ykval-gen-clients:db:DB query is:SELECT id FROM clients ORDER BY id DESC LIMIT 1 LOG_DEBUG:ykval-gen-clients:db:DB query is: INSERT INTO clients (id,active,created,secret,email,notes,otp) VALUES ('1', '1', '1404359826','XXXXXXXXXXXXXXXXXXXXXXXX =','','','') LOG_INFO:ykval-gen-clients:db:Database query error: Array ( [0] => 42000 [1] => 1142 [2] => INSERT command denied to user 'ykval_verifier'@'localhost' for table 'clients' ) LOG_ERR:ykval-gen-clients:Failed to insert new client with query INSERT INTO clients (id,active,created,secret,email,notes,otp) VALUES ('1', '1', '1404359826’,’XXXXXXXXXXXXXXXXXXXXXXXX=','','','') Failed to insert new client with query INSERT INTO clients (id,active,created,secret,email,notes,otp) VALUES ('1', '1', '1404359826','XXXXXXXXXXXXXXXXXXXXXXXX =','','','')` ``` Therefore, update the documentation, to also grant the user `ykval_verifier` the rights to insert and update records into the table `clients`. No delete rights are granted, because there is an `active` column, which should probably used over deletion of clients. Note, the original idea was probably to use two database users. One for inserting and updating data, and one for querying/validating it. As, nothing is written about this though, use the existing/recommended user for both things. Fixes: #20 (ykval_verifier SQL user doesn't have permission to INSERT INTO clients, breaks ykval-gen-clients) 2016-02-05 Klas Lindfors * : Merge pull request #38 from paulmenzel/improve-documentation-for-import-export-data Improve documentation for import export data 2016-02-04 Paul Menzel * doc/Import_Export_Data.adoc: doc/Import_Export_Data: Remove trailing whitespace Run the command `StripWhitespace` from Vim Better Whitespace Plugin [1]. [1] https://github.com/ntpeters/vim-better-whitespace 2016-01-07 Klas Lindfors * : Merge pull request #37 from paulmenzel/add-install-command-for-non-deb-distributions doc/Installation: Add install commands for non-Debian distributions 2016-01-05 Klas Lindfors * : Merge pull request #36 from paulmenzel/improve-installation-documentation Improve installation documentation 2015-12-23 Paul Menzel * doc/Installation.adoc: doc/Installation: Update Ubuntu recommendation to 14.04 LTS Ubuntu 12.04 LTS will be supported until April 2017, but Ubuntu 14.04 LTS has been around long enough, so it’s well tested and probably more common to install than 12.04 LTS. It’s supported until April 2019 [1]. [1] https://wiki.ubuntu.com/Releases 2015-12-23 Paul Menzel * doc/Installation.adoc: doc/Installation: Fix wording to *The following steps apply …* 2015-12-22 Klas Lindfors * : Merge pull request #35 from paulmenzel/remove-trailing-whitespace-from-installation-documentationdoc/Installation: Remove trailing whitespace 2015-12-09 Jean Paul Galea * : Merge pull request #33 from paulmenzel/fix-typo-in-comment-of-config-file ykval-config.php: Spell *addresses* correctly in comment 2015-12-08 Paul Menzel * ykval-config.php: ykval-config.php: Use *ksm* instead of *kms* Avoid confusion and use the correct spelling for the three letter acronym KSM (Key Storage Module). 2015-12-08 Paul Menzel * ykval-config.php: ykval-config.php: Spell *addresses* correctly in comment 2015-10-05 Jean Paul Galea * Makefile, NEWS: Bump versions. 2015-10-05 Jean Paul Galea * NEWS: NEWS for 2.33 2015-09-24 Jean Paul Galea * ykval-config.php: Added localhost port 80 for ksm service. - previously the default config only included port 80. - this was changed in 382cfc2ab506a4c0f6ba0222d473ff3df77dd6f5, to avoid issues with yhsm-yubikey-ksm, which defaults to port 8002. - however, this broke configurations running with yubikey-ksm, which defaults to port 80. - a better approach is to have both projects using the same defaults, but for now we'll include both urls instead. - the ksm decrypt requests happen asynchronously, so there should not be any performance degradation. (since either one of the urls will timeout) 2015-09-15 Jean Paul Galea * ykval-verify.php: Drop some comments. - not really helpful, better to just depend on what the code does. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Refactor. - simplify and avoid using different arrays with same values. - build $otpParams from $otpinfo as soon as we have ksm result, then unset $otpinfo. - futher down, only use $otpParams and $localParams. 2015-09-15 Jean Paul Galea * ykval-verify.php: Refactor and modify LOG_INFO message. - as a result of this commit, key=val are separated with two spaces instead of one. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-15 Jean Paul Galea * ykval-verify.php: Avoid variable aliases. 2015-09-14 Jean Paul Galea * Makefile, NEWS: Bump versions. 2015-09-14 Jean Paul Galea * NEWS: NEWS for 2.32 2015-09-10 Jean Paul Galea * ykval-sync.php: Refactor. 2015-09-10 Jean Paul Galea * ykval-sync.php, ykval-verify.php: Modified log messages. - avoid doing what is already handled by the Log class. - the log name is appended automatically, so don't append it again in the invocation. i.e. "ykval-verify" - the log level name is also appended automatically, so don't append it manually, especially when it doesn't match the log priority! i.e. LOG_WARNING -> ":notice:" - fix whitespace in some messages. 2015-09-10 Jean Paul Galea * ykval-log.php: Cosmetic. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. 2015-09-10 Jean Paul Galea * ykval-log.php: Rename variable. 2015-09-10 Jean Paul Galea * ykval-log.php: Rename variable. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. - make it easier to follow, create prefix first, then suffix. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. - build separate string from $extra array, and append it in syslog call. 2015-09-10 Jean Paul Galea * ykval-log.php: Rename variable. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. 2015-09-10 Jean Paul Galea * ykval-log.php: Refactor. - init variables as class property, no need to init in construct. - set scopes on private properties, and public methods. 2015-09-10 Jean Paul Galea * ykval-common.php: Refactor. - get rid of log_format() function. - was only used in one place and it just complicates things. 2015-09-10 Jean Paul Galea * ykval-common.php: Documentation. 2015-09-10 Jean Paul Galea * ykval-common.php: Cosmetic. 2015-09-10 Jean Paul Galea * ykval-common.php: Refactor. - $urls is already checked prior to invoking function. 2015-09-10 Jean Paul Galea * Makefile, NEWS: Bump versions. 2015-09-10 Jean Paul Galea * NEWS: Cosmetic fix. 2015-09-10 Jean Paul Galea * NEWS: NEWS for 2.31 2015-09-09 Jean Paul Galea * ykval-sync.php: Fix bug. - fix fatal error when an empty sync request is sent to the server. - logging boilerplate must be initiated before we start validating the request. 2015-09-09 Jean Paul Galea * ykval-verify.php: Fix bug. - argument to sprintf, not concat to first argument! 2015-09-09 Jean Paul Galea * Makefile, NEWS: Bump versions. 2015-09-09 Jean Paul Galea * NEWS: NEWS for 2.30 2015-09-09 Jean Paul Galea * ykval-munin-vallatency.php: Fix. - add newline for munin error message. 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php, ykval-synclib.php: Refactor out function into library. 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Rewrote ykval-munin-queuelength plugin. - bring in line with ksm and val latency plugin. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Rewrite ykval-munin-ksmlatency plugin. - same as 1e4da5dac66210a85cf0e3bee739a6839edeeb46, but for ksm latency plugin. 2015-09-08 Jean Paul Galea * ykval-common.php, ykval-munin-vallatency.php: Rewrite ykval-munin-vallatency plugin. - avoid having to use the same internal and label name, as it's problematic. - internal name has a lot of restrictions: s/^[^A-Za-z_]/_/ s/[^A-Za-z0-9_]/_/g - which doesn't allow us to show proper label names, the names that users will see. - label displays :80 or :443 depending on scheme. - avoid ugliness with shortname() and instead use endpoints(). 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Cosmetic. 2015-09-08 Jean Paul Galea * ykval-common.php: Use underscore instead of colon for host/port. - munin plugin only supports a-zA-Z0-9_ so colon will probably give us problems. 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Fix. - import common, required for shortname function. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php: Add shortname failure checks for munin plugins. 2015-09-08 Jean Paul Galea * ykval-common.php, ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php: Rename function 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Modify ykval-munin-queuelength plugin. - use host (and port if any) for graph title. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php, ykval-munin-vallatency.php: Use single quotes where possible. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php, ykval-munin-vallatency.php: Use echo in all munin php plugins. 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Modify ykval-munin-queuelength plugin. - don't auto configure if running a single node cluster. (i.e. no queues for sync requests to other servers). 2015-09-08 Jean Paul Galea * ykval-munin-queuelength.php: Refactor. - move autoconf block lower down. - will be taken advantage of in a newer commit. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Modify ykval-munin-ksmlatency. - same as f2604e751abe43c2cec773194172ac90b9f89a98, except this is for KSM URLs. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Add FIXME marker. 2015-09-08 Jean Paul Galea * ykval-munin-vallatency.php: Modify ykval-munin-vallatency plugin. - don't auto configure if running a single node cluster. (i.e. no other servers to sync to). 2015-09-08 Jean Paul Galea * ykval-common.php, ykval-munin-vallatency.php: Modify ykval-munin-vallatency plugin. - use hostname (+ port if any) for graph name. i.e. if we have a sync URL: https://api.yubico.com:8080/wsapi/2.0/sync instead of having "api" as name, we have "api.yubico.com:8080". - also avoid using regex and use parse_url() from php core instead. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Rename variable. - $ksms => $urls - $ksm => $url - mainly to be closer to vallatency plugin. 2015-09-08 Jean Paul Galea * ykval-munin-vallatency.php: Cosmetic. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Rename variable. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php, ykval-munin-vallatency.php: Use bracket guards for substitution. 2015-09-08 Jean Paul Galea * ykval-common.php, ykval-munin-vallatency.php: Drop half baked functionality in ykval-munin-vallatency. - plugin assumed URL uses a hostname (no static ips) and that hostname resolves to both ipv4 and ipv6. - if we want to differentiate stats between ipv4 and ipv6, we need to re-think this and do it in a smart way. - for now we prefer to allow cURL to pick whatever IP it resolves, and run the latency test on that. - signed off by Klas Lindfors. 2015-09-08 Jean Paul Galea * ykval-checksum-clients, ykval-checksum-deactivated, ykval-export, ykval-export-clients, ykval-gen-clients, ykval-import, ykval-import-clients, ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php, ykval-nagios-queuelength.php, ykval-queue: Refactor include paths. - use PATH_SEPARATOR everywhere, instead of a mix of PATH_SEPARATOR and hard coded colons. - always include /usr/share/yubikey-val first, then /etc/yubico/val. - should not have any visible affects, since no file names are common between the two directories. - use array+implode to make it easier to add/remove paths, and to avoid hardcoded the path separator. 2015-09-08 Jean Paul Galea * ykval-munin-yubikeystats.php: Refactor. - string substitution rather than concatenation. 2015-09-08 Jean Paul Galea * ykval-munin-ksmlatency.php: Refactor ykval-munin-ksmlatency plugin. - depend on libcurl instead of curl binary. - due to this commit, requests sent to KSM URLs will contain a User-Agent header. 2015-09-08 Jean Paul Galea * ykval-common.php, ykval-munin-vallatency.php: Move function into ykval-common.php 2015-09-07 Jean Paul Galea * ykval-munin-vallatency.php: Refactor. - don't depend on external binaries, it assumes too much and is dangerous. - we can depend on libcurl instead, since it's already a dependency in core. - we should do this for other plugins too, and move the new function into ykval-common.php - plugin reports same exact values as before. 2015-09-07 Jean Paul Galea * ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php: Cosmetic changes. - refactor whitespace for munin plugins written in php. - change spaces into tabs and fix brackets mostly. 2015-08-18 Jean Paul Galea * ykval-queue: Modify ykval-queue daemon. - don't run ykval-queue for single node configurations. 2015-08-18 Jean Paul Galea * ykval-db-pdo.php: Refactor. - remove unnecessary else {} wrapper. 2015-08-18 Jean Paul Galea * ykval-db-pdo.php: Cosmetic changes. - make it easier to understand query construction. 2015-08-18 Jean Paul Galea * ykval-synclib.php: Don't set a default value for reSync argument. - reSync() is only called in ykval-queue, and that sets an $older_than argument. - additionally, the defaults did not match. - the value in ykval-queue (via ykval-config) is 10 seconds, and the value in reSync($older_than=) was 60 seconds. - no functional change, just makes things less confusing. 2015-08-12 Jean Paul Galea * ykval-verify.php: FIXME marker. 2015-08-12 Jean Paul Galea * travis/server.pl: Fix failing tests. - bug introduced in 382cfc2ab506a4c0f6ba0222d473ff3df77dd6f5. - travis perl server test should use port 8002 to simulate ksm server. 2015-07-28 Jean Paul Galea * ykval-queue: FIXME markers. 2015-07-28 Jean Paul Galea * ykval-config.php: Modify default KSM URL. - our ksm daemon listens on port 8002 by default, so ykval should also have the same default. 2015-07-24 Jean Paul Galea * ykval-verify.php: Fix. - fix bug introduced in 6181abee14aacca55e81f8d051b2ed0d2002eefa. - essentially, strftime() uses different format than date() 2015-07-24 Jean Paul Galea * ykval-verify.php: Refactor. - avoid unnecessary strtotime() call. - instead of: strtotime(date('Y-m-d H:i:s', $timestamp)) use: $timestamp since: $timestamp === strtotime(date('Y-m-d H:i:s', $timestamp)) 2015-07-24 Jean Paul Galea * ykval-verify.php: Refactor. - strftime -> date. - strftime is same as date, but with locales. - date format doesn't output names (January, March, etc.), so locale doesn't matter. - also, would we really want locale in logs? 2015-07-24 Jean Paul Galea * ykval-verify.php: Modify log write. - Log::log() internally support array implode, so no need to duplicate functionality. - however, the internal implode uses two consecutive spaces as separator, so this will change the log format slightly. e.g. "delta=x now=y" becomes "delta=x now=y" 2015-07-24 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-24 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-24 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-24 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-22 Jean Paul Galea * ykval-common.php: Refactor. - rename $curlopts -> $opts. 2015-07-22 Jean Paul Galea * ykval-common.php: Refactor. 2015-07-22 Jean Paul Galea * ykval-common.php: Refactor. - rename $handle -> $ch. 2015-07-22 Jean Paul Galea * ykval-common.php: Refactor. 2015-07-22 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-22 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-21 Jean Paul Galea * ykval-verify.php: FIXME markers. 2015-07-21 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-21 Jean Paul Galea * ykval-common.php: Refactor. 2015-07-21 Jean Paul Galea * ykval-verify.php: Better grouping. - same as 1e799aa6e57dffcb7baeb130919180bef22ea085. - group $timeout filtering and validation. - this commit might change replies sent to clients, since the validation check is done eaerlier now, and we might return S_MISSING_PARAM before S_BAD_OTP for example. - this should really not cause any issues though, the order of which error is raised first should not matter to clients. 2015-07-21 Jean Paul Galea * ykval-verify.php: Better grouping. - group $sl filtering and validation. - this commit might change replies sent to clients, since the validation check is done eaerlier now, and we might return S_MISSING_PARAM before S_BAD_OTP for example. - this should really not cause any issues though, the order of which error is raised first should not matter to clients. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor and unset after use. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - single quotes. - unset after use. - don't wrap. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-21 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - only add nonce to $extra array after check. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - $new_otp not used afterwards, clean up to avoid reuse by mistake. 2015-07-21 Jean Paul Galea * ykval-verify.php: Better grouping. - no functional affect whatsoever. 2015-07-21 Jean Paul Galea * ykval-verify.php: More robust https check. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - avoid using $_SERVER vars in "core", helps when debugging or running via cli. 2015-07-21 Jean Paul Galea * ykval-common.php: Refactor sign function. - this commit might affect LOG_DEBUG message, since now we log utf8_encode($qs) not $qs. - this is probably what we want though, since we run hash_hmac on the latter. 2015-07-21 Jean Paul Galea * ykval-verify.php: Unwrap else block. - sendResp calls exit() 2015-07-21 Jean Paul Galea * ykval-verify.php: More minor fixes. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - $apiKey is initiliased further down. 2015-07-21 Jean Paul Galea * ykval-verify.php: Refactor. - str substitution rather than concat. - cosmetic changes. 2015-07-21 Jean Paul Galea * ykval-verify.php: double -> single quotes. 2015-07-20 Jean Paul Galea * COPYING, Makefile, ykval-checksum-clients, ykval-checksum-clients.1, ykval-checksum-deactivated, ykval-checksum-deactivated.1, ykval-common.php, ykval-config.php, ykval-db-oci.php, ykval-db-pdo.php, ykval-db.php, ykval-export, ykval-export-clients, ykval-export-clients.1, ykval-export.1, ykval-gen-clients.1, ykval-import, ykval-import-clients, ykval-import-clients.1, ykval-import.1, ykval-log.php, ykval-munin-ksmlatency.php, ykval-munin-ksmresponses.pl, ykval-munin-queuelength.php, ykval-munin-responses.pl, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php, ykval-nagios-queuelength.php, ykval-ping.php, ykval-queue, ykval-queue.1, ykval-resync.php, ykval-revoke.php, ykval-sync.php, ykval-synchronize, ykval-synchronize.1, ykval-synclib.php, ykval-verify.php: Update copyright year. 2015-07-20 Jean Paul Galea * ykval-config.php: Add FIXME markers. 2015-07-20 Jean Paul Galea * ykval-synclib.php: Refactor. - negate test and return early. - avoid wrapping whole function in `if () { }`. - move $condition below $arr, since $arr is passwed first, then $condition, to conditionalUpdateBy(). 2015-07-20 Jean Paul Galea * ykval-synclib.php: Refactor. 2015-07-20 Jean Paul Galea * ykval-config.php: Improve documentation. 2015-07-20 Jean Paul Galea * ykval-config.php: Refactor database configuration. - don't repeat config-db.php file path - add @is_readable, we might not have the proper permissions. - use 'require_once' instead of 'include', this file should only be included once and we should fail dramatically if we can't load it. - better documentation. 2015-07-20 Jean Paul Galea * ykval-config.php: Cosmetic changes. \# -> // 2015-07-20 Jean Paul Galea * ykval-config.php: Cosmetic changes. 2015-07-20 Jean Paul Galea * ykval-config.php: Move comment where applicable. 2015-07-20 Jean Paul Galea * ykval-config.php: Cosmetic changes. 2015-07-20 Jean Paul Galea * ykval-config.php: Remove unused variables. - will add db host/port later, currently they are ignored even if configured. 2015-07-20 Jean Paul Galea * ykval-checksum-clients.1, ykval-checksum-deactivated.1, ykval-export-clients.1, ykval-export.1, ykval-gen-clients.1, ykval-import-clients.1, ykval-import.1, ykval-nagios-queuelength.1, ykval-queue.1, ykval-synchronize.1: Use TLS for man page www.yubico.com links. 2015-07-20 Jean Paul Galea * ykval-config.php: Use TLS in ykval-config.php examples 2015-07-18 Jean Paul Galea * ykval-synclib.php: Refactor counter logic. - break up into multiple if comparisons. 2015-07-18 Jean Paul Galea * ykval-ping.php: Single quotes. 2015-07-18 Jean Paul Galea * ykval-synclib.php: Added helper comments. 2015-07-18 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. - method grouping. 2015-07-18 Jean Paul Galea * ykval-synclib.php: Change scope on private methods. - mainly to help refactor, and avoid grep'ing globally. 2015-07-18 Jean Paul Galea * ykval-verify.php: Refactor. - getClientData() returns array or bool false on failure. 2015-07-18 Jean Paul Galea * ykval-synclib.php: Set scopes on methods. - confirmed to be used publically. 2015-07-18 Jean Paul Galea * ykval-verify.php: FIXME markers. 2015-07-18 Jean Paul Galea * ykval-common.php: Fix. - fix bug introduced in a28ad6df698b4ef20b6698a1f993019ad25bef25. 2015-07-18 Jean Paul Galea * ykval-synclib.php: Refactor. - use single quotes where possible. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: FIXME marker. - probably should be '&local_counter' not ',local_counter'. - check later as this is written to db and if we fix here, we might break other stuff. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Fix bug. - this was not introduced by my refactoring. - LOG_ALERT message was incorrect, probably yy,p from counter block. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Fix bug. - this was not introduced by my refactoring. - LOG_ALERT for; yk_low, yk_high, nonce was written only if yk_use failed to be parsed. - as a result, this commit might change LOG_ALERT output. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Refactor away useless else { } wrap. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Refactor away useless variable. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Refactor. - be explicit and declare as public, since we're clearly using it. 2015-07-17 Jean Paul Galea * ykval-resync.php, ykval-sync.php, ykval-verify.php: Refactor. - getLocalParams() returns array or bool false on failure. 2015-07-17 Jean Paul Galea * ykval-verify.php: Refactor. - str sub instead of concat. 2015-07-17 Jean Paul Galea * ykval-verify.php: Refactor. - removed duplicate variable. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Refactor. - remove unnecessary else { } wrap. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Refactor. - str sub instead of concat 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Refactor. - KSMDecryptOTP returns array or bool false on failure. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - minor improvements. - move $ret init right before it's used. - use string substitution rather than concatenation. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. - adhere with some form of convetion for comments. - use single quotes where possible. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php, ykval-synclib.php: Refactor. - retrieveURLasync() always returns FALSE on failure now, before it might have returned a string. - use array_shift($a) to pop first element, safer than $a[0]; - this commit might affect what is written to LOG_DEBUG, since now we only write the YK-KSM message when we are certain to have a valid response. 2015-07-17 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - remove counter and use count($array) instead. 2015-07-17 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - $id never used. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - use string substitution rather than concatenation. 2015-07-17 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - $mrc never used. 2015-07-17 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - enable strict comparison for sscanf result. - use single quotes where possible. - styling. 2015-07-17 Jean Paul Galea * ykval-common.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-verify.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-common.php: Fix. - introduced bug in 0d03c2be29d394a7a8a9c9617481f4b6a5ff0556. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - gmdate(, $x) already defaults to time() 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - unwrap getUTCTimeStamp() - use gmdate() instead of date_default_timezone_set('UTC') + date() 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - $status is always set in invocation, and never to null. 2015-07-17 Jean Paul Galea * ykval-common.php: Cosmetic changes. - readability. 2015-07-17 Jean Paul Galea * ykval-common.php: Refactor. - improve readability. 2015-07-17 Jean Paul Galea * ykval-sync.php: Remove broken link. 2015-07-17 Jean Paul Galea * ykval-sync.php: Cosmetic changes. - brackets, comment blocks. 2015-07-17 Jean Paul Galea * ykval-sync.php: Cosmetic changes. 2015-07-17 Jean Paul Galea * ykval-sync.php: Refactor. - use variable substitution rather than concatenation. - use single quotes where possible. 2015-07-17 Jean Paul Galea * ykval-sync.php: Refactor. - parse request before opening up a database connection and init'ing synclib. 2015-07-16 Jean Paul Galea * ykval-sync.php: Cosmetic changes. - more consistency with comment style. 2015-07-16 Jean Paul Galea * ykval-sync.php: Cosmetic changes. - spaces -> tabs 2015-07-16 Jean Paul Galea * ykval-sync.php: Cosmetic changes. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - move further down, easier to read, but no real benefit resource wise. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - check for empty request first, before opening up syslog. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - before opening up a database connection (and init synclib), verify request comes from whitelisted address first. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - $apiKey is always '' and sendResp() $apiKey argument defaults to '' 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - $allowed is easier on the eyes. - enabled in_array(, , TRUE) for strict comparision. 2015-07-16 Jean Paul Galea * ykval-sync.php: Cosmetic changes. - readability at the expense of long lines. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - merge validation into one block. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - use simple comparisons and ctype for validation, less resource intensive than regex. 2015-07-16 Jean Paul Galea * ykval-sync.php: Refactor. - $ipaddr is easier on the eyes. 2015-07-16 Jean Paul Galea * ykval-sync.php: Cosmetic changes. 2015-07-16 Jean Paul Galea * ykval-common.php, ykval-sync.php, ykval-verify.php: Refactor. - after each sendResp() we had an exit; - move exit; inside sendResp() function instead. 2015-07-16 Jean Paul Galea * ykval-synclib.php, ykval-verify.php: Unwrap function. 2015-07-16 Jean Paul Galea * ykval-synclib.php: Refactor. - syncServers was mostly always an array. - change init value from NULL to array(). - simplify getNumberOfServers. 2015-07-16 Jean Paul Galea * ykval-common.php: Prettify. 2015-07-16 Jean Paul Galea * ykval-common.php: Prettify hash_equals. 2015-07-16 Jean Paul Galea * ykval-common.php: Unwrap, only used here. 2015-07-16 Jean Paul Galea * ykval-common.php, ykval-db-pdo.php, ykval-db.php, ykval-synclib.php: Removed dead code, second try. - grep with -i switch. - left UnixToDbTime... will refactor later and unwrap to plain date() - left timestamp* methods in ykval-db, not used but might be useful while refactoring other code. 2015-07-16 Jean Paul Galea * ykval-common.php, ykval-db-pdo.php, ykval-db.php, ykval-synclib.php: Revert "Removed dead code." This reverts commit 29deb6007dd66a47ab9275687fcac140a228e404. PHP functions are __not__ case-sensitive! 2015-07-16 Jean Paul Galea * ykval-verify.php: Refactor. - better grouping for validation. 2015-07-16 Jean Paul Galea * ykval-common.php, ykval-db-pdo.php, ykval-db.php, ykval-synclib.php: Removed dead code. 2015-07-15 Jean Paul Galea * ykval-import: Cosmetic changes. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. - remove last remaining tabs, so now the whole file is using the same indentation convention. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. - make it easier to read, even though we have a couple of long lines now... 2015-07-15 Jean Paul Galea * ykval-synclib.php: Refactor. - make it easier to follow what is happenining in queue(). 2015-07-15 Jean Paul Galea * ykval-db-oci.php, ykval-db-pdo.php, ykval-db.oracle.sql: Remove trailing whitespace. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Refactor updateDbCounters. - make it easier to follow what is happening. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Refactor. - removed unnecessary else, always return at end of function. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Cosmetic changes. - use spaces where possible. 2015-07-15 Jean Paul Galea * ykval-synclib.php: Refactor. - remove wrapper which provides no help, just makes it harder to follow the code. 2015-07-15 Jean Paul Galea * ykval-sync.php: Cosmetic changes. - remove tabs/space mix. - use single quotes where possible. 2015-07-15 Jean Paul Galea * ykval-log.php: Cosmetic changes. - remove mix of tabs/spaces, use tabs everywhere. - remove mix of double/single quotes, use single quotes everywhere unless $var substitution. 2015-07-15 Jean Paul Galea * ykval-checksum-clients, ykval-checksum-deactivated, ykval-common.php, ykval-db-oci.php, ykval-db-pdo.php, ykval-db.php, ykval-export, ykval-export-clients, ykval-log.php, ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php, ykval-nagios-queuelength.php, ykval-ping.php, ykval-queue, ykval-resync.php, ykval-revoke.php, ykval-sync.php, ykval-synchronize, ykval-synclib.php, ykval-verify.php: Drop php closing tags. 2015-07-15 Jean Paul Galea * ykval-config.php: Cosmetic changes. 2015-07-02 Klas Lindfors * ykval-gen-clients: add newline in help text 2015-05-28 Klas Lindfors * : Merge pull request #30 from cam34/master Modify config-db.php include to check for file instead of doing a (fa… 2015-05-27 Klas Lindfors * Makefile, NEWS: bump versions 2015-05-27 Klas Lindfors * NEWS: NEWS for 2.29 2015-05-20 Klas Lindfors * : Merge pull request #29 from jschauma/master use https URL to allow anonymous cloning 2015-04-14 Jean Paul Galea * ykval-synclib.php: Reduce argument passing. - set curlopts directly in wrapper invocation. 2015-04-14 Jean Paul Galea * ykval-synclib.php: Set __YKVAL_SYNC_CURL_OPTS__ for resync requests. - Ensure sync/resync requests set the same curl options. - This changes a debug message from "url is " to "YK-VAL resync adding URL: " - curlopts is now a property of SyncLib class. Removes duplication between sync/resync code. 2015-04-14 Jean Paul Galea * ykval-common.php, ykval-config.php: Have enough rope to hang yourself. - Don't be overly strict, and allow users to hang themselves in they want to. 2015-04-13 Jean Paul Galea * ykval-common.php, ykval-config.php, ykval-synclib.php, ykval-verify.php: Allowed certain cURL options to be configurable. - When calling either URLs in the sync pool or the KSMs, the following curl options are configurable; CURLOPT_PROTOCOLS CURLOPT_IPRESOLVE CURLOPT_SSLVERSION CURLOPT_SSL_VERIFYPEER CURLOPT_SSL_VERIFYHOST CURLOPT_CAINFO CURLOPT_CAPATH 2015-04-13 Jean Paul Galea * ykval-config.php: Removed php closing tag. - Considered a best practice, avoids the possibility of introducing whitespace after the closing tag. 2015-02-24 Henrik StrÃ¥th * doc/Installation.adoc: Added .conf extension to Apache config files. Required in Apache 2.4. Supported in Apache 2.2. 2015-02-11 Klas Lindfors * .travis.yml: travis doesn't have php 5.2 anymore 2015-02-11 Klas Lindfors * : commit f02d5c250cf94be583f20e919b494947d5c3725b Author: Klas Lindfors Date: Wed Feb 11 09:43:41 2015 +0100 2015-02-11 Klas Lindfors * NEWS: NEWS for 2.28 2015-01-09 Dain Nilsson * Makefile, doc/Getting_Started_Writing_Clients.adoc, ykval-nagios-queuelength.1, ykval-nagios-queuelength.php: Added link to upgrade.yubico.com 2015-01-09 Dain Nilsson * doc/Getting_Started_Writing_Clients.adoc: Added link to upgrade.yubico.com 2014-11-26 Henrik StrÃ¥th * doc/Installation.adoc: Update Installation.adoc 2014-10-30 Dain Nilsson * Makefile: Fix doc/* names in Makefile. 2014-10-29 Dain Nilsson * doc/Installation.adoc: Fix __VARIABLE_NAMES__. 2014-10-29 Dain Nilsson * doc/ClientInfoFormat.adoc, doc/Client_Info_Format.adoc, doc/GeneratingClients.adoc, doc/Generating_Clients.adoc, doc/GettingStartedWritingClients.adoc, doc/Getting_Started_Writing_Clients.adoc, doc/ImportExportData.adoc, doc/Import_Export_Data.adoc, doc/Installation.adoc, doc/MakeRelease.adoc, doc/Make_Release.adoc, doc/MuninProbes.adoc, doc/Munin_Probes.adoc, doc/RevocationService.adoc, doc/Revocation_Service.adoc, doc/ServerReplicationProtocol.adoc, doc/Server_Replication_Protocol.adoc, doc/SyncMonitor.adoc, doc/Sync_Monitor.adoc, doc/Troubleshooting.adoc, doc/ValidationProtocolV20.adoc, doc/ValidationServerAlgorithm.adoc, doc/Validation_Protocol_V2.0.adoc, doc/Validation_Server_Algorithm.adoc, doc/YubiKeyInfoFormat.adoc, doc/YubiKey_Info_Format.adoc, doc/legacy/ValidationProtocolV10.adoc, doc/legacy/ValidationProtocolV11.adoc, doc/legacy/Validation_Protocol_V1.0.adoc, doc/legacy/Validation_Protocol_V1.1.adoc: Improved asciidoc formatting 2014-10-29 Henrik StrÃ¥th * README.adoc: symlinked README 2014-10-29 Henrik StrÃ¥th * README: Update README 2014-10-14 Klas Lindfors * ykval-munin-queuelength.php: refactor queuelength munin graph to show individual values as an AREASTACK graph. 2014-09-27 Dain Nilsson * ykval-common.php, ykval-verify.php: Use constant time string comparisson for validating HMAC signature (fixes #26). 2014-09-25 Klas Lindfors * Makefile, NEWS: bump versions 2014-09-25 Klas Lindfors * NEWS: release version 2.27 2014-09-25 Klas Lindfors * NEWS: NEWS for ykval-munin-ksmresponses 2014-09-25 Klas Lindfors * Makefile: install ykval-munin-ksmresponses.pl 2014-09-25 Klas Lindfors * ykval-munin-responses.pl: change to use variable file handle instead of bare-word 2014-09-25 Klas Lindfors * ykval-munin-ksmresponses.pl: add munin plugin for parsing out ksmresponses 2014-09-24 Simon Josefsson * NEWS: Doc fix. 2014-09-24 Simon Josefsson * BLURB, README: Doc fix. 2014-09-24 Henrik StrÃ¥th * doc/GettingStartedWritingClients.adoc: Fixed broken link in docs. 2014-09-24 Klas Lindfors * ykval-munin-responses.pl: take logfile from env if set, default to /var/log/syslog 2014-09-24 Simon Josefsson * ykval-sync.php, ykval-synclib.php: Drop log level of useless messages. 2014-09-24 Klas Lindfors * Makefile, NEWS: bump version 2014-09-24 Klas Lindfors * NEWS: NEWS for 2.26 2014-09-23 Klas Lindfors * ykval-log.php: make sure that we only log strings 2014-09-23 Simon Josefsson * ykval-checksum-clients, ykval-checksum-deactivated: Optimize. From Klas. 2014-09-23 Klas Lindfors * Makefile, ykval-export-clients.1, ykval-export.1, ykval-import-clients.1, ykval-import.1, ykval-sync.php, ykval-synclib.php: change wiki links 2014-09-23 Klas Lindfors * doc/ClientInfoFormat.adoc: add ClientInfoFormat from the wiki 2014-09-23 Klas Lindfors * ykval-synclib.php: move some logging in reSync() to LOG_DEBUG this is only run from ykval-queue fixes #24 2014-09-23 Klas Lindfors * ykval-common.php: raise logging on KSM response 2014-09-18 Henrik StrÃ¥th * : Merge pull request #25 from vkarlsen/master Specified that the API key has to be base64decoded 2014-09-12 Klas Lindfors * Makefile, NEWS: bump versions after release 2014-08-27 Klas Lindfors * travis/selftest.sh: again try to fix up the travis run for postfix 2014-08-27 Klas Lindfors * travis/selftest.sh: try to check if postgres is running on travis there seems to be issues where the postgres service isn't started when our tests are run, would this help? 2014-08-27 Klas Lindfors * Makefile: fixup installation of documents since they moved from .wiki extension to .adoc also add more documents to be installed fixes #23 2014-08-18 Henrik StrÃ¥th * NEWS: Update NEWS 2014-08-18 Henrik StrÃ¥th * NEWS: Updated NEWS for 2.25 release 2014-08-18 Henrik StrÃ¥th * .gitmodules: Deleted .gitmodules 2014-08-14 Klas Lindfors * doc/GeneratingClients.adoc, doc/GettingStartedWritingClients.adoc, doc/ImportExportData.adoc, doc/Installation.adoc, doc/MakeRelease.adoc, doc/MuninProbes.adoc, doc/RevocationService.adoc, doc/ServerReplicationProtocol.adoc, doc/SyncMonitor.adoc, doc/Troubleshooting.adoc, doc/ValidationServerAlgorithm.adoc, doc/YubiKeyInfoFormat.adoc: fixup formatting 2014-08-13 Henrik StrÃ¥th * doc/GettingStartedWritingClients.adoc: Update GettingStartedWritingClients.adoc 2014-08-12 Klas Lindfors * Makefile, README: drop mentions of submodules 2014-08-12 Klas Lindfors * doc/ValidationProtocolV20.adoc: add header option to all tables 2014-08-12 Klas Lindfors * doc/ValidationProtocolV20.adoc: add header option for tables 2014-08-12 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Stricter Asciidoc, that now works on opensource.yubico.com as well 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV10.adoc, doc/ValidationProtocolV11.adoc, doc/legacy/ValidationProtocolV10.adoc, doc/legacy/ValidationProtocolV11.adoc: Restructured legacy docs 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Update ValidationProtocolV20.adoc 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Update ValidationProtocolV20.adoc 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Update ValidationProtocolV20.adoc 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Update ValidationProtocolV20.adoc 2014-08-11 Henrik StrÃ¥th * doc/ValidationProtocolV20.adoc: Update ValidationProtocolV20.adoc 2014-08-11 Henrik StrÃ¥th * doc/YubiKeyInfoFormat.adoc: Update YubiKeyInfoFormat.adoc 2014-08-11 Henrik StrÃ¥th * doc/ClientInfoFormat.adoc: Delete ClientInfoFormat.adoc 2014-08-11 Henrik StrÃ¥th * doc/YubiKeyInfoFormat.adoc: Update YubiKeyInfoFormat.adoc 2014-08-11 Henrik StrÃ¥th * doc/MakeRelease.adoc: Update MakeRelease.adoc 2014-08-11 Henrik StrÃ¥th * doc/ClientInfoFormat.adoc: Update ClientInfoFormat.adoc 2014-08-11 Henrik StrÃ¥th * doc, doc/ClientInfoFormat.adoc, doc/GeneratingClients.adoc, doc/GettingStartedWritingClients.adoc, doc/ImportExportData.adoc, doc/Installation.adoc, doc/MakeRelease.adoc, doc/MuninProbes.adoc, doc/RevocationService.adoc, doc/ServerReplicationProtocol.adoc, doc/SyncMonitor.adoc, doc/Troubleshooting.adoc, doc/ValidationProtocolV10.adoc, doc/ValidationProtocolV11.adoc, doc/ValidationProtocolV20.adoc, doc/ValidationServerAlgorithm.adoc, doc/YubiKeyInfoFormat.adoc: removed submodule 2014-06-26 Klas Lindfors * .travis.yml: add php 5.6 for travis 2014-02-19 Klas Lindfors * BLURB: add BLURB 2014-01-07 Klas Lindfors * ykval-synchronize, ykval-synclib.php: always verify ssl peer fixes #15 2013-12-20 Klas Lindfors * .travis.yml: drop travis again.. apparently hhvm doesn't support -B which we use 2013-12-20 Klas Lindfors * .travis.yml: add hhvm to travis will this work? 2013-11-11 Klas Lindfors * travis/selftest.sh: skip the test of gen-client since that breaks on php 5.2 2013-11-11 Klas Lindfors * travis/selftest.sh: add output on failure 2013-11-11 Klas Lindfors * travis/selftest.sh: fix interpreter for scripts in test 2013-11-11 Klas Lindfors * travis/selftest.sh: run a validation with non-existing client 2013-11-11 Klas Lindfors * travis/selftest.sh: test generating a new client as well 2013-11-11 Klas Lindfors * travis/selftest.sh: run the export commands 2013-11-08 Simon Josefsson * tests/DbTest.php, tests/syncLibTest.php, tests/test-multi.php: Drop obsolete tests/. 2013-11-08 Klas Lindfors * .travis.yml: more php versions for the tests 2013-11-08 Klas Lindfors * .travis.yml: start with older php version 2013-11-08 Klas Lindfors * travis/selftest.sh: actually start the server component 2013-11-08 Klas Lindfors * .travis.yml, travis/selftest.sh, travis/server.pl: add travis ci for yubikey-val 2013-10-16 Klas Lindfors * ykval-common.php: let the ksm decrypt function always call retrieveUrlAsync() fixes #12 2013-09-18 Simon Josefsson * NEWS: Version 2.24. 2013-09-18 Simon Josefsson * Makefile, NEWS, README: Improve README and include in tarball. 2013-09-18 Simon Josefsson * doc: Bump. 2013-07-03 Klas Lindfors * ykval-db-oci.php: add license to ykval-db-oci.php 2013-06-11 Dain Nilsson * NEWS, ykval-gen-clients: Remove space after comma in csv output. 2013-04-19 Simon Josefsson * Makefile: Fix make release output. 2013-04-19 Simon Josefsson * Makefile: Fix check for YUBICO_GITHUB_REPO. 2013-04-17 Simon Josefsson * Makefile, NEWS: Bump version. 2013-04-17 Simon Josefsson * NEWS: Version 2.23. 2013-04-17 Simon Josefsson * Makefile: Add license to Makefile. 2013-04-17 Simon Josefsson * NEWS, ykval-common.php, ykval-config.php, ykval-sync.php, ykval-verify.php: Use LF as EOL consistently. 2013-04-17 Simon Josefsson * NEWS: Add. 2013-04-10 Dain Nilsson * Makefile: Updated release publishing. 2013-03-12 Dain Nilsson * Makefile, NEWS: Updated version number to (unreleased) 2.23 2013-03-12 Dain Nilsson * ykval-checksum-clients, ykval-checksum-deactivated, ykval-export, ykval-export-clients, ykval-gen-clients, ykval-import, ykval-import-clients, ykval-synchronize: Removed empty line from output. 2013-03-12 Dain Nilsson * NEWS: Version 2.22 2013-03-12 Simon Josefsson * ykval-verify.php: Log query for POST requests too. 2013-03-12 Dain Nilsson * doc: Updated docs. 2013-03-12 Dain Nilsson * Makefile, ykval-gen-clients.1: Added ykval-gen-clients.1 2013-03-12 Dain Nilsson * ykval-gen-clients: ykval-gen-clients -h does not include db config. 2013-03-12 Dain Nilsson * Makefile: Added ykval-gen-clients to Makefile. 2013-03-11 Dain Nilsson * NEWS, ykval-gen-clients: Added ykval-gen-clients (fixes #7) 2013-03-05 Dain Nilsson * doc: Updated doc (fixes #5). 2013-02-13 Dain Nilsson * Makefile: Added ykval-synchronize to Makefile. 2013-02-13 Dain Nilsson * ykval-synchronize.1: Added man page for ykval-synchronize. 2013-02-13 Dain Nilsson * doc: Updated doc. 2013-02-13 Dain Nilsson * Makefile: Updated version in Makefile. 2013-02-13 Dain Nilsson * NEWS: Updated NEWS. 2013-02-13 Dain Nilsson * ykval-config.php: Default to allow the same IPs for resync as for sync. 2013-02-13 Dain Nilsson * ykval-sync.php: Nitpicking 2013-02-12 Dain Nilsson * ykval-synchronize: Added script for invoking ykval-resync.php. 2013-02-12 Dain Nilsson * ykval-resync.php: Added full resync by sending yk=all. 2013-02-05 Dain Nilsson * NEWS: Updated NEWS for 2.21 release. 2013-02-05 Dain Nilsson * Makefile, NEWS: Changed release format of NEWS for consistency. 2013-02-04 Dain Nilsson * COPYING, ykval-checksum-clients, ykval-checksum-deactivated, ykval-common.php, ykval-config.php, ykval-db-pdo.php, ykval-db.php, ykval-export, ykval-export-clients, ykval-import, ykval-import-clients, ykval-log.php, ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-responses.pl, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php, ykval-ping.php, ykval-queue, ykval-resync.php, ykval-revoke.php, ykval-sync.php, ykval-synclib.php, ykval-verify.php: Updated copyright headers. 2013-02-04 Dain Nilsson * doc, ykval-sync.php, ykval-synclib.php: Updated references to old Google Code project. 2013-01-31 Dain Nilsson * NEWS, ykval-db-pdo.php: Fixed problems when no current result exists. 2013-01-31 Dain Nilsson * Makefile, NEWS: Updated NEWS and Makefile post 2.20 release. 2013-01-31 Dain Nilsson * Makefile: Added quoting of versions for Jekyll 2013-01-31 Dain Nilsson * NEWS: Updated NEWS for 2.20 2013-01-31 Dain Nilsson * doc: Updated doc. 2013-01-30 Dain Nilsson * NEWS: Updated NEWS. 2013-01-30 Dain Nilsson * Makefile: Made releases go to GitHub. 2013-01-30 Dain Nilsson * README: Updated README 2013-01-30 Dain Nilsson * doc: Updated doc. 2013-01-30 Dain Nilsson * Makefile, ykval-checksum-clients.1, ykval-checksum-deactivated.1, ykval-export-clients.1, ykval-export.1, ykval-import-clients.1, ykval-import.1, ykval-queue.1: Added man pages. 2013-01-30 Dain Nilsson * ykval-import, ykval-import-clients: Basic handling of #comments and empty lines in import tools. 2013-01-29 Dain Nilsson * Makefile, ykval-checksum-clients, ykval-checksum-clients.php, ykval-checksum-deactivated, ykval-checksum-deactivated.php, ykval-export, ykval-export-clients, ykval-export-clients.php, ykval-export.php, ykval-import, ykval-import-clients, ykval-import-clients.php, ykval-import.php, ykval-queue, ykval-queue.php: Removed file extensions of executables. 2013-01-29 Dain Nilsson * NEWS, ykval-queue.php: Removed System_Daemon. 2013-01-29 Dain Nilsson * ykval-munin-responses.pl: Made ykval-munin-responses use /var/log/syslog. 2013-01-28 Dain Nilsson * NEWS: Updated NEWS file. 2013-01-28 Dain Nilsson * ykval-export-clients.php, ykval-export.php, ykval-import-clients.php, ykval-import.php: Switched import/export scripts to use comma separation instead of tabs. 2013-01-28 Dain Nilsson * doc: Removed reference to yubikey-val-server-php in doc. 2013-01-28 Dain Nilsson * Makefile, ykval-config.php: Made ykval-config.php work out of the box. 2013-01-28 Dain Nilsson * README: Updated path to wiki in README 2013-01-28 Dain Nilsson * NEWS: Updated NEWS with path changes. 2013-01-28 Dain Nilsson * .gitmodules: Updated remote of doc submodule. 2013-01-28 Dain Nilsson * Makefile, doc, ykval-checksum-clients.php, ykval-checksum-deactivated.php, ykval-export-clients.php, ykval-export.php, ykval-import-clients.php, ykval-import.php, ykval-munin-ksmlatency.php, ykval-munin-queuelength.php, ykval-munin-vallatency.php, ykval-munin-yubikeystats.php: Use yubikey-val instead of ykval in paths, configuration in /etc/yubico/val 2013-01-24 Dain Nilsson * Makefile, NEWS: Added ChangeLog generation using git2cl. 2012-08-22 Klas Lindfors * Makefile, ykval-checksum-deactivated.php: script for checksumming deactivated YubiKeys 2012-08-22 Klas Lindfors * ykval-munin-yubikeystats.php, ykval-resync.php: mend things broken after db rewrite merge. 2012-08-21 Klas Lindfors * ykval-munin-ksmlatency.php, ykval-munin-responses.pl, ykval-munin-vallatency.php: newer munin uses variables in the plugin instead of the filename to determine graph name, make them consistent. 2012-07-05 Klas Lindfors * Makefile, NEWS: bump versions post-release 2012-07-05 Klas Lindfors * NEWS: release 2.19 2012-07-05 Klas Lindfors * NEWS: NEWS for db rewrite 2012-07-05 Klas Lindfors * : commit 0c62692871d8034626d38924a6339310f467d93d Author: Klas Lindfors Date: Wed Jul 4 13:35:25 2012 +0200 2012-06-29 Klas Lindfors * Makefile: add resync.php to Makefile 2012-06-29 Klas Lindfors * ykval-munin-yubikeystats.php: add 'as count' to sql to get it working on mysql 2012-06-29 Klas Lindfors * ykval-db-pdo.php: do $res->rowCount() instead of count($res->fetchAll()) this time for the pdo code on oracle branch. 2012-06-29 Klas Lindfors * : commit c4a6fdfc9da32718777428fa984cd9fb07f84808 Author: Klas Lindfors Date: Fri Jun 29 09:52:39 2012 +0200 2012-06-28 Remi Mollon * ykval-checksum-clients.php, ykval-db-pdo.php, ykval-export-clients.php, ykval-export.php, ykval-synclib.php: getRowValue is not needed anymore 2012-06-28 Remi Mollon * ykval-db-oci.php: fix Oracle query in findByMultiple + getRowValue is not needed anymore 2012-06-18 Fredrik Thulin * ykval-config.php: Add __YKRESYNC_IPS__ to template. 2012-06-18 Fredrik Thulin * ykval-munin-yubikeystats.php: init 2012-06-18 Fredrik Thulin * ykval-resync.php: init 2012-06-18 Fredrik Thulin * ykval-sync.php: Less verbose logging when verifying remote IP. 2012-06-15 Klas Lindfors * ykval-export-clients.php, ykval-export.php: with postgres the bool active is returned as a php bool that's casted to a string gives 1 when true and empty string when false.. cast to an int to get 1 and 0. 2012-06-15 Klas Lindfors * Makefile, NEWS: bump versions post-release 2012-06-15 Klas Lindfors * : commit 38185be07d587864b7d9d29c7403a748abc66042 Author: Fredrik Thulin Date: Fri Jun 15 11:59:42 2012 +0200 2012-06-15 Fredrik Thulin * : commit 69ec7da1769aa8126cb1b5e052e699287b0ad56b Author: Klas Lindfors Date: Fri Jun 15 10:50:39 2012 +0200 2012-06-15 Klas Lindfors * Makefile, NEWS: rollback to 2.17 2012-06-15 Klas Lindfors * Makefile: add munin pluin to MUNIN so it's included in tar 2012-06-15 Klas Lindfors * Makefile: actually install the responses munin check 2012-06-15 Klas Lindfors * Makefile, NEWS: bump versions post-release 2012-06-15 Klas Lindfors * NEWS: NEWS for 2.17 2012-06-15 Klas Lindfors * ykval-munin-responses.pl: simple munin plugin for response types 2012-06-14 Klas Lindfors * : commit 9ac5741e6c6ee369c2213e0fd34a7929180a9523 Author: Klas Lindfors Date: Thu Jun 14 16:44:19 2012 +0200 2012-06-14 Fredrik Thulin * ykval-common.php, ykval-revoke.php: Make logdie() take logger as argument. 2012-06-14 Fredrik Thulin * ykval-verify.php: Change protocol version logging to 'debug'. 2012-06-14 Fredrik Thulin * ykval-common.php, ykval-verify.php: Get rid of debug() - use log_format() for the formatting part. 2012-06-14 Fredrik Thulin * ykval-synclib.php: Remove now unused retrieveURLasync_old() 2012-06-14 Fredrik Thulin * : commit c8e9eb828f85e0a5a54727bc99560cea5aafa381 Author: Fredrik Thulin Date: Thu Jun 14 15:19:04 2012 +0200 2012-06-14 Klas Lindfors * ykval-common.php, ykval-sync.php, ykval-verify.php: instead of passing context to sendResp, give it a logger. 2012-06-14 Fredrik Thulin * ykval-common.php: minor debug log fixes 2012-06-14 Fredrik Thulin * : commit 01969a279e54baa4be63610490d17163249aee84 Author: Klas Lindfors Date: Thu Jun 14 14:55:50 2012 +0200 2012-06-14 Fredrik Thulin * ykval-synclib.php: Use retrieveURLasync in ykval-common instead. 2012-06-14 Fredrik Thulin * ykval-common.php: retrieveURLasync: logging using ident string 2012-06-14 Fredrik Thulin * ykval-common.php: retrieveURLasync: cater for the last need in ykval-synclib. 2012-06-14 Fredrik Thulin * ykval-common.php: retrieveURLasync: make timeout an argument 2012-06-14 Fredrik Thulin * ykval-common.php: Move de-arraying out of retrieveURLasync. 2012-06-14 Klas Lindfors * ykval-synclib.php: if the remote sync site says BAD_OTP log and remove from queue 2012-06-14 Fredrik Thulin * ykval-sync.php: Restore responding BAD_OTP if YubiKey is disabled. It seems that we might get into problems if responding OK - the other sync client validation server would think we approved of the OTP. 2012-06-14 Klas Lindfors * : commit b5849acef1fabc4de679a98f827009771eff2244 Merge: cb0de9d 6dd5501 Author: Fredrik Thulin Date: Thu Jun 14 13:01:10 2012 +0200 2012-06-14 Fredrik Thulin * ykval-config.php: Add __YKREV_IPS__ to template. 2012-06-14 Klas Lindfors * ykval-db-oci.php: lowercase columns from oracle, we use lower everywhere. 2012-06-14 Fredrik Thulin * ykval-sync.php: Don't refuse sync for disabled YubiKeys. It is better to consume any OTPs produced by a YubiKey, so if - for some reason - another validation server has accepted an OTP we'd better bump our counter values accordingly. 2012-06-14 Fredrik Thulin * ykval-db-oci.php: Check for ^oci: instead of just ^oci. 2012-06-13 Klas Lindfors * : commit 6dd55013f993f6a26b670ed7cffa4f7d61578d3d Author: Klas Lindfors Date: Wed Jun 13 14:45:37 2012 +0200 2012-06-13 Fredrik Thulin * ykval-synclib.php: delete-trailing-whitespace 2012-06-13 Klas Lindfors * ykval-db.oracle.sql: 40 char nonce for oracle as well 2012-06-13 Fredrik Thulin * ykval-synclib.php: Don't LOG_NOTICE when remote server has seen latest OTP too. This is an expected condition for many (most) validation requests using the asynchronous validation protocol 2.0. 2012-06-13 Fredrik Thulin * ykval-synclib.php: Logging improvements. 2012-06-13 Fredrik Thulin * ykval-sync.php: Downgrade 'Sync request unnecessarily sent' to INFO. Also add comment explaining that this is not an error (and why). 2012-06-13 Klas Lindfors * : commit a41b7476ac780f7b10609221c6c4e6b171410da3 Author: Klas Lindfors Date: Wed Jun 13 09:55:42 2012 +0200 2012-06-13 Klas Lindfors * Makefile: fix version check for this NEWS format. 2012-06-13 Klas Lindfors * NEWS: NEWS for 2.16 2012-06-13 Klas Lindfors * ykval-sync.php: if the sync request is empty, drop it as early as possible. 2012-06-13 Klas Lindfors * ykval-export-clients.php: change ] to ) 2012-06-13 Klas Lindfors * ykval-synclib.php: and { is needed. 2012-06-13 Klas Lindfors * ykval-synclib.php: findByMultiple() calls fetchArray on it's own result, just loop it. 2012-06-13 Klas Lindfors * ykval-checksum-clients.php: remove $this, not in object context 2012-06-12 Fredrik Thulin * ykval-synclib.php: Use consistent camel-casing of function countersEqual(). Reduces confusion, even though PHP apparently has case insensitive function names. 2012-06-12 Klas Lindfors * : commit af292fbcd60e514c22192acdf4753d5bcd443e3b Author: Fredrik Thulin Date: Tue Jun 12 14:50:31 2012 +0200 2012-06-12 Klas Lindfors * ykval-db-oci.php, ykval-db-pdo.php: make query protected, accessed from super class 2012-06-12 Klas Lindfors * ykval-db.php: remove bareword oci 2012-06-12 Fredrik Thulin * ykval-sync.php: More explanatory logging. 2012-06-12 Fredrik Thulin * : commit 929e7aedc9280bda411d3aadb83e4490699e8503 Author: Klas Lindfors Date: Tue Jun 12 13:47:22 2012 +0200 2012-06-12 Klas Lindfors * : commit a648a3f66e1771d28d3c89aed74cf21708eef46b Author: Klas Lindfors Date: Tue Jun 12 13:45:40 2012 +0200 2012-06-12 Klas Lindfors * ykval-db-oci.php, ykval-db-pdo.php: extends properly 2012-06-12 Klas Lindfors * ykval-db.oracle.sql: sql for initing oracle 2012-06-12 Klas Lindfors * ykval-checksum-clients.php, ykval-db-oci.php, ykval-db-pdo.php, ykval-db.php, ykval-export-clients.php, ykval-export.php, ykval-import-clients.php, ykval-import.php, ykval-revoke.php, ykval-synclib.php: more oracle compatibility 2012-06-12 Klas Lindfors * ykval-checksum-clients.php, ykval-config.php, ykval-export.php, ykval-import.php, ykval-synclib.php, ykval-verify.php: rest of oracle patches from Remi Mollon 2012-06-12 Klas Lindfors * ykval-db-oci.php, ykval-db-pdo.php, ykval-db.php: start work on integrating oracle patches from Remi Mollon 2012-06-12 Klas Lindfors * .gitignore: ignore release artifacts 2012-06-11 Klas Lindfors * : commit 4337fd13df86330f8d70660b1fcddd53bad22c66 Author: Klas Lindfors Date: Mon Jun 11 12:50:57 2012 +0200 2012-06-11 Klas Lindfors * ykval-synclib.php: use one curl-handle per server does connection re-use while syncing to that server 2012-05-29 Fredrik Thulin * ykval-sync.php: Slightly less verbose log for remote IP check. 2012-05-29 Fredrik Thulin * ykval-sync.php, ykval-synclib.php: Improve logging of refused sync requests. 2012-05-29 Fredrik Thulin * ykval-checksum-clients.php, ykval-common.php, ykval-config.php, ykval-db.php, ykval-export-clients.php, ykval-export.php, ykval-import-clients.php, ykval-import.php, ykval-log.php, ykval-ping.php, ykval-queue.php, ykval-revoke.php, ykval-sync.php, ykval-synclib.php, ykval-verify.php: delete-trailing-whitespace 2012-05-25 Fredrik Thulin * : commit 6b1e08eca81e1175ca2a0b8a9e9097ec66b02ca4 Author: Fredrik Thulin Date: Fri May 25 10:58:52 2012 +0200 2012-05-24 Klas Lindfors * Makefile, NEWS: bump versions 2012-05-24 Klas Lindfors * NEWS: NEWS for 2.15 2012-05-24 Klas Lindfors * ykval-verify.php: check if $sl or $timeout is empty, if they are insert default 2012-05-23 Klas Lindfors * ykval-import.php: use fgetcsv instead of fscanf, handles empty fields 2012-05-23 Klas Lindfors * ykval-export-clients.php, ykval-import-clients.php: add scripts for exporting and importing the clients 2012-05-22 Klas Lindfors * Makefile, NEWS: Bump version 2012-05-22 Klas Lindfors * NEWS: News for 2.14 2012-05-22 Klas Lindfors * : commit 3de7ca3c8b3e8706867c8b0571008f3e02432e42 Author: Klas Lindfors Date: Tue May 22 13:15:25 2012 +0200 2012-05-22 Fredrik Thulin * ykval-munin-ksmlatency.php, ykval-munin-vallatency.php: Detect timeouts and errors in curl (such as resolver failures). 2012-05-22 Simon Josefsson * ykval-db.php: Silence PHP warning. 2012-05-21 Simon Josefsson * ykval-munin-queuelength.php, ykval-synclib.php, ykval-verify.php: Silence PHP warnings. 2012-05-21 Simon Josefsson * ykval-munin-ksmlatency.php: Chmod. 2012-05-16 Klas Lindfors * Makefile, NEWS: bump version 2012-05-16 Klas Lindfors * Makefile: set version to 2.13 2012-05-16 Klas Lindfors * NEWS: News for 2.13 2012-05-16 Klas Lindfors * ykval-common.php: use urldecode(http_build_request()) instead of looping and building request string 2012-05-16 Klas Lindfors * ykval-verify.php: build up the array to sign by taking $_GET or $_POST and remove the h key 2012-05-14 Klas Lindfors * ykval-checksum-clients.php: check if $argv[1] is set before trying to access it 2012-05-14 Klas Lindfors * ykval-checksum-clients.php: need ykval-config.php before ykval-db.php 2012-05-10 Klas Lindfors * NEWS: Bump version 2012-05-09 Klas Lindfors * Makefile: ange how we name the tag to be consistent with old tags 2012-05-09 Klas Lindfors * NEWS: News for 2.12 2012-05-08 Klas Lindfors * ykval-verify.php: update comment about nonce to reflect what the code actually does enforce 2012-05-08 Klas Lindfors * ykval-db.sql: raise nonce limit to 40 chars as that's what we say in the documentation 2012-02-22 Klas Lindfors * README: basic README 2012-02-22 Klas Lindfors * ykval-verify.php: fix fast or secure strings as sl move transformation of strings for sync and default values for sync and timeout to before sanity checking. 2012-02-22 Klas Lindfors * Makefile: make sure we have the doc submodule and that it's updated before we copy docs 2012-02-22 Klas Lindfors * .gitmodules, doc: adding doc from github wiki as submodule 2012-02-22 Simon Josefsson * Makefile: change svn copying tag to git tag + push 2012-01-23 Simon Josefsson * NEWS: Bump version. 2012-01-23 Simon Josefsson * COPYING, Makefile: Bump version and copyright information. 2011-11-16 Simon Josefsson * NEWS: Version 2.11. 2011-11-14 Simon Josefsson * ykval-synclib.php: Remove rowCount entries instead, it reset the search result. 2011-11-14 Simon Josefsson * NEWS, ykval-synclib.php: Fix two remaining non-portable uses of rowCount. 2011-11-01 Simon Josefsson * Makefile, NEWS: Install non-bin PHP files with --mode 644 to avoid executable bit. 2011-10-31 Simon Josefsson * NEWS: Credit. 2011-10-31 Simon Josefsson * NEWS, ykval-export.php, ykval-import.php: Reorder include's to allow for dbi-settings through ykval-config.php. From Fredrik. 2011-10-31 Simon Josefsson * Makefile, NEWS: Support for DESTDIR in 'make install'. 2011-10-31 Simon Josefsson * Makefile, NEWS: Include munin scripts in tarball. 2011-10-25 Simon Josefsson * COPYING, Makefile, NEWS: Update NEWS and release info. 2011-10-25 Simon Josefsson * ykval-common.php, ykval-db.php, ykval-verify.php: Tiny fixes to silence PHP warnings from Hiroki Nose . 1. PHP Notice: Use of undefined constant CURL_OK - assumed 'CURL_OK' in /usr/share/ykval/ykval-common.php on line 156 2. PHP Notice: Undefined index: HTTPS in /usr/share/ykval/ykval-verify.php on line 14 3. PHP Notice: Undefined variable: query in /usr/share/ykval/ykval-db.php on line 186 2011-08-18 Simon Josefsson * NEWS: Version 2.10. 2011-08-18 Simon Josefsson * Makefile: Fix release rule. 2011-08-18 Simon Josefsson * Makefile, NEWS, ykval-verify.php: Don't echo (unsanitized) OTP/NONCE values back to client when sending error codes. Reported by Paul van Empelen. 2011-05-09 Simon Josefsson * Makefile: Fix OpenPGP key. 2011-05-09 Simon Josefsson * Makefile, NEWS, ykval-revoke.php: Support multiple IP authorizations in ykval-revoke.php. 2011-01-06 Simon Josefsson * NEWS: Version 2.8. 2010-11-15 Simon Josefsson * ykval-munin-ksmlatency.php: Simplify more. 2010-11-15 Simon Josefsson * ykval-munin-ksmlatency.php: Simplify. 2010-11-15 Simon Josefsson * NEWS: Add. 2010-11-15 Simon Josefsson * Makefile: Install ykval-munin-vallatency. 2010-11-15 Simon Josefsson * ykval-munin-vallatency.php: Add. 2010-09-21 Simon Josefsson * Makefile, NEWS, ykval-verify.php: Support YubiKey OTPs filtered through a US Dvorak keyboard layout. 2010-09-12 Simon Josefsson * Makefile: Fix version. 2010-09-12 Simon Josefsson * NEWS: Version 2.7. 2010-09-12 Simon Josefsson * ykval-verify.php: Fix typo. 2010-09-12 Simon Josefsson * NEWS: Add. 2010-09-12 Simon Josefsson * ykval-common.php, ykval-verify.php: Sanity check OTP variable before trusting it. Reported by Ricky Zhou . 2010-08-22 Simon Josefsson * NEWS, ykval-verify.php: Log HTTPS status. 2010-08-22 Simon Josefsson * NEWS, ykval-common.php: Timestamp responses. 2010-08-22 Simon Josefsson * NEWS, ykval-verify.php: Timestamp requests. 2010-08-02 Simon Josefsson * Makefile, NEWS: Bump versions. 2010-08-02 Simon Josefsson * Makefile, NEWS: Version 2.6. 2010-08-02 Simon Josefsson * NEWS: Mention queuelength plugin. 2010-08-02 Simon Josefsson * Makefile, ykval-munin-queuelength.php: Add ykval-munin-queuelength.php. 2010-06-22 Simon Josefsson * NEWS: Add. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Reduce max-time. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Fix auto markers. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Add auto markers. 2010-06-22 Simon Josefsson * Makefile: Fix munin plugin name. 2010-06-22 Simon Josefsson * Makefile: Better install name. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Fix typo. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Support autoconf. 2010-06-22 Simon Josefsson * Makefile: Install munin plugin. 2010-06-22 Simon Josefsson * ykval-munin-ksmlatency.php: Add munin checker. 2010-06-10 Simon Josefsson * ykval-revoke.php: MySQL does not parse 'TRUE' as a true boolean, use '1' instead. 2010-06-01 Simon Josefsson * Makefile: Bump version. 2010-06-01 Simon Josefsson * NEWS: Add. 2010-06-01 Simon Josefsson * ykval-revoke.php: Don't use rowCount, it is broken. 2010-05-17 Simon Josefsson * Makefile: Use yubico google account. 2010-05-17 Simon Josefsson * NEWS: Version 2.5 2010-05-17 Simon Josefsson * NEWS, ykval-db.php, ykval-synclib.php: Don't use PDO rowCount function to get number of rows returned because that isn't portable. Patch from arte42.ripe in issue #7 (yubikey-val-2.1-php-rowcount.patch). 2010-05-17 Simon Josefsson * NEWS: Fix. 2010-05-17 Simon Josefsson * NEWS, ykval-common.php: When there is only one KSM, use more portable code without async. Patch from arte42.ripe in issue #7. 2010-05-17 Simon Josefsson * NEWS, ykval-verify.php: When number of sync servers equals zero, set sync result to success. Patch from arte42.ripe in issue #7. 2010-04-23 Simon Josefsson * ykval-verify.php: Don't reject on nonce error for v1.x requests. 2010-04-23 Simon Josefsson * ykval-verify.php: Permit somewhat longer nonces (think SHA1 hex). 2010-04-23 Simon Josefsson * ykval-verify.php: Improve error checking of nonce. 2010-04-23 Simon Josefsson * Makefile, ykval-api.html: Remove, see wiki pages instead. 2010-04-23 Simon Josefsson * NEWS: Add. 2010-04-23 Simon Josefsson * Makefile: Distribute COPYING file. 2010-04-23 Simon Josefsson * AUTHORS, Makefile, ykval-db.php: Simplify license headers. 2010-04-23 Simon Josefsson * COPYING: Add file. 2010-04-23 Simon Josefsson * Makefile, NEWS: Add. 2010-04-23 Simon Josefsson * ykval-db.php, ykval-sync.php, ykval-synclib.php: Fix undefined warnings. Solves Issue #8. 2010-03-16 Simon Josefsson * NEWS: Add dates. 2010-03-12 Simon Josefsson * Makefile: Bump version. 2010-03-12 Simon Josefsson * ykval-checksum-clients.php: Typo. 2010-03-12 Simon Josefsson * NEWS: Add. 2010-03-12 Simon Josefsson * ykval-checksum-clients.php: Work around PostgreSQL bug. 2010-03-12 Simon Josefsson * Makefile: Bump version. 2010-03-12 Simon Josefsson * Makefile: Don't overwrite live config file. 2010-03-12 Simon Josefsson * Makefile, NEWS, ykval-checksum-clients.php: Add ykval-checksum-clients. 2010-02-22 Simon Josefsson * NEWS: Add. 2010-02-22 Simon Josefsson * Makefile: Fix DOCS. 2010-02-22 Simon Josefsson * Makefile: Increment version. 2010-02-22 Simon Josefsson * Makefile: Add revoke target. 2010-02-22 Simon Josefsson * ykval-revoke.php: Error checking. 2010-02-22 Simon Josefsson * ykval-revoke.php: Simplify. 2010-02-22 Simon Josefsson * ykval-revoke.php: Add. 2010-02-22 Simon Josefsson * ykval-common.php: More debugging. 2010-02-22 Simon Josefsson * ykval-synclib.php: Whitespace. 2010-02-22 Simon Josefsson * ykval-common.php: Re-add, some duplication but needed by KSMdecryptOTP. 2010-02-22 Simon Josefsson * ykval-common.php: Remove (hopefully) unused stuff. 2010-01-30 Simon Josefsson * Makefile: Fix dist rules. 2010-01-30 Simon Josefsson * Makefile, NEWS: Prepare v2.1. 2010-01-25 Olov Danielson * ykval-import.php: . 2010-01-25 Olov Danielson * ykval-export.php: Use order by to know order of yubikeys 2010-01-25 Olov Danielson * ykval-import.php: changed insert syntax to comply with postgresql 2010-01-25 Olov Danielson * ykval-import.php: added '' around yk_publicname 2010-01-25 Olov Danielson * ykval-import.php: changed permissions 2010-01-25 Olov Danielson * Makefile: Added ykval-import 2010-01-25 Olov Danielson * ykval-import.php: added 2010-01-25 Olov Danielson * ykval-export.php: close result? 2010-01-25 Olov Danielson * ykval-export.php: Close db after finish 2010-01-25 Olov Danielson * ykval-export.php: added incudepath 2010-01-25 Olov Danielson * ykval-export.php: Added include path 2010-01-25 Olov Danielson * Makefile: Added ykval-export 2010-01-25 Olov Danielson * ykval-export.php: Added 2010-01-25 Simon Josefsson * ykval-synclib.php: Drop internalname. Fix nonce. 2010-01-25 Simon Josefsson * ykval-db.sql: Drop unused column. 2010-01-25 Olov Danielson * ykval-sync.php: Use -1 in yk_counter etc. to indicate yubikey discovered in protocol 2010-01-25 Simon Josefsson * ykval-synclib.php: Fix modified/nonce. 2010-01-25 Simon Josefsson * ykval-synclib.php: Use -1 for non-existing YubiKey. 2010-01-25 Simon Josefsson * ykval-db.sql: Add NOT NULL. 2010-01-25 Olov Danielson * ykval-synclib.php: When new OTP is discovered, local DB is set to yk_counter=-1 and yk_use=-1 . 2010-01-25 Olov Danielson * ykval-otpgen.php: Removed systemtests from this lib 2010-01-20 Olov Danielson * ykval-verify.php: Corrected spelling error for replayed_request 2010-01-20 Olov Danielson * ykval-verify.php: Added otp, nonce in all responses for protocol >= 2.0. 2010-01-19 Olov Danielson * systemtests/setupTest.php, ykval-otpgen.php: missing require 2010-01-19 Olov Danielson * ykval-verify.php: . 2010-01-19 Olov Danielson * ykval-verify.php: In protocol versions less than 2.0, nonce needs to added by server. This must be done after signature is computed. 2010-01-19 Simon Josefsson * Makefile: Fix release targets. 2010-01-19 Simon Josefsson * NEWS: Add. 2010-01-18 Olov Danielson * systemtests/setupTest.php, ykval-otpgen.php: Added systemtest functionality. System tests unders systemtests/ 2010-01-14 Simon Josefsson * ykval-verify.php: Fix last commit. 2010-01-14 Simon Josefsson * ykval-verify.php: Review fixes. 2010-01-14 Olov Danielson * ykval-db.php, ykval-queue.php, ykval-synclib.php: Refactored. Db log gets name after synclib + db now. 2010-01-14 Olov Danielson * tests/syncLibTest.php, ykval-synclib.php: refactoring. removed unneccessary SQL query 2010-01-14 Olov Danielson * ykval-db.php, ykval-sync.php, ykval-synclib.php, ykval-verify.php: . 2010-01-14 Simon Josefsson * ykval-log.php: Use openlog. 2010-01-14 Olov Danielson * ykval-db.php: . 2010-01-14 Olov Danielson * ykval-log.php: Log module logs log_level as well 2010-01-14 Olov Danielson * ykval-log.php, ykval-sync.php, ykval-verify.php: Added possibility to use custom fields in logging module. Also added client IP and otp in verify and sync logs. 2010-01-14 Olov Danielson * ykval-sync.php, ykval-synclib.php, ykval-verify.php: Added a few checks for input parameters and corrected warnings according to new docuemnt 2010-01-13 Olov Danielson * ykval-db.php, ykval-verify.php: . 2010-01-13 Simon Josefsson * ykval-config.php: Use names again. 2010-01-13 Olov Danielson * ykval-sync.php, ykval-synclib.php: Corrected a few log entries 2010-01-12 Olov Danielson * ykval-synclib.php: . 2010-01-12 Olov Danielson * ykval-synclib.php: . 2010-01-12 Olov Danielson * ykval-db.php: . 2010-01-12 Olov Danielson * ykval-synclib.php: when creatin yubikey entries all values better be filled in 2010-01-12 Olov Danielson * ykval-synclib.php: . 2010-01-12 Olov Danielson * ykval-verify.php: . 2010-01-12 Olov Danielson * tests/DbTest.php, tests/syncLibTest.php, ykval-db.php, ykval-db.sql, ykval-synclib.php, ykval-verify.php: Remove ID column from yubikeys and queue table. Renamed and changed random_key to server_nonce 2010-01-11 Simon Josefsson * ykval-queue.php: Fix startup code. 2010-01-11 Simon Josefsson * ykval-config.php: Fix. 2010-01-11 Simon Josefsson * ykval-config.php: fix 2010-01-11 Simon Josefsson * ykval-config.php: Fix. 2010-01-11 Simon Josefsson * .htaccess, Makefile: Remove .htaccess. 2010-01-11 Olov Danielson * Makefile: Removed .php on ykval-queue install 2010-01-11 Olov Danielson * ykval-queue.php: Takes path argument on commandline 2010-01-11 Simon Josefsson * ykval-synclib.php: Cleanup. 2010-01-11 Olov Danielson * Makefile: Added queue and log 2010-01-11 Simon Josefsson * ykval-db.sql: Simplify SQL. 2010-01-11 Olov Danielson * ykval-log.php: ops, ykval-log file needed as well. 2010-01-11 Olov Danielson * ykval-common.php, ykval-db.php, ykval-queue.php, ykval-sync.php, ykval-synclib.php, ykval-verify.php: Unified logging to use Log class defined in ykval-log.php which in turn uses syslog. NOTE: ykval common debug function is still available but uses Log class aswell to actually log message. 2010-01-11 Olov Danielson * ykval-sync.php: Spelling error corrected 2010-01-11 Olov Danielson * ykval-config.php, ykval-sync.php: Only allowed sync requests from specified IP addresses 2010-01-10 Olov Danielson * ykval-queue.php: Added help description to sync daemon 2010-01-10 Olov Danielson * tests/DbTest.php, ykval-db.php: corrected. Rowcount acts on last statement result rather on db 2010-01-10 Olov Danielson * ykval-db.php, ykval-synclib.php: Added rowcount function to db 2010-01-10 Olov Danielson * ykval-config.php, ykval-daemon, ykval-db.php, ykval-queue.php, ykval-queuedaemon.php, ykval-synclib.php: Rewritten sync daemon to work in a sequential way. Now called ykval-queue.php 2010-01-08 Olov Danielson * tests/DbTest.php, tests/syncLibTest.php, ykval-config.php, ykval-db.php, ykval-synclib.php, ykval-verify.php: Changed to using PDO database connection 2010-01-08 Olov Danielson * tests/DbTest.php, tests/syncLibTest.php, ykval-daemon, ykval-db.php, ykval-db.sql, ykval-queuedaemon.php, ykval-sync.php, ykval-synclib.php, ykval-verify.php: Changed DB-names to be more consistent (WARNING current revision might be broken but needs to be submitted for multiserver test purposes) 2009-12-15 Simon Josefsson * test-multi.php, tests/test-multi.php: Move. 2009-12-15 Simon Josefsson * ykval-config.php, ykval-revoke.php: Remove. 2009-12-15 Simon Josefsson * Makefile: Improve. 2009-12-15 Simon Josefsson * ykval-db.sql: Simplify. 2009-12-15 Simon Josefsson * Makefile: fix 2009-12-15 Simon Josefsson * Makefile: fix 2009-12-15 Simon Josefsson * : rm. 2009-12-15 Simon Josefsson * tests/DbTest.php, tests/syncLibTest.php, ykval-synclib.php: Fix filename. 2009-12-15 Simon Josefsson * Makefile, lib/Db.php, ykval-db.php: Add install target. 2009-12-15 Simon Josefsson * Makefile, get-api-key/index.php, ykval-config.php, ykval-db.sql, ykval-getapikey.php: Remove getapikey service. 2009-12-15 Simon Josefsson * ykval-config.php: Add comments. 2009-12-15 Olov Danielson * ykval-synclib.php: change nonce to allow alphanumeric characters 2009-12-15 Olov Danielson * ykval-db.sql: nonce introduced 2009-12-15 Olov Danielson * lib/Db.php, tests/syncLibTest.php, ykval-common.php, ykval-db.sql, ykval-sync.php, ykval-synclib.php, ykval-verify.php: 1. Nonce introduced in protocol. This required changes in the chain from client->verify->sync. 2. ykval-verify is modified a bit. It now acts more as a flow controller and relies on ykval-synclib to do details on DB-calls and counterlogic. The "system" decision making is still located in ykval-verify. 2009-12-08 Olov Danielson * ykval-synclib.php, ykval-verify.php: Corrected calculation of hmac with extra parameters (protocol v. 2). Corrected calculation of sl return value (use float inside) 2009-12-08 Olov Danielson * ykval-daemon: Added sync daemon 2009-12-08 Olov Danielson * ykval-verify.php: sl parameter returned on "NOT_ENOUGH_ANSWERS" 2009-12-07 Olov Danielson * ykval-config.php, ykval-synclib.php, ykval-verify.php: Taking care of sl and timeout parameters in new protocol 2009-12-07 Olov Danielson * lib/Db.php, ykval-synclib.php: changed updateDbParams function to only update counters if they are newer than before 2009-12-07 Olov Danielson * ykval-config.php, ykval-synclib.php: . 2009-12-07 Olov Danielson * ykval-queuedaemon.php: . 2009-12-07 Olov Danielson * ykval-config.php, ykval-db.sql, ykval-queuedaemon.php, ykval-synclib.php: Moved config to ykval-config 2009-12-07 Olov Danielson * ykval-synclib.php: . 2009-12-07 Olov Danielson * ykval-synclib.php: iremoved echos 2009-12-07 Olov Danielson * tests/syncLibTest.php, ykval-queuedaemon.php, ykval-synclib.php: Added first version of queue daemon 2009-12-04 Olov Danielson * ykval-synclib.php: fixed bug. When only partial answer were received, the queue delete functionality didn't work 2009-12-04 Olov Danielson * ykval-config.php: . 2009-12-04 Olov Danielson * tests/syncLibTest.php, ykval-common.php, ykval-db.sql, ykval-synclib.php, ykval-verify.php: Storing local param info at the time when verify request arrived. Used to give correct warnings of wether local/remote is out of sync or not 2009-12-04 Olov Danielson * ykval-synclib.php: changed structure of info in db 2009-12-03 Olov Danielson * ykval-synclib.php: Added modified and otp parameter to sync requests from synclib 2009-12-02 Olov Danielson * lib/Db.php, tests/DbTest.php, tests/syncLibTest.php, ykval-common.php, ykval-config.php, ykval-db.sql, ykval-sync.php, ykval-synclib.php, ykval-verify.php: Committed first trial version for replication protocol. 2009-11-25 Simon Josefsson * ykval-db.sql: Fix. 2009-11-25 Simon Josefsson * ykval-db.sql: Add queue table. 2009-11-20 Simon Josefsson * Makefile: Add. 2009-11-20 Simon Josefsson * : Pull in docs from wiki. 2009-10-12 Olov Danielson * ykval-api.html: added description of request and response for retrieving timestamp and session counter information from the validation server 2009-10-08 Simon Josefsson * ykval-api.html: Add, from yubico.com web page. 2009-10-05 Olov Danielson * ykval-common.php, ykval-verify.php: Added option to get timestamp and session counters in the response. Use with verify?id=x&otp=xxx..×tamp=1 returns timestamp, sessoncounter and session use in response 2009-09-21 Simon Josefsson * ykval-ping.php: Add. 2009-08-31 Simon Josefsson * ykval-db.sql: Make sure b64 values are compared case-sensitively. 2009-08-31 Simon Josefsson * get-api-key/index.php: Use POST. 2009-08-31 Simon Josefsson * ykval-config.php, ykval-db.sql, ykval-revoke.php: Add revoke service. 2009-08-28 Simon Josefsson * get-api-key/index.php: Add front-end to get-api-key service. 2009-08-28 Simon Josefsson * ykval-getapikey.php: Fix terminology. 2009-08-28 Simon Josefsson * ykval-db.sql: Reorder again.. 2009-08-28 Simon Josefsson * ykval-db.sql: Place notes field last. Add notes field to yubikeys. 2009-08-28 Simon Josefsson * ykval-getapikey.php: Make it work. 2009-08-28 Simon Josefsson * ykval-getapikey.php: Silence SQL query. 2009-08-28 Simon Josefsson * ykval-db.sql: Add comment to drop ykval_getapikey. 2009-08-28 Simon Josefsson * ykval-db.sql: Reorder. 2009-08-28 Simon Josefsson * ykval-getapikey.php: Don't put secret in log. Use new OTP database field for OTPs. 2009-08-28 Simon Josefsson * ykval-db.sql: Add otp field to clients column. 2009-08-28 Simon Josefsson * ykval-getapikey.php: Add service to add a new api key on validation server. 2009-08-28 Simon Josefsson * ykval-common.php, ykval-config.php, ykval-db.sql, ykval-verify.php: Lay foundation for get-api-key service. 2009-05-06 Simon Josefsson * ykval-common.php, ykval-verify.php: Cleanups. 2009-05-06 Simon Josefsson * ykval-verify.php: If adding key doesn't work, it is an internal error. 2009-05-06 Simon Josefsson * ykval-common.php: Fix field names. 2009-05-06 Simon Josefsson * ykval-common.php: Drop removed field. 2009-05-06 Simon Josefsson * ykval-common.php: Don't die. 2009-05-06 Simon Josefsson * ykval-db.sql: Fix comment. 2009-05-06 Simon Josefsson * ykval-verify.php: Don't use die. 2009-05-06 Simon Josefsson * ykval-db.sql: Fix. 2009-05-06 Simon Josefsson * ykval-common.php, ykval-db.sql, ykval-verify.php: Drop chk_time. 2009-05-05 Simon Josefsson * ykval-config.php: Fix URLs. 2009-05-04 Simon Josefsson * common.php, config.php.sample, ping.php, verify.php, ykval-common.php, ykval-config.php, ykval-verify.php: Rename and cleanup. 2009-04-27 Simon Josefsson * ykval-db.sql: Fix perms. 2009-04-27 Simon Josefsson * config.php.sample: Align with wiki. 2009-04-27 Simon Josefsson * ykval-db.sql: Create user. 2009-04-27 Simon Josefsson * ykval-db.sql: Simplify SQL. 2009-04-27 Simon Josefsson * common.php, config.php.sample, test-multi.php, verify.php: Support parallel queries to multiple KSMs. 2009-04-13 Simon Josefsson * ykval-db.sql: userId cannot be unique, to deal with auto-discovered keys. 2009-04-01 Simon Josefsson * verify.php: Don't query twice. 2009-04-01 Simon Josefsson * common.php, verify.php: Auto-discover yubikeys known by the ykksm. 2009-03-18 Simon Josefsson * common.php: Don't fetch always true active field. 2009-03-18 Simon Josefsson * common.php: Reorder high/low to match internal order. 2009-03-18 Simon Josefsson * common.php: Reorder high/low to match internal order. 2009-03-18 Simon Josefsson * common.php, verify.php: Always check signatures. 2009-03-18 Simon Josefsson * verify.php: Sanity check OTP before asking KSM, to get a better error code. 2009-03-18 Simon Josefsson * verify.php: Fix typo. 2009-03-18 Simon Josefsson * .htaccess: Fix rewrite regexp. 2009-03-18 Simon Josefsson * common.php, verify.php: Don't hard code prefix length. 2009-03-18 Simon Josefsson * ykval-db.sql: Make possible to use from fresh installation. 2009-03-18 Simon Josefsson * ykval-db.sql: Simplify. 2009-03-11 Simon Josefsson * common.php: Curl errno/error is order dependent?! 2009-03-11 Simon Josefsson * common.php: More curl debugging. 2009-03-11 Simon Josefsson * verify.php: Reorder db query after yk-ksm query. 2009-03-11 Simon Josefsson * common.php: Improve debug message. 2009-03-11 Simon Josefsson * common.php: Add timeout for ykksm queries. 2009-03-11 Simon Josefsson * common.php, verify.php: More cleanups. 2009-03-11 Simon Josefsson * index.php: Remove. 2009-03-11 Simon Josefsson * verify_debug.php: Removed, debug logging are sent to error_log. 2009-03-11 Simon Josefsson * common.php: Improve debugging. 2009-03-11 Simon Josefsson * common.php, verify.php: Cleanup. 2009-03-11 Simon Josefsson * AES128.php, common.php, config.php.sample, verify.php, yubikey.php: Use YKKSM instead of local secret. Remove more code. 2009-03-11 Simon Josefsson * common.php, verify.php: Code cleanups. 2009-03-11 Simon Josefsson * common.php, verify.php: Use absolute timestamp tolerance as well. 2009-03-11 Simon Josefsson * common.php, verify.php: Improve checking of OTPs. 2009-03-10 Simon Josefsson * verify_debug.php: Update after renaming. 2009-03-10 Simon Josefsson * AES128.php, common.php, config.php.sample, verify.php, yubikey.php: Make standalone. 2009-03-10 Simon Josefsson * verify.php, verifyOTP.php: Move verifyOTP.php to verify.php. 2009-03-10 Simon Josefsson * .htaccess: Fix CRLF. 2009-03-10 Simon Josefsson * sign_demo.php: Removed, use demo.php from yubico-php instead. 2009-03-10 Simon Josefsson * common.php, verifyOTP.php: Make it work. 2009-03-10 Simon Josefsson * addKey.php, add_key.php, add_key_debug.php: Remove. 2009-03-10 Simon Josefsson * common.php: Make getUTCTimeStamp return milliseconds too, similar to Java server. 2009-03-10 Simon Josefsson * addKey.php, sign_demo.php, verifyOTP.php: Fix. 2009-02-25 Simon Josefsson * ykval-db.sql: From yubiphpbase. 2008-12-17 Paul Chen * verifyOTP.php: typo fix 2008-12-17 Paul Chen * verifyOTP.php: print more debug info on time based otp phishing 2008-12-11 Paul Chen * addKey.php: bugfix addkey 2008-12-11 Paul Chen * addKey.php: Add sn 2008-12-10 Paul Chen * addKey.php, sign_demo.php, verifyOTP.php: Restructure for easier installation 2008-12-08 Paul Chen * common.php: bugfix verify otp 2008-12-08 Paul Chen * sign_demo.php: bugfix verify otp 2008-12-08 Paul Chen * verifyOTP.php: bugfix verify otp 2008-12-08 Paul Chen * sign_demo.php: bugfix sign demo 2008-12-08 Paul Chen * sign_demo.php, verifyOTP.php: Chk sig when if it exists 2008-12-03 Paul Chen * common.php: fine tune time per tick 2008-12-03 Paul Chen * verifyOTP.php: anti otp phishing 2008-12-03 Paul Chen * verifyOTP.php: anti otp phishing 2008-12-03 Paul Chen * verifyOTP.php: anti otp phishing 2008-12-03 Paul Chen * common.php, verifyOTP.php: Use time stamp to prevent OTP phishing 2008-12-03 Paul Chen * addKey.php: sn 2008-12-02 Paul Chen * addKey.php: add sn 2008-12-02 Paul Chen * addKey.php: add sn 2008-12-02 Paul Chen * addKey.php: add sn 2008-12-02 Paul Chen * addKey.php: bugfix add key 2008-11-29 Paul Chen * verifyOTP.php: Case-insensitive 2008-11-21 Paul Chen * sign_demo.php: more demo 2008-11-21 Paul Chen * : 1 2 common.php 2008-10-10 Paul Chen * verifyOTP.php: upd history on validation 2008-10-08 Paul Chen * .htaccess: strip the .php extension 2008-10-08 Paul Chen * common.php, sign_demo.php, verifyOTP.php: sign example 2008-10-07 Paul Chen * verifyOTP.php: check yubikey owner when told to 2008-09-27 Paul Chen * : 107 0 addKey.php 3 99 add_key.php 5 0 add_key_debug.php 31 0 common.php 7 0 ping.php 16 29 verifyOTP.php create mode 100644 addKey.php create mode 100644 add_key_debug.php create mode 100644 ping.php 2008-09-26 Paul Chen * add_key.php, common.php, verifyOTP.php: add key 2008-09-26 Paul Chen * verifyOTP.php: lego stackup 2008-09-24 Paul Chen * verifyOTP.php: loosen the client checking, will make it optional 2008-09-23 Paul Chen * verifyOTP.php: check signature 2008-09-23 Paul Chen * verifyOTP.php: resp mesgs 2008-09-22 Paul Chen * verifyOTP.php: Fix counter comp algo 2008-09-20 Paul Chen * verifyOTP.php: Fix counter comparison 2008-09-18 Paul Chen * verify.php, verifyOTP.php, verify_debug.php: Init 2008-09-17 Paul Chen * index.php, verify.php: Init, experiment 2008-09-17 Paul Chen * Initial directory structure. yubikey-val-2.38/ykval-checksum-clients0000755000175000017500000000522612726004025016641 0ustar jeanjean#!/usr/bin/php connect()) { $myLog->log(LOG_WARNING, "Could not connect to database"); exit(1); } $everything = ""; $result=$db->customQuery("SELECT id, active, secret ". "FROM clients ". "ORDER BY id"); while($row = $db->fetchArray($result)) { $active = $row['active']; if ($active == "") { # For some reason PostgreSQL returns empty strings for false values?! $active = "0"; } $everything .= $row['id'] . "\t" . $active . "\t" . $row['secret'] . "\n"; } $db->closeCursor($result); $hash = sha1 ($everything); if ($verbose) { print $everything; } print substr ($hash, 0, 10) . "\n"; $result=null; $db=null; yubikey-val-2.38/ykval-synclib.php0000644000175000017500000004564712726004025015641 0ustar jeanjeanmyLog = new Log($logname); global $baseParams; $this->syncServers = $baseParams['__YKVAL_SYNC_POOL__']; $this->db = Db::GetDatabaseHandle($baseParams, $logname); $this->isConnected=$this->db->connect(); $this->server_nonce=md5(uniqid(rand())); if (array_key_exists('__YKVAL_SYNC_CURL_OPTS__', $baseParams)) { $this->curlopts = $baseParams['__YKVAL_SYNC_CURL_OPTS__']; } } public function addField($name, $value) { $this->myLog->addField($name, $value); $this->db->addField($name, $value); } public function isConnected() { return $this->isConnected; } public function getNumberOfServers() { return count($this->syncServers); } public function getNumberOfValidAnswers() { if (isset($this->valid_answers)) return $this->valid_answers; return 0; } public function getNumberOfAnswers() { if (isset($this->answers)) return $this->answers; return 0; } public function getClientData($client) { $res = $this->db->customQuery("SELECT id, secret FROM clients WHERE active='1' AND id='" . $client . "'"); $r = $this->db->fetchArray($res); $this->db->closeCursor($res); if ($r) return $r; return false; } public function getQueueLength() { return count($this->db->findBy('queue', null, null, null)); } public function getQueueLengthByServer() { $counters = array(); foreach ($this->syncServers as $server) { $counters[$server] = 0; } $result = $this->db->customQuery('SELECT server, COUNT(server) as count FROM queue GROUP BY server'); while ($row = $this->db->fetchArray($result)) { $counters[$row['server']] = $row['count']; } $this->db->closeCursor($result); return $counters; } public function queue($otpParams, $localParams) { $info = $this->createInfoString($otpParams, $localParams); $this->otpParams = $otpParams; $this->localParams = $localParams; $queued = time(); $result = true; foreach ($this->syncServers as $server) { $arr = array( 'queued' => $queued, 'modified' => $otpParams['modified'], 'otp' => $otpParams['otp'], 'server' => $server, 'server_nonce' => $this->server_nonce, 'info' => $info ); if (! $this->db->save('queue', $arr)) $result = false; } return $result; } public function log($priority, $msg, $params=NULL) { if ($params) $msg .= ' 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_low=' . $params['yk_low']; if ($this->myLog) $this->myLog->log($priority, $msg); else error_log("Warning: myLog uninitialized in ykval-synclib.php. Message is " . $msg); } public function getLocalParams($yk_publicname) { $this->log(LOG_DEBUG, "searching for yk_publicname $yk_publicname in local db"); $res = $this->db->findBy('yubikeys', 'yk_publicname', $yk_publicname, 1); if (!$res) { $this->log(LOG_NOTICE, "Discovered new identity $yk_publicname"); $this->db->save('yubikeys', array( 'active' => 1, 'created' => time(), 'modified' => -1, 'yk_publicname' => $yk_publicname, 'yk_counter' => -1, 'yk_use' => -1, 'yk_low' => -1, 'yk_high' => -1, 'nonce' => '0000000000000000', 'notes' => '' )); $res = $this->db->findBy('yubikeys', 'yk_publicname', $yk_publicname, 1); } if ($res) { $localParams = array( 'modified' => $res['modified'], 'nonce' => $res['nonce'], 'active' => $res['active'], 'yk_publicname' => $yk_publicname, '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; } $this->log(LOG_NOTICE, "params for yk_publicname $yk_publicname not found in database"); return false; } public function updateDbCounters($params) { if (!isset($params['yk_publicname'])) return false; $arr = 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'] ); $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'], $arr, $condition)) { $this->log(LOG_CRIT, 'failed to update internal DB with new counters'); return false; } if ($this->db->rowCount() > 0) $this->log(LOG_INFO, 'updated database ', $params); else $this->log(LOG_INFO, 'database not updated', $params); return true; } public function countersHigherThan($p1, $p2) { if ($p1['yk_counter'] > $p2['yk_counter']) return true; if ($p1['yk_counter'] == $p2['yk_counter'] && $p1['yk_use'] > $p2['yk_use']) return true; return false; } public function countersHigherThanOrEqual($p1, $p2) { if ($p1['yk_counter'] > $p2['yk_counter']) return true; if ($p1['yk_counter'] == $p2['yk_counter'] && $p1['yk_use'] >= $p2['yk_use']) return true; return false; } public function countersEqual($p1, $p2) { return ($p1['yk_counter'] == $p2['yk_counter'] && $p1['yk_use'] == $p2['yk_use']); } // queue daemon public function reSync($older_than, $timeout) { $this->log(LOG_DEBUG, 'starting resync'); /* Loop over all unique servers in queue */ $queued_limit = time()-$older_than; $server_res = $this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null"); $server_list = array(); $mh = curl_multi_init(); $ch = array(); $entries = array(); $handles = 0; while ($my_server = $this->db->fetchArray($server_res)) { $server = $my_server['server']; $this->log(LOG_DEBUG, "Processing queue for server " . $server); $res = $this->db->customQuery("select * from queue WHERE (queued < " . $queued_limit . " or queued is null) and server='" . $server . "' LIMIT 1000"); $list = array(); while ($entry = $this->db->fetchArray($res)) { $list[] = $entry; } $server_list[$server] = $list; $handle = curl_init(); $ch[$server] = $handle; $this->db->closeCursor($res); } $this->db->closeCursor($server_res); /* add one entry for each server we're going to sync */ foreach ($server_list as $server) { $entry = array_shift($server); if(count($server) == 0) { unset($server_list[$entry['server']]); } $handle = $ch[$entry['server']]; $this->log(LOG_INFO, "server=" . $entry['server'] . ", server_nonce=" . $entry['server_nonce'] . ", info=" . $entry['info']); $url = $this->buildSyncUrl($entry); curl_settings($this, 'YK-VAL resync', $handle, $url, $timeout, $this->curlopts); $entries[$entry['server']] = $entry; curl_multi_add_handle($mh, $handle); $handles++; } while($handles > 0) { while (curl_multi_exec($mh, $active) == CURLM_CALL_MULTI_PERFORM); while ($info = curl_multi_info_read($mh)) { $handle = $info['handle']; $server = strtok(curl_getinfo($handle, CURLINFO_EFFECTIVE_URL), "?"); $entry = $entries[$server]; $this->log(LOG_DEBUG, "handle indicated to be for $server."); curl_multi_remove_handle($mh, $handle); $handles--; if ($info['result'] === CURLE_OK) { $response = curl_multi_getcontent($handle); 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 */ /* This is the counter values we had in our database *before* processing the current OTP. */ $validationParams = $this->localParamsFromInfoString($entry['info']); /* This is the data from the current OTP. */ $otpParams = $this->otpParamsFromInfoString($entry['info']); /* Fetch current information from our database */ $localParams = $this->getLocalParams($otpParams['yk_publicname']); $this->log(LOG_DEBUG, 'validation params: ', $validationParams); $this->log(LOG_DEBUG, 'OTP params: ', $otpParams); /* 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)) { if ($this->countersEqual($resParams, $otpParams)) { $this->log(LOG_INFO, 'Remote server had received the current counter values already. '); } else { $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_DEBUG, 'deleting queue entry with modified=' . $entry['modified'] . ' server_nonce=' . $entry['server_nonce'] . ' server=' . $entry['server']); $this->db->deleteByMultiple('queue', array( 'modified' => $entry['modified'], 'server_nonce' => $entry['server_nonce'], 'server' => $entry['server'] )); } else if (preg_match('/status=BAD_OTP/', $response)) { $this->log(LOG_WARNING, 'Remote server says BAD_OTP, pointless to try again, removing from queue.'); $this->db->deleteByMultiple('queue', array( 'modified' => $entry['modified'], 'server_nonce' => $entry['server_nonce'], 'server' => $entry['server'] )); } else { $this->log(LOG_ERR, 'Remote server refused our sync request. Check remote server logs.'); } if($server_list[$server]) { $entry = array_shift($server_list[$server]); if(count($server_list[$server]) == 0) { $this->log(LOG_DEBUG, "All entries for $server synced."); unset($server_list[$server]); } $this->log(LOG_INFO, "server=" . $entry['server'] . ", server_nonce=" . $entry['server_nonce'] . ", info=" . $entry['info']); $url = $this->buildSyncUrl($entry); curl_settings($this, 'YK-VAL resync', $handle, $url, $timeout, $this->curlopts); $entries[$server] = $entry; curl_multi_add_handle($mh, $handle); $handles++; } } else { $this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $entry['server']); unset($server_list[$server]); } } } foreach ($ch as $handle) { curl_close($ch); } curl_multi_close($mh); return true; } // blocks verify requests 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[] = $this->buildSyncUrl($row); } // send out requests $ans_arr = retrieveURLasync('YK-VAL sync', $urls, $this->myLog, $ans_req, $match='status=OK', $returl=True, $timeout, $this->curlopts); if ($ans_arr === FALSE) { $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) { // parse out parameters from each response $resParams=$this->parseParamsFromMultiLineString($answer); $this->log(LOG_DEBUG, 'local db contains ', $localParams); $this->log(LOG_DEBUG, 'response contains ', $resParams); $this->log(LOG_DEBUG, 'OTP contains ', $this->otpParams); // update internal DB (conditional) $this->updateDbCounters($resParams); /** * Check for warnings * * See https://developers.yubico.com/yubikey-val/doc/ServerReplicationProtocol.html * * NOTE: We use localParams for validationParams comparison since they are actually the * 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) && $resParams['nonce'] != $localParams['nonce']) { $this->log(LOG_NOTICE, 'Servers out of sync. Nonce differs. '); } 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. * Otherwise, return false. */ if ($this->valid_answers == $ans_req) return true; return false; } private function createInfoString($otpParams, $localParams) { # FIXME &local_counter return 'yk_publicname=' . $otpParams['yk_publicname'] . '&yk_counter=' . $otpParams['yk_counter'] . '&yk_use=' . $otpParams['yk_use'] . '&yk_high=' . $otpParams['yk_high'] . '&yk_low=' . $otpParams['yk_low'] . '&nonce=' . $otpParams['nonce'] . ',local_counter=' . $localParams['yk_counter'] . '&local_use=' . $localParams['yk_use']; } private function otpParamsFromInfoString($info) { $out = explode(',', $info); parse_str($out[0], $params); return $params; } private function otpPartFromInfoString($info) { $out = explode(',', $info); return $out[0]; } private function localParamsFromInfoString($info) { $out = explode(',', $info); parse_str($out[1], $params); return array( 'yk_counter' => $params['local_counter'], 'yk_use' => $params['local_use'] ); } private function parseParamsFromMultiLineString($str) { $i = preg_match("/^modified=(-1|[0-9]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse modified value: $str"); } $resParams['modified']=$out[1]; $i = preg_match("/^yk_publicname=([cbdefghijklnrtuv]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse publicname value: $str"); } $resParams['yk_publicname']=$out[1]; $i = preg_match("/^yk_counter=(-1|[0-9]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse counter value: $str"); } $resParams['yk_counter']=$out[1]; $i = preg_match("/^yk_use=(-1|[0-9]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse use value: $str"); } $resParams['yk_use']=$out[1]; $i = preg_match("/^yk_high=(-1|[0-9]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse high value: $str"); } $resParams['yk_high']=$out[1]; $i = preg_match("/^yk_low=(-1|[0-9]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse low value: $str"); } $resParams['yk_low']=$out[1]; $i = preg_match("/^nonce=([[:alnum:]]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse nonce value: $str"); } $resParams['nonce']=$out[1]; return $resParams; } private function deleteQueueEntry($answer) { preg_match('/url=(.*)\?/', $answer, $out); $server = $out[1]; $this->log(LOG_INFO, "deleting server=" . $server . " modified=" . $this->otpParams['modified'] . " server_nonce=" . $this->server_nonce); $this->db->deleteByMultiple('queue', array( 'modified' => $this->otpParams['modified'], 'server_nonce' => $this->server_nonce, 'server' => $server )); } private function buildSyncUrl($entry) { return $entry['server'] . "?otp=" . $entry['otp'] . "&modified=" . $entry['modified'] . "&" . $this->otpPartFromInfoString($entry['info']); } } yubikey-val-2.38/ykval-sync.php0000644000175000017500000001370012726004025015133 0ustar jeanjeanaddField('ip', $ipaddr); $myLog->log(LOG_INFO, 'Request: ' . $_SERVER['QUERY_STRING']); $myLog->log(LOG_DEBUG, "Received request from $ipaddr"); if (empty($_SERVER['QUERY_STRING'])) { sendResp(S_MISSING_PARAMETER, $myLog); } // verify request sent by whitelisted address if (in_array($ipaddr, $allowed, TRUE) === FALSE) { $myLog->log(LOG_NOTICE, "Operation not allowed from IP $ipaddr"); $myLog->log(LOG_DEBUG, "Remote IP $ipaddr not listed in allowed sync pool : " . implode(', ', $allowed)); sendResp(S_OPERATION_NOT_ALLOWED, $myLog); } // define requirements on protocol $syncParams = array( 'modified' => NULL, 'otp' => NULL, 'nonce' => NULL, 'yk_publicname' => NULL, 'yk_counter' => NULL, 'yk_use' => NULL, 'yk_high' => NULL, 'yk_low' => NULL ); // extract values from HTTP request $tmp_log = 'Received '; foreach ($syncParams as $param => $value) { $value = getHttpVal($param, NULL, $_GET); if ($value == NULL) { $myLog->log(LOG_NOTICE, "Received request with parameter[s] ($param) missing value"); sendResp(S_MISSING_PARAMETER, $myLog); } $syncParams[$param] = $value; $tmp_log .= "$param=$value "; } $myLog->log(LOG_INFO, $tmp_log); $sync = new SyncLib('ykval-sync:synclib'); $sync->addField('ip', $ipaddr); if (! $sync->isConnected()) { sendResp(S_BACKEND_ERROR, $myLog); } // at this point we should have the otp so let's add it to the logging module $myLog->addField('otp', $syncParams['otp']); $sync->addField('otp', $syncParams['otp']); // verify correctness of input parameters foreach (array('modified','yk_counter', 'yk_use', 'yk_high', 'yk_low') as $param) { // -1 is valid except for modified if ($param !== 'modified' && $syncParams[$param] === '-1') continue; // [0-9]+ if ($syncParams[$param] !== '' && ctype_digit($syncParams[$param])) continue; $myLog->log(LOG_NOTICE, "Input parameters $param not correct"); sendResp(S_MISSING_PARAMETER, $myLog); } // get local counter data $yk_publicname = $syncParams['yk_publicname']; if (($localParams = $sync->getLocalParams($yk_publicname)) === FALSE) { $myLog->log(LOG_NOTICE, "Invalid Yubikey $yk_publicname"); sendResp(S_BACKEND_ERROR, $myLog); } // conditional update local database $sync->updateDbCounters($syncParams); $myLog->log(LOG_DEBUG, 'Local params ', $localParams); $myLog->log(LOG_DEBUG, 'Sync request params ', $syncParams); if ($sync->countersHigherThan($localParams, $syncParams)) { $myLog->log(LOG_WARNING, 'Remote server out of sync.'); } if ($sync->countersEqual($localParams, $syncParams)) { if ($syncParams['modified'] == $localParams['modified'] && $syncParams['nonce'] == $localParams['nonce']) { /** * This is not an error. When the remote server received an OTP to verify, it would * have sent out sync requests immediately. When the required number of responses had * been received, the current implementation discards all additional responses (to * return the result to the client as soon as possible). If our response sent last * time was discarded, we will end up here when the background ykval-queue processes * the sync request again. */ $myLog->log(LOG_INFO, 'Sync request unnecessarily sent'); } if ($syncParams['modified'] != $localParams['modified'] && $syncParams['nonce'] == $localParams['nonce']) { $deltaModified = $syncParams['modified'] - $localParams['modified']; if ($deltaModified < -1 || $deltaModified > 1) { $myLog->log(LOG_WARNING, "We might have a replay. 2 events at different times have generated the same counters. The time difference is $deltaModified seconds"); } } if ($syncParams['nonce'] != $localParams['nonce']) { $myLog->log(LOG_WARNING, 'Remote server has received a request to validate an already validated OTP'); } } if ($localParams['active'] != 1) { /** * The remote server has accepted an OTP from a YubiKey which we would not. * We still needed to update our counters with the counters from the OTP though. */ $myLog->log(LOG_WARNING, "Received sync-request for de-activated Yubikey $yk_publicname - check database synchronization!!!"); sendResp(S_BAD_OTP, $myLog); } $extra = array( 'modified' => $localParams['modified'], 'nonce' => $localParams['nonce'], 'yk_publicname' => $yk_publicname, 'yk_counter' => $localParams['yk_counter'], 'yk_use' => $localParams['yk_use'], 'yk_high' => $localParams['yk_high'], 'yk_low' => $localParams['yk_low'] ); sendResp(S_OK, $myLog, '', $extra); yubikey-val-2.38/ykval-verify.php0000644000175000017500000003217112726004025015466 0ustar jeanjeanaddField('ip', $ipaddr); $myLog->request = new LogVerify(); if (array_key_exists('__YKVAL_VERIFY_LOGFORMAT__', $baseParams) && is_string($baseParams['__YKVAL_VERIFY_LOGFORMAT__'])) { $myLog->request->format = $baseParams['__YKVAL_VERIFY_LOGFORMAT__']; } $myLog->request->set('ip', $ipaddr); $myLog->request->set('tls', ($https ? 'tls' : '-')); $myLog->request->set('time_start', $time_start); unset($time_start); if ($_GET) { $request = $_GET; $message = 'Request: ' . $_SERVER['QUERY_STRING']; } else if ($_POST) { $request = $_POST; $kv = array(); foreach ($request as $key => $value) { $kv[] = "$key=$value"; } $message = 'POST: ' . join('&', $kv); unset($kv); } else { $request = array(); $message = ''; } $message .= ' (at ' . date('c') . ' ' . microtime() . ') HTTP' . ($https ? 'S' : ''); $myLog->log(LOG_INFO, $message); unset($message); /* Detect protocol version */ if (preg_match('/\/wsapi\/([0-9]+)\.([0-9]+)\//', $_SERVER['REQUEST_URI'], $out)) { $protocol_version = $out[1] + $out[2] * 0.1; } else { $protocol_version = 1.0; } $myLog->request->set('protocol', $protocol_version); $myLog->log(LOG_DEBUG, "found protocol version $protocol_version"); /** * Extract values from HTTP request */ $h = getHttpVal('h', '', $request); $client = getHttpVal('id', '0', $request); $timestamp = getHttpVal('timestamp', '0', $request); $otp = getHttpVal('otp', '', $request); $otp = strtolower($otp); if (preg_match('/^[jxe.uidchtnbpygk]+$/', $otp)) { $new_otp = strtr($otp, 'jxe.uidchtnbpygk', 'cbdefghijklnrtuv'); $myLog->log(LOG_INFO, "Dvorak OTP converting $otp to $new_otp"); $otp = $new_otp; unset($new_otp); } $myLog->request->set('signed', ($h === '' ? '-' : 'signed')); $myLog->request->set('client', ($client === '0' ? '-' : $client)); $myLog->request->set('otp', $otp); /** * Construct response parameters */ $extra = array(); if ($protocol_version >= 2.0) { $extra['otp'] = $otp; } /** * We have the OTP now, so let's add it to the logging */ $myLog->addField('otp', $otp); if ($protocol_version >= 2.0) { $sl = getHttpVal('sl', '', $request); $timeout = getHttpVal('timeout', '', $request); $nonce = getHttpVal('nonce', '', $request); $myLog->request->set('sl', $sl); $myLog->request->set('timeout', $timeout); $myLog->request->set('nonce', $nonce); /* Nonce is required from protocol 2.0 */ if (!$nonce) { $myLog->log(LOG_NOTICE, 'Nonce is missing and protocol version >= 2.0'); sendResp(S_MISSING_PARAMETER, $myLog); } /* Add nonce to response parameters */ $extra['nonce'] = $nonce; } /** * 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 */ /* Change default protocol "strings" to numeric values */ if (isset($sl) && strcasecmp($sl, 'fast') == 0) { $sl = $baseParams['__YKVAL_SYNC_FAST_LEVEL__']; } if (isset($sl) && strcasecmp($sl, 'secure') == 0) { $sl = $baseParams['__YKVAL_SYNC_SECURE_LEVEL__']; } if (!isset($sl) || $sl == '') { $sl = $baseParams['__YKVAL_SYNC_DEFAULT_LEVEL__']; } 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, $myLog); } if (!isset($timeout) || $timeout == '') { $timeout = $baseParams['__YKVAL_SYNC_DEFAULT_TIMEOUT__']; } if ($timeout && preg_match("/^[0-9]+$/", $timeout) == 0) { $myLog->log(LOG_NOTICE, 'timeout is provided but not correct'); sendResp(S_MISSING_PARAMETER, $myLog); } if ($otp == '') { $myLog->log(LOG_NOTICE, 'OTP is missing'); sendResp(S_MISSING_PARAMETER, $myLog); } if (strlen($otp) < TOKEN_LEN || strlen($otp) > OTP_MAX_LEN) { $myLog->log(LOG_NOTICE, "Incorrect OTP length: $otp"); sendResp(S_BAD_OTP, $myLog); } if (preg_match('/^[cbdefghijklnrtuv]+$/', $otp) == 0) { $myLog->log(LOG_NOTICE, "Invalid OTP: $otp"); sendResp(S_BAD_OTP, $myLog); } if (preg_match("/^[0-9]+$/", $client) == 0) { $myLog->log(LOG_NOTICE, 'id provided in request must be an integer'); sendResp(S_MISSING_PARAMETER, $myLog); } if ($client === '0') { $myLog->log(LOG_NOTICE, 'Client ID is missing'); sendResp(S_MISSING_PARAMETER, $myLog); } if (isset($nonce) && preg_match("/^[A-Za-z0-9]+$/", $nonce) == 0) { $myLog->log(LOG_NOTICE, 'NONCE is provided but not correct'); sendResp(S_MISSING_PARAMETER, $myLog); } if (isset($nonce) && (strlen($nonce) < 16 || strlen($nonce) > 40)) { $myLog->log(LOG_NOTICE, 'Nonce too short or too long'); sendResp(S_MISSING_PARAMETER, $myLog); } /** * Timestamp parameter is not checked since current protocol * says that 1 means request timestamp and anything else is discarded. */ /** * Initialize the sync library. Strive to use this instead of custom * DB requests, custom comparisons etc. */ $sync = new SyncLib('ykval-verify:synclib'); $sync->addField('ip', $ipaddr); $sync->addField('otp', $otp); if (! $sync->isConnected()) { sendResp(S_BACKEND_ERROR, $myLog); } if (($cd = $sync->getClientData($client)) === FALSE) { $myLog->log(LOG_NOTICE, "Invalid client id $client"); sendResp(S_NO_SUCH_CLIENT, $myLog); } $myLog->log(LOG_DEBUG, 'Client data:', $cd); /** * Check client signature */ $apiKey = $cd['secret']; $apiKey = base64_decode($apiKey); unset($cd); if ($h != '') { // Create the signature using the API key unset($request['h']); $hmac = sign($request, $apiKey, $myLog); if (hash_equals($hmac, $h) === FALSE) { $myLog->log(LOG_DEBUG, "client hmac=$h, server hmac=$hmac"); sendResp(S_BAD_SIGNATURE, $myLog, $apiKey); } } /** * 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())); $myLog->log(LOG_INFO, "protocol version below 2.0. Created nonce $nonce"); } // which YK-KSM should we talk to? $urls = otp2ksmurls($otp, $client); if (!is_array($urls)) { sendResp(S_BACKEND_ERROR, $myLog, $apiKey); } // decode OTP from input $curlopts = array(); if (array_key_exists('__YKVAL_KSM_CURL_OPTS__', $baseParams)) { $curlopts = $baseParams['__YKVAL_KSM_CURL_OPTS__']; } if (($otpinfo = KSMdecryptOTP($urls, $myLog, $curlopts)) === FALSE) { /** * FIXME * * Return S_BACKEND_ERROR if there are connection issues, * e.g. misconfigured otp2ksmurls. */ sendResp(S_BAD_OTP, $myLog, $apiKey); } $myLog->request->set('counter', $otpinfo['session_counter']); $myLog->request->set('use', $otpinfo['session_use']); $myLog->request->set('high', $otpinfo['high']); $myLog->request->set('low', $otpinfo['low']); $myLog->log(LOG_DEBUG, 'Decrypted OTP:', $otpinfo); // get Yubikey from DB $public_id = substr($otp, 0, strlen ($otp) - TOKEN_LEN); $myLog->request->set('public_id', $public_id); if (($localParams = $sync->getLocalParams($public_id)) === FALSE) { $myLog->log(LOG_NOTICE, "Invalid Yubikey $public_id"); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); } $myLog->log(LOG_DEBUG, 'Auth data:', $localParams); if ($localParams['active'] != 1) { $myLog->log(LOG_NOTICE, "De-activated Yubikey $public_id"); sendResp(S_BAD_OTP, $myLog, $apiKey); } /* Build OTP params */ $otpParams = array( 'modified' => time(), 'otp' => $otp, 'nonce' => $nonce, 'yk_publicname' => $public_id, 'yk_counter' => $otpinfo['session_counter'], 'yk_use' => $otpinfo['session_use'], 'yk_high' => $otpinfo['high'], 'yk_low' => $otpinfo['low'] ); unset($otpinfo); /* First check if OTP is seen with the same nonce, in such case we have an replayed request */ if ($sync->countersEqual($localParams, $otpParams) && $localParams['nonce'] == $otpParams['nonce']) { $myLog->log(LOG_WARNING, 'Replayed request'); sendResp(S_REPLAYED_REQUEST, $myLog, $apiKey, $extra); } /* 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); $sync->log(LOG_WARNING, 'replayed OTP: Otp counters ', $otpParams); sendResp(S_REPLAYED_OTP, $myLog, $apiKey, $extra); } /* Valid OTP, update database. */ if (!$sync->updateDbCounters($otpParams)) { $myLog->log(LOG_CRIT, 'Failed to update yubikey counters in database'); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); } /* Queue sync requests */ if (!$sync->queue($otpParams, $localParams)) { $myLog->log(LOG_CRIT, 'failed to queue sync requests'); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); } $nr_servers = $sync->getNumberOfServers(); $req_answers = ceil($nr_servers * $sl / 100.0); if ($req_answers > 0) { $syncres = $sync->sync($req_answers, $timeout); $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; $nr_valid_answers = 0; $sl_success_rate = 0; } $myLog->log(LOG_INFO, '', array( 'synclevel' => $sl, 'nr servers' => $nr_servers, 'req answers' => $req_answers, 'answers' => $nr_answers, 'valid answers' => $nr_valid_answers, 'sl success rate' => $sl_success_rate, 'timeout' => $timeout, )); if ($syncres == False) { /* sync returned false, indicating that either at least 1 answer marked OTP as invalid or there were not enough answers */ $myLog->log(LOG_WARNING, 'Sync failed'); if ($nr_valid_answers != $nr_answers) sendResp(S_REPLAYED_OTP, $myLog, $apiKey, $extra); $extra['sl'] = $sl_success_rate; sendResp(S_NOT_ENOUGH_ANSWERS, $myLog, $apiKey, $extra); } if ($otpParams['yk_counter'] == $localParams['yk_counter'] && $otpParams['yk_use'] > $localParams['yk_use']) { $ts = ($otpParams['yk_high'] << 16) + $otpParams['yk_low']; $seenTs = ($localParams['yk_high'] << 16) + $localParams['yk_low']; $tsDiff = $ts - $seenTs; $tsDelta = $tsDiff * TS_SEC; $now = time(); $elapsed = $now - $localParams['modified']; $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. if ($elapsed != 0) { $percent = $deviation/$elapsed; } else { $percent = 1; } $myLog->log(LOG_INFO, 'Timestamp', array( 'seen' => $seenTs, 'this' => $ts, 'delta' => $tsDiff, 'secs' => $tsDelta, 'accessed' => sprintf('%s (%s)', $localParams['modified'], date('Y-m-d H:i:s', $localParams['modified'])), 'now' => sprintf('%s (%s)', $now, date('Y-m-d H:i:s', $now)), 'elapsed' => $elapsed, 'deviation' => sprintf('%s secs or %s%%', $deviation, round(100 * $percent)), )); if ($deviation > TS_ABS_TOLERANCE && $percent > TS_REL_TOLERANCE) { $myLog->log(LOG_NOTICE, 'OTP failed phishing test'); // FIXME // This was wrapped around if (0). should we nuke or enable? // sendResp(S_DELAYED_OTP, $myLog, $apiKey, $extra); } } /** * Fill up with more response parameters */ if ($protocol_version >= 2.0) { $extra['sl'] = $sl_success_rate; } if ($timestamp == 1) { $extra['timestamp'] = ($otpParams['yk_high'] << 16) + $otpParams['yk_low']; $extra['sessioncounter'] = $otpParams['yk_counter']; $extra['sessionuse'] = $otpParams['yk_use']; } sendResp(S_OK, $myLog, $apiKey, $extra); yubikey-val-2.38/ykval-queue.10000644000175000017500000000422412726004025014655 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-queue "1" "January 2013" "yubico-val" .SH NAME ykval-queue - Sync servers in a yubikey-val sync pool. .SH SYNOPSIS .B ykval-queue .SH DESCRIPTION Periodically attempts to synchronize the Yubikey counter data with other yubikey-val servers in the sync pool. Reads configuration from /etc/yubico/val/ykval-config.php This process is meant to be run as a daemon. .SH BUGS Report ykval-queue bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" The .URL "https://github.com/Yubico/yubikey-val" "yubikey-val home page" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/doc/0000755000175000017500000000000012726004025013066 5ustar jeanjeanyubikey-val-2.38/doc/Validation_Protocol_V2.0.adoc0000644000175000017500000001325312726004025020402 0ustar jeanjean== Validation Protocol Version 2.0 === Introduction All requests are HTTP GET requests. As such, all parameters must be properly URL encoded. In particular, some base64 characters (such as "+") in the value fields needs to be escaped. Each response sent by the server is signed. To verify that the response has not been tampered with, clients either verify the HMAC signature or use HTTPS connections (and verify the server certificate). === Generating signatures The protocol uses HMAC-SHA-1 signatures. The HMAC key to use is the client API key. Generate the signature over the parameters in the message. Each message contains a set of key/value pairs, and the signature is always over the entire set (excluding the signature itself), and sorted in alphabetical order of the keys. More precisely, to generate a message signature do: * Alphabetically sort the set of key/value pairs by key order. * Construct a single line with each ordered key/value pair concatenated using '&', and each key and value contatenated with '='. Do not add any linebreaks. Do not add whitespace. For example: `a=2&b=1&c=3`. * Apply the HMAC-SHA-1 algorithm on the line as an octet string using the API key as key (remember to base64decode the API key obtained from Yubico). * Base 64 encode the resulting value according to RFC 4648, for example, `t2ZMtKeValdA+H0jVpj3LIichn4=`. * Append the value under key 'h' to the message. === Verifying signatures To verify a signature on a response message, follow the same procedure that was used to sign the response message and compare the signature in the response to the signature you generated. If the signature values are equal, the signature is correct. Make sure you remove the signature itself from the values you generate the signature over for verification. If the incoming message is b=1&a=2&c=3&h=V5FkMYr9GCG9tQA9ihuuybWl99U= make sure to remove h before verifying: b=1&a=2&c=3 Don't forget to sort the key/value pairs. === Verification There is one call to verify YubiKey OTPs: verify. The verify call lets you check whether an OTP is valid. Since the OTP itself contains identification information, all you have to do is to send the OTP. To avoid cut'n'paste attacks, the client MUST verify that the "otp" in the response is the same as the "otp" supplied in the request. === Request Construct an HTTP GET call to http://api.yubico.com/wsapi/2.0/verify with the following parameters (note that this request need not be signed): [options="header"] |=== | parameter | type | required | purpose | id | string | Yes | Specifies the requestor so that the end-point can retrieve correct shared secret for signing the response. |otp | string | Yes | The OTP from the YubiKey. | h | string | No | The optional HMAC-SHA1 signature for the request. | timestamp | string | No | Timestamp=1 requests timestamp and session counter information in the response | nonce | string | Yes | A 16 to 40 character long string with random unique data | sl | string | No | A value 0 to 100 indicating percentage of syncing required by client, or strings "fast" or "secure" to use server-configured values; if absent, let the server decide | timeout | integer | No | Number of seconds to wait for sync responses; if absent, let the server decide |=== An example request: http://api.yubico.com/wsapi/2.0/verify?otp=vvvvvvcucrlcietctckflvnncdgckubflugerlnr&id=87&timeout=8&sl=50&nonce=askjdnkajsndjkasndkjsnad And if you require additional information on timestamp and session counters: http://api.yubico.com/wsapi/2.0/verify?id=87&otp=vvvvvvcucrlcietctckflvnncdgckubflugerlnr&timeout=8&sl=50&nonce=askjdnkajsndjkasndkjsnad×tamp=1 === Response The verification response tells you whether the OTP is valid. The response has the following values: [options="header"] |=== |parameter | type | purpose |otp |string |The OTP from the YubiKey, from request |nonce |string |Random unique data, from request |h |string (base64) |Signature as described above. |t |time stamp |Timestamp in UTC |status |string |The status of the operation, see below |timestamp |string |YubiKey internal timestamp value when key was pressed |sessioncounter |string |YubiKey internal usage counter when key was pressed |sessionuse |string |YubiKey internal session usage counter when key was pressed |sl |integer |percentage of external validation server that replied successfully (0 to 100) |=== These are the possible "status" values in a verify response: [options="header"] |=== | name | meaning | OK | The OTP is valid. | BAD_OTP | The OTP is invalid format. | REPLAYED_OTP | The OTP has already been seen by the service. | BAD_SIGNATURE | The HMAC signature verification failed. | MISSING_PARAMETER | The request lacks a parameter. | NO_SUCH_CLIENT | The request id does not exist. | OPERATION_NOT_ALLOWED | The request id is not allowed to verify OTPs. | BACKEND_ERROR | Unexpected error in our server. Please contact us if you see this error. | NOT_ENOUGH_ANSWERS | Server could not get requested number of syncs during before timeout | REPLAYED_REQUEST | Server has seen the OTP/Nonce combination before |=== === Changes since version 1.1 The verify URL has changed. In the request, the new required field "nonce" were added, and the new optional fields "sl" and "timeout" are added. In the response, the new fields "otp", "nonce", and "sl" are added. The status codes NOT_ENOUGH_ANSWERS and REPLAYED_REQUEST were added. Since both the URL and required fields has changed, version 2.0 is not backwards compatible with version 1.1 or version 1.0. However, because version 2.0 use a different URL than version 1.x, the server may support both version 1.x and version 2.0 clients at the same time. yubikey-val-2.38/doc/Installation.adoc0000644000175000017500000004434412726004025016370 0ustar jeanjean== Introduction This document describes how to get one instance of the Yubikey Validation Server (YK-VAL) up and running. The purpose of the Yubikey validation server is to validate Yubikey OTPs. The validation server is written in PHP, and thus needs a web server and a database. We will use Apache and MySQL, but with small modifications it should be possible to use with other implementations too (e.g., lighttpd and PostgreSQL). The validation server needs to talk to a Yubikey Key Storage Module (YK-KSM) to work. Thus, you either need to arrange for access to a remote YK-KSM and get the URL to it, or install your own YK-KSM. Currently there are two recommended implementations of a YK-KSM. If you have a YubiHSM hardware dongle and want improve security, we recommend using https://developers.yubico.com/python-pyhsm/[Python-PyHSM]. Otherwise we recommend the "soft" https://developers.yubico.com/yubikey-ksm/[YK-KSM] The YK-KSM can be on the same machine as the validation server, but for improved security we recommend to use different machines for the validation server and the KSM. The OTP validation service is delivered through web service API. There's no web-based HTML form interface involved. The protocol is defined at: http://www.yubico.com/developers/api/ For redundancy it is possible to set up multiple instances of the YubiKey Validation Server. The intent is that clients should be able to continue validate OTPs even if one of the servers are down. This is reflected in the configuration of a YK-VAL by having a "sync pool" concept. The sync pool of a particular YK-VAL instance is a list of URLs that the local server will synchronize the OTP with, depending on client request. Normally if you have 5 servers, each server will have a list of the 4 other servers in its sync pool -- however it IS possible to deviate from this if for some reason it is not possible to reach one particular server from one of the servers. For simplicity, we strongly recommend you to list non-local servers in each sync pool though. == Installation The following steps apply to any GNU/Linux-like system, although it was written for Debian GNU/Linux. If you do not know which OS to use, we recommend a default choice of Ubuntu 14.04 LTS since it is a well-known distribution that comes with 5 years of security support. Install the OS following its manual and enable automatic security upgrades if prompted. === Step 1: YK-VAL Installation First you should download and install the latest YK-VAL release: [source, sh] ---- user@val:~$ sudo apt-get install git make ... user@val:~$ git clone https://github.com/Yubico/yubikey-val.git ... user@val:~$ cd yubikey-val user@val:~/yubikey-val$ sudo make install ---- Depending on your distribution, the group of Apache (or the HTTP server) might be different from `www-data`, used in Debian and Ubuntu. On Red Hat, Fedora or CentOS the group is `apache` and in SUSE it is `www`. [source, sh] ---- user@val:~/yubikey-val: sudo make install wwwgroup=apache ---- The rest of this documentation will assume you have YK-VAL available in the default installation targets. You can override the paths, see the Makefile. === Step 2: Install web server and PHP You also need to install a web server with PHP5, php5-curl and php-pear. [source, sh] user@val:~$ sudo apt-get install apache2 php5 php5-curl php-pear Any web server with PHP support should work. === Step 3: Database installation Any SQL database with PHP support should work. We give examples for MySQL and PostgreSQL here. Note that you need to chose between either PostgreSQL or MySQL here. ==== Step 3A: MySQL Installation Install the required packages: [source, sh] user@val:~$ sudo apt-get install mysql-server php5-mysql The installation asks you for a MySQL "root" password, and I recommend to specify one. To avoid having to specify a password when using the 'mysql' tool interactively, you can store the password in `~/.my.cnf`, see `/usr/share/doc/mysql-server-5.0/README.Debian.gz`. For example: [source, sh] ---- user@val:~$ cat > .my.cnf [client] user = root password = YOURPASSWORD user@val:~$ chmod go-r .my.cnf user@val:~$ ---- Note the 'chmod' to protect your password from non-root users. The database needs to be initialized as follows: [source, sh] ---- user@val:~$ echo 'create database ykval' | mysql user@val:~$ mysql ykval < /usr/share/doc/yubikey-val/ykval-db.sql user@val:~$ ---- You also need to create a database user for the verifier interface, normally called 'ykval_verifier': [source, sh] ---- user@val:~$ mysql --silent ykval mysql> CREATE USER 'ykval_verifier'@'localhost'; \ GRANT SELECT,INSERT,UPDATE(modified, yk_counter, yk_low, yk_high, yk_use, nonce) ON ykval.yubikeys TO 'ykval_verifier'@'localhost'; \ GRANT SELECT,INSERT,UPDATE(id, secret, active) ON ykval.clients TO 'ykval_verifier'@'localhost'; \ GRANT SELECT,INSERT,UPDATE,DELETE ON ykval.queue TO 'ykval_verifier'@'localhost'; \ SET PASSWORD FOR 'ykval_verifier'@'localhost' = PASSWORD('yourpassword'); \ FLUSH PRIVILEGES; mysql> \q user@val:~$ ---- ==== Step 3B: PostgreSQL Installation Install the required packages: [source, sh] ---- user@val:~$ sudo apt-get install postgresql php5-pgsql ... user@val:~$ ---- The database needs to be initialized as follows: [source, sh] ---- user@val:~$ sudo su postgres postgres@val:~$ createdb ykval postgres@val:~$ psql ykval < /usr/share/doc/yubikey-val/ykval-db.sql postgres@val:~$ ---- You also need to create a database user for the verifier interface, normally called 'ykval_verifier': [source, sh] ---- postgres@val:~$ psql ykval -q ykval=# CREATE USER ykval_verifier PASSWORD 'yourpassword'; ykval=# GRANT SELECT,INSERT,UPDATE ON yubikeys TO ykval_verifier; ykval=# GRANT SELECT,INSERT,UPDATE ON clients TO ykval_verifier; ykval=# GRANT SELECT, INSERT, UPDATE, DELETE ON queue TO ykval_verifier; ykval=# \q postgres@val:~$ ---- Don't forget to switch back to your normal user [source, sh] ---- postgres@val:~$ exit user@val:~$ ---- During installation and debugging it may be useful to watch the database log entries: [source, sh] user@val:~$ sudo tail -F /var/log/postgresql/postgresql-*-main.log & === Step 4: Setup Verify OTP Interface The interface to verify OTPs is implemented using a PHP script. You can place the script under any URL, but we recommend serving it as 'http://ykval.example.org/wsapi/verify'. The simplest way to setup the symlinks is to invoke 'make symlink' in your YK-VAL source tree. Like this: [source, sh] ---- user@val:~/yubikey-val$ sudo make symlink install -d /var/www/wsapi/2.0 ln -sf /usr/share/yubikey-val/ykval-verify.php /var/www/wsapi/2.0/verify.php ln -sf /usr/share/yubikey-val/ykval-sync.php /var/www/wsapi/2.0/sync.php user@val:~/yubikey-val$ ---- If you want to do it manually, you can invoke the above commands manually. === Step 5: Include path configuration Set the include path for the queue daemon by creating a file /etc/default/ykval-queue with the following content: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/default/ykval-queue' DAEMON_ARGS="/etc/yubico/val:/usr/share/yubikey-val" user@val:~$ ---- You also need to set the include path for the PHP scripts running via Apache, using a .htaccess file: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /var/www/wsapi/2.0/.htaccess' RewriteEngine on RewriteRule ^([^/\.\?]+)(\?.*)?$ $1.php$2 [L] php_value include_path ".:/etc/yubico/val:/usr/share/yubikey-val" user@val:~$ sudo ln -s 2.0/.htaccess /var/www/wsapi/.htaccess user@val:~$ ---- The .htaccess file also sets up rewriting from the non-.PHP suffix URL name to the right script. The paths are the default, if you installed the YK-VAL in some other place you need to modify the paths. === Step 6: YK-VAL Configuration You also need to create a ykval-config.php script. An example file is included in YK-VAL package as ykval-config.php A template is typically installed in /etc/yubico/val/ykval-config.php-template. [source, sh] ---- user@val:~$ sudo cp /etc/yubico/val/ykval-config.php-template /etc/yubico/val/ykval-config.php user@val:~$ sudo emacs -nw /etc/yubico/val/ykval-config.php ---- Be careful about the user permissions and ownership so that unrelated users on the system cannot read the database password. You will typically need to modify the DSN (`__YKVAL_DB_DSN__`), database passwords (`__YKVAL_DB_PW__`), the sync pool lists (`__YKVAL_SYNC_POOL__` and `__YKVAL_ALLOWED_SYNC_POOL__`), and the YK-KSM URLs inside the otp2ksmurls function. An example DSN for a MySQL setup: [source, php] $baseParams['__YKVAL_DB_DSN__'] = "mysql:dbname=ykval;host=127.0.0.1"; An example DSN for a PostgreSQL setup: [source, php] $baseParams['__YKVAL_DB_DSN__'] = "pgsql:dbname=ykval;host=127.0.0.1"; We recommend to add the hosts in YKVAL_SYNC_POOL as entries in '/etc/hosts' to avoid network delays caused by DNS-lookups. For example: [source, sh] ---- user@val:~$ sudo sh -c 'cat >> /etc/hosts' 1.2.3.4 api1.example.com 2.3.4.5 api2.example.com user@val:~$ ---- To improve database performance you can use persistent database connection so that each request doesn't require a new connection to be setup. To enable this modify `__YKVAL_DB_OPTIONS__` as follows: [source, php] $baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_PERSISTENT => true); === Step 7: Apache configuration Create an apache web configuration file for the normal HTTP interface like this: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval.conf' ServerName api.example.com ServerAdmin support@example.com DocumentRoot /var/www/ Options FollowSymLinks AllowOverride None Options FollowSymLinks AllowOverride All Order allow,deny allow from all ErrorLog /var/log/apache2/ykval-error.log LogLevel warn CustomLog /var/log/apache2/ykval-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" ServerSignature On user@val:~$ ---- HTTPS is strictly speaking not required, but we strongly recommend it. You need to install a TLS stack for Apache, there are two popular options here: mod_gnutls and mod_ssl. We'll explain how to install both, but you will need to decide which one to use. You will need to create a key/certificate for your server using normal tools like GnuTLS "certtool". A small howto for !GoDaddy is available from http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/4062. ==== Step 7A: HTTPS via mod_gnutls First install and enable the mod_gnutls module: [source, sh] ---- user@val:~$ sudo apt-get install libapache2-mod-gnutls user@val:~$ sudo a2enmod gnutls Enabling module gnutls. Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$ ---- You will need to place the private key in /etc/ssl/private/api.example.com-key.pem and the certificate chain in /etc/ssl/private/api.example.com-chain.pem. Create Apache web configuration files: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl.conf' Listen 443 ServerName api.example.com ServerAdmin support@example.com GnuTLSEnable on GnuTLSCertificateFile /etc/ssl/private/api.example.com-chain.pem GnuTLSKeyFile /etc/ssl/private/api.example.com-key.pem GnuTLSPriorities NORMAL DocumentRoot /var/www/ Options FollowSymLinks AllowOverride None Options FollowSymLinks AllowOverride All Order allow,deny allow from all ErrorLog /var/log/apache2/ykval-ssl-error.log LogLevel warn CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" ServerSignature On user@val:~$ ---- ==== Step 7B: HTTPS via mod_ssl The mod_ssl module is typically installed by default, but you need to enable it. [source, sh] ---- user@val:~$ sudo a2enmod ssl Enabling module ssl. Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$ ---- You will need to place the private key in /etc/ssl/private/api.example.com-key.pem and the certificate chain in /etc/ssl/private/api.example.com-chain.pem. [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl.conf' ServerName api.example.com ServerAdmin support@example.com SSLEngine on SSLCertificateFile /etc/ssl/private/api.example.com-chain.pem SSLCertificateChainFile /etc/ssl/private/api.example.com-chain.pem SSLCertificateKeyFile /etc/ssl/private/api.example.com-key.pem DocumentRoot /var/www/ Options FollowSymLinks AllowOverride None Options FollowSymLinks AllowOverride All Order allow,deny allow from all ErrorLog /var/log/apache2/ykval-ssl-error.log LogLevel warn CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" ServerSignature On user@val:~$ ---- ==== Common Apache Configuration This step is the same for both mod_gnutls and mod_ssl. [source, sh] ---- user@val:~$ sudo a2enmod rewrite Enabling module rewrite. Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$ sudo a2dissite default Site default disabled. Run '/etc/init.d/apache2 reload' to activate new configuration! user@val:~$ sudo a2ensite ykval ykval-ssl Enabling site ykval. Enabling site ykval-ssl. Run '/etc/init.d/apache2 reload' to activate new configuration! user@val:~$ sudo /etc/init.d/apache2 restart user@val:~$ ---- === Step 8: Logging The PHP interface uses syslog for logging of incoming requests. The facility is LOG_LOCAL0. To place these messages in a separate file, you can add the following to /etc/syslog.conf, or if you use rsyslog, create a file /etc/rsyslog.d/ykval.conf with this content: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/rsyslog.d/ykval.conf' local0.* -/var/log/ykval.log user@val:~$ sudo /etc/init.d/rsyslog restart ... user@val:~$ ---- The '-' before the filename avoids syncing the file after each write, which is recommended for performance. The log file can grow large quickly, so it is a good idea to setup rotation of log files. Here is an example that rotates the log file weekly. Create a file /etc/logrotate.d/ykval like this: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/logrotate.d/ykval' /var/log/ykval.log { weekly dateext compress missingok rotate 9999 notifempty postrotate invoke-rc.d rsyslog reload > /dev/null endscript } user@val:~$ ---- You may want to modify the default /etc/logrotate.d/apache2, useful things to add are 'dateext' and 'compress' and change 'rotate' to something large if you want to retain logs. === Step 8.1: Fix default log (optional) Unfortunately, most default syslog configuration, including the syslog.conf configuration file on Debian, will also log all entries to /var/log/syslog and/or /var/log/messages. I am not aware of any way to avoid this without modifying these other rules. To avoid YK-VAL log entries in these other files, you must modify the default rules. For example, edit the following lines of /etc/rsyslog.conf (or /etc/syslog.conf if you don't use rsyslog): [source, sh] ---- *.=debug;\ auth,authpriv.none;\ news.none;mail.none -/var/log/debug *.*;auth,authpriv.none -/var/log/syslog *.=info;*.=notice;*.=warn;\ auth,authpriv.none;\ cron,daemon.none;\ mail,news.none -/var/log/messages ---- Change them into: [source, sh] ---- *.=debug;\ auth,authpriv.none;\ news.none;mail.none;local0.none -/var/log/debug *.*;auth,authpriv.none,local0.none -/var/log/syslog *.=info;*.=notice;*.=warn;\ auth,authpriv.none;\ cron,daemon.none;\ local0.none;\ mail,news.none -/var/log/messages ---- Idempotent commands to speed this up: [source, sh] ---- user@host:~$ sudo perl -pi -e 's/;auth,authpriv.none/;auth,local0.none,authpriv.none/' /etc/rsyslog.conf user@host:~$ sudo perl -pi -e 's/news.none;mail.none/news.none;local0.none;mail.none/' /etc/rsyslog.conf user@host:~$ sudo perl -pi -e 's/cron,daemon.none/cron,daemon.none;local0.none/' /etc/rsyslog.conf user@host:~$ sudo /etc/init.d/rsyslog restart ---- === Step 9: Start Sync Daemon When using yubikey-val in a sync pool, you need to have the ykval-queue daemon running to ensure that data is synchronized between the servers in the pool. The easiest way of running this is to simply invoke ykval-queue in a shell: [source, sh] user@val:~$ sudo ykval-queue However, the recommended approach is to automate running this process in the background, by use of an init script or similar. Instructions on doing so vary depending on your operating system. === Step 10: Sync data from an existing server (optional) If you're adding a new server to an existing pool, you can synchronize all YubiKey counter data from one of the existing servers. To do so, the server you want to sync from needs to be configured to allow it. Do this by editing /etc/yubico/val/ykval-config.php on the existing server, adding the new servers IP address to the `__YKRESYNC_IPS__` setting. You'll most likely want to add the IP to the `__YKVAL_ALLOWED_SYNC_POOL__` setting as well. You also need to edit this file on the new server, adding the existing server(s) IP address(es) to `__YKVAL_ALLOWED_SYNC_POOL__`. Once these permissions have been configured, you can initiate the full sync by running the following command from the new server: [source, sh] user@val:~$ ykval-synchronize http:///wsapi/2.0/resync all === Step 11: Test it You can test the service by requesting a URL. Using wget, for example: [source, sh] ---- user@val:~$ wget -q -O - 'http://localhost/wsapi/2.0/verify?id=1&nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak&otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh' h=/QVWkl5VlcX+Or1A2b3vOeoLEwI= t=2010-05-17T14:48:15Z0355 otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak status=NO_SUCH_CLIENT user@val:~$ ---- Naturally, you will need to import client keys into the database for the verify function to work properly. === The End You now have a YK-VAL up and running. See https://developers.yubico.com/yubikey-ksm/Server_Hardening.html on how to improve security of your system. yubikey-val-2.38/doc/Server_Replication_Protocol.adoc0000644000175000017500000000511612726004025021401 0ustar jeanjean== Server Replication Protocol This document describes the server to server protocol. Its purpose is to synchronize the last used session and use counter between multiple validation servers. Multiple validations servers are connected together so that each validation server can talk to any of the other validation server using the Server Replication Protocol. The validation servers are authenticated by the use of certificates. val A <-> val B <-> val C <-> val A See the ValidationProtocolV20 for definition of the client to server protocol. The protocol described here is the server to server protocol. See ValidationServerAlgorithm for a description of the implementation algorithm that uses this protocol. === Sync request specification A sync request is issued with a HTTP get call, like this: https://apiX.yubico.com/wsapi/sync?otp=xyz&modified=1264430686&nonce=foobar&yk_identity=foo&yk_counter=42&yk_use=17&yk_high=10&yk_low=5 The following parameters are used [options="header"] |============================= | parameter |type |values | otp | string | one-time password (for logging purposes) | modified | integer | unix timestamp of when OTP was received | nonce | string | nonce from client request | yk_identity | modhex | YubiKey OTP identity in question | yk_counter | integer | last seen session counter by sender | yk_use | integer | last seen session use by sender | yk_high | integer | OTP internal high time value | yk_low | integer | OTP internal low time value |============================== Input values for yk_counter, yk_use, yk_high and yk_low are always positive except for -1 which indicates that the requesting server did not have any earlier information about the !YubiKey. An example response is modified=1264430686 nonce=aspodkaaspdokas yk_identity=cccccccccccf yk_counter=api2 session counter yk_use=api2 session use counter yk_high=value yk_low=value The values returned are: [options="header"] |==================== | parameter |type |values | modified | integer | timestamp of when last OTP was received | nonce | string | nonce from client for last OTP | yk_identity | modhex | YubiKey OTP identity in question | yk_counter | integer | last seen session counter | yk_use | integer | last seen session use | yk_high | integer | last seen high time value | yk_low | integer | last seen low time value |======================== Output values for modified, yk_counter, yk_use, yk_high and yk_low are always positive except for -1 which indicates that the server did not have any earlier information about the YubiKey. In this case, nonce is a newly allocated random nonce. yubikey-val-2.38/doc/Revocation_Service.adoc0000644000175000017500000000273712726004025017520 0ustar jeanjean== Introduction The YK-VAL server has an optional interface that can be used to enable/disable validation of particular YubiKeys from a remote server. This document explains how to configure and set up that service. Currently authorization is based on IP address of client, which may not be secure unless you take additional pre-cautions. == Installation [source, sh] ---- user@val:~/yubikey-val$ sudo make revoke user@val:~/yubikey-val$ ---- == Configuration Add the following to your /etc/yubico/val/ykval-config.php: [source, php] ---- # For the revoke service. $baseParams['__YKREV_IPS__'] = array('10.0.0.1', '2000:1:2:3::4'); ---- Obviously you need to modify the IP address. You also need to grant additional rights to the database, for MySQL: [source, sh] ---- user@val:~$ mysql --silent ykval mysql> GRANT UPDATE(active) ON ykval.yubikeys to 'ykval_verifier'@'localhost'; \ FLUSH PRIVILEGES; mysql> \q user@val:~$ ---- For PostgreSQL this should already be working, through this command: [source, sh] ---- postgres@val:~$ psql ykval -q ykval=# GRANT UPDATE ON yubikeys TO ykval_verifier; ykval=# \q postgres@val:~$ ---- == Testing Test the installation like this: [source, sh] ---- user@revoke:~$ wget -q -O - 'http://api.example.com/wsapi/revoke?yk=dteffujehknh&do=enable' OK Processed dteffujehknh with enable user@revoke:~$ ---- Use 'disable' instead of 'enable' to test disabling of the YubiKey. == The End You now have the YK-VAL Revocation Service up and running. yubikey-val-2.38/doc/Sync_Monitor.adoc0000644000175000017500000000235712726004025016350 0ustar jeanjean== YK-VAL Synchronization Monitor If you deploy multiple YK-VAL instances, it is important to monitor them to make sure the data they have is synchronized. While there are many mechanisms to achieve this, we provide a simple yet flexible approach. The 'ykval-checksum-clients' tool reads out the important fields from the database and computes a SHA-1 hash of it, and truncates the hash to 10 hex characters and prints them to stdout. The "important fields" are currently considered to be the id, active, and secret columns of the clients table. The typical way to use this is either manually or to run it in a cron job and output the hash to a file that can be downloaded by a remote monitor system such as Nagios. [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/cron.hourly/run-ykval-checksum-clients' #!/bin/sh FILE=/var/www/checksum-clients.txt (date --utc +%s; ykval-checksum-clients) > $FILE.tmp mv $FILE.tmp $FILE user@val:~$ sudo chmod +x /etc/cron.hourly/run-ykval-checksum-clients ---- If you notice mismatches, you may want to run ykval-checksum-clients with the '-v' parameter on the different hosts and then use 'diff -ur' or similar tool to compare the outputs. This should make it possible to identify the missmatching entries easily. yubikey-val-2.38/doc/Getting_Started_Writing_Clients.adoc0000644000175000017500000001166012726004025022175 0ustar jeanjean== Getting Started Writing Clients === Introduction While the canonical description of the validation protocol is documented in link:Validation_Protocol_V2.0.adoc[Validation Protocol V2.0], it may be difficult to grasp the high level of how a client typically works. The intention with this page is to illustrate one simple case. NOTE: This does not cover the replicated protocol. If you want to make your own client implementation, here is the quickest way to get started: === API key API key is used to optionally sign the OTP validation request and to verify the OTP validation response. We recommend all production deployments use either API key or HTTPS. If you use HTTPS to access Yubico's validation web service and you validate the Yubico server SSL certificate, you don't need to use the shared key to further authenticate response signatures from Yubico. If you for some reason do not want to rely on HTTPS. You may also sign requests using this API key. To get an API key, first use https://upgrade.yubico.com/getapikey/[our online API key generator]. It will assign you an ID and create a shared key. You can use the shared key to authenticate that the API responses do come from Yubico. === Capture an OTP Capture an OTP output from your YubiKey. You can do that by opening a text editor and simply pressing the button on the YubiKey. The OTP is a simple string of characters, like this: vvvvvvcurikvhjcvnlnbecbkubjvuittbifhndhn === Validate OTP format Prudent clients should validate the data entered by the user so that it is what the software expects. YubiKey OTPs consists of 32-48 characters in the ModHex alphabet `cbdefghijklnrtuv`. Unfortunately, this has turned out to be over-aggresive because if the keyboard layout is Dvorak-based, it will look differently. For example, the modhex alphabet in the US Dvorak layout is `jxe.uidchtnbpygk`. There are other Dvorak layouts as well. For this reason, our recommendation is that clients only check that the input consists of 32-48 printable characters. === Send OTP to our server Send the authentication request to our servers following the protocol specified below. Your request should include the verifier ID (a number that identifies the signature key), the OTP you captured in the previous instruction, and a random looking string of characters to make the request unique. The request is part of the HTTP GET URL, encoded using normal parameter/value pairs. For example (broken into two lines for legibility): http://api2.yubico.com/wsapi/2.0/verify?id=1&otp=cccccccbcjdifc\ trndncchkftchjlnbhvhtugdljibej&nonce=aef3a7835277a28da831005c2ae3b919e2076a62 The servers that Yubico provides are: api.yubico.com api2.yubico.com api3.yubico.com api4.yubico.com api5.yubico.com These servers are hosted in different places and by different organizations. === Parse response You will recieve a response back from the server, a string of text that resembles the following: h=vjhFxZrNHB5CjI6vhuSeF2n46a8= t=2010-04-23T20:34:51Z0678 otp=cccccccbcjdifctrndncchkftchjlnbhvhtugdljibej nonce=aef3a7835277a28da831005c2ae3b919e2076a62 sl=75 status=OK You can check the authenticity of this response by checking that the OTP and nonce was the same as the one you requested validation for and verify the HMAC-SHA-1 signature. === Make a decision Use the `status=` codes to make a decision whether to authenticate your user or not. All the status codes and their meanings are described by the protocol specification, see below. === Binding an OTP to an Identity Since a valid OTP on its own is not terribly useful, you need to connect it to a user in some way. This is normally not something the client needs to do, it belongs elsewhere in the application, however for completeness we mention how it is done here. In some situations, the user is typing her username directly into your application, which solves the issue. More generally, the YubiKey OTP contains as the initial part an identity of the YubiKey, and it can be used to identify the user. The identity part is the same for every OTP, and it is the initial 2-16 modhex characters of the OTP. (The identity can be programmed to 0 characters, but then obviously this scheme does not apply.) Since the rest of the OTP is always 32 characters, the method to extract the identity is to remove 32 characters from the end and then use the remaining string, which should be 2-16 characters, as the YubiKey identity. Note that the validation server is case insensitive, so you need to lower-case the string in order to avoid caps lock resulting in different identities with the only differ being case of the prefix. Typically you would store the association between the user and the YubiKey prefix in a database. === The End There are some more subtle matters that can be important, so please read the entire protocol specification for all the details. Further, for added reliability, you may send the request in parallel to more than one server, which is not explained above. yubikey-val-2.38/doc/Generating_Clients.adoc0000644000175000017500000000516112726004025017465 0ustar jeanjean== Generating Clients For a client to be able to authenticate a YubiKey OTP with the Validation service, a client ID and matching secret is needed (the secret is only required for authenticated verification). To create a new client in the database with a new generated secret, the ykval-gen-clients command can be used. This document describes step by step instructions on generating and using clients. For more information regarding the various fields of the client database, see link:Client_Info_Format.adoc[Client Info Format]. === Client generation Use the command below to generate 5 clients. Note the usage of the --urandom flag, which speeds up generation, but is less secure! The command is run as root (using sudo), since it needs to be able to read the database configuration stored in /etc/yubico/val/config-db.php. [source, sh] ---- user@val:~$ sudo ykval-gen-clients --urandom 5 1,l+/c/XfDPDHsaNKrpjwL+bf/Hgs= 2,LPGHqukoIAUGgDuOs7O0e1f8xD0= 3,K+gWRE0euOjVOiLD4Nm0wyHrHY8= 4,+8LF+ADANTAHnwB82xkBb+mNEFs= 5,URc6oabcuRV8OWW1Hs1cYym3ba4= user@val:~$ ---- === Testing the clients The above clients can now be used with the validation server. If you have a YubiKey validation client, you can easily test this now. For example, using the ykclient command (available in the ykclient-dev package, which is in Debian as well as Ubuntu): [source, sh] ---- user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey LPGHqukoIAUGgDuOs7O0e1f8xD0= 2 cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv Input: validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s client id: 2 token: cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv api key: LPGHqukoIAUGgDuOs7O0e1f8xD0= Verification output (1): Yubikey OTP was bad (BAD_OTP) user@val:~$ ---- Note that even though the response was BAD_OTP (since the key used is in fact a bad OTP), the verification worked as expected. Compare it to the next example: [source, sh] ---- user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey not_a_real_secret 3 cccccccccccdutfiljtbignggckhgdtfigbdricugdrvInput: validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s client id: 3 token: cccccccccccdutfiljtbignggckhgdtfigbdricugdrv api key: not_a_real_secret Verification output (106): Server response signature was invalid (BAD_SERVER_SIGNATURE) user@val:~$ ---- In the above example, the server actually noticed that the client secret was incorrect, and responded as it should. The response is signed with the correct secret, which the client then interprets as invalid (since it thinks the correct key is the dummy key we just gave it). yubikey-val-2.38/doc/YubiKey_Info_Format.adoc0000644000175000017500000000230312726004025017560 0ustar jeanjean== Format of YubiKey Info Data This file holds data used in the YubiKey OTP validation phase. Each of the lines in the file follows the following format: active,created,modified,yk_publicname,yk_counter,yk_use,yk_low,yk_high,nonce,notes Any empty line, or a line beginning with a # is ignored. The meaning are as follows: active:: the YubiKey state, 1 if active, 0 if not created:: unix timestamp of when the YubiKey entry was created, decimal integer modified:: unix timestamp of when the YubiKey entry was last modified, decimal integer yk_publicname:: the public id of the YubiKey, modhex string yk_counter:: the YubiKey session counter, decimal integer yk_use:: the YubiKey use counter, decimal integer yk_low:: the low part of the YubiKey timestamp counter, decimal integer yk_high:: the high part of the YubiKey timestamp counter, decimal integer nonce:: the nonce used for the last validation request, ascii printable string notes:: not used, printable ascii string An example of a valid data line: 1,1359470658,1359470658,cccccccccccb,2,1,32729,4,aoincuhfuahs For an example of importing and exporting YubiKey Info data, please see link:Import_Export_Data.adoc[Import Export Data] yubikey-val-2.38/doc/Make_Release.adoc0000644000175000017500000000167012726004025016237 0ustar jeanjean== Maintainer instructions for making releases === Introduction The point of this document is to describe all steps required to make a proper release of the yubikey-personalization project. === Dependencies Making a release requires the following packages: make, git, gnupg, git2cl which can be installed (under Ubuntu) by running: sudo apt-get install make git gnupg git2cl === Details * Make sure the doc/ sub-directory uses the latest revision. Confirm with: cd doc && git checkout master && git pull && git diff * Make sure the version number in Makefile has been incremented. * Make sure NEWS describes all changes since the last release. Use https://github.com/Yubico/yubikey-val/commits/master to review. * Change the '(unreleased)' part in NEWS to '(released 20XX-YY-ZZ)' and commit that with a note 'Version Q.P'. * Run 'make release'. * Increment version number in Makefile and add a NEWS template for the next release. yubikey-val-2.38/doc/Import_Export_Data.adoc0000644000175000017500000000561012726004025017464 0ustar jeanjean== Importing and Exporting Data The yubikey-val database holds client data as well as yubikey counter data which you can import and export using the provided tools. As it is important to protect the data, we will show you how to encrypt and decrypt these files using GnuPG. You will therefor require a private key for both importing as well as exporting (these can be the same keys, or differnent ones, depending on if you are importing on the same system as you have exported from). === Client Info Data The client data holds information about the clients that are able to use the validation service, such as their ID and secret key. This data is stored in the *clients* table of the database. The information here covers exporting existing clients to a file, and importing the clients from that file into another database. For generating clients, see link:Generating_Clients.html[Generating Clients] To export client data, you can use the following command (Replace C5B8D4EA with the key of the recipient of the data): .... user@val:~$ sudo ykval-export-clients | gpg -a --encrypt -r C5B8D4EA -s > yk-client-info.asc You need a passphrase to unlock the secret key for user: "YK-KSM import key" 2048-bit RSA key, ID C5B8D4EA, created 2013-01-28 user@val:~$ .... To import the client data exported above, you can use: .... user@val:~$ gpg < yk-client-info.asc | sudo ykval-import-clients You need a passphrase to unlock the secret key for user: "YK-KSM import key" 2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA) gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28 "YK-KSM import key" gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA gpg: Good signature from "YK-KSM import key" Successfully imported clients to database user@val:~$ .... === Yubikey Counter Data The Yubikey counter data holds information about the state of the known Yubikeys, such as their various counter values. This data is stored in the *yubikeys* table of the database. To export Yubikey counter data, you can use the following command (Replace C5B8D4EA with the key of the recipient of the data): .... user@val:~$ sudo ykval-export | gpg -a --encrypt -r C5B8D4EA -s > yk-counter-data.asc You need a passphrase to unlock the secret key for user: "YK-KSM import key" 2048-bit RSA key, ID C5B8D4EA, created 2013-01-28 user@val:~$ .... To import the counter data exported above, you can use: .... user@val:~$ gpg < yk-counter-data.asc | sudo ykval-import You need a passphrase to unlock the secret key for user: "YK-KSM import key" 2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA) gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28 "YK-KSM import key" gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA gpg: Good signature from "YK-KSM import key" Successfully imported yubikeys to database user@val:~$ .... yubikey-val-2.38/doc/Munin_Probes.adoc0000644000175000017500000000370412726004025016322 0ustar jeanjean== YK-VAL Munin Plugin Munin is a powerful system monitoring solution. See http://munin-monitoring.org/ for more information. This document documents how to install and enable the YK-VAL Munin plugins on a Munin node. You need to install and configure Munin before following these steps. The following Munin plugins are shipped as part of YK-VAL. They make it easy for you to monitor your YK-VAL installation. ykval_ksmlatency:: Monitor the latency to each KSM. A useful side effect is that it tests whether the KSM is operational for the particular validation server. ykval_vallatency:: Monitor the latency to the other VAL servers, for both IPv4 and IPv6. ykval_queuelength:: Monitor the size of the YK-VAL queue. The plugins are installed by 'make install' but needs to be configured before they can be used. First create a Munin configuration file to make sure the plugins can access the YK-VAL ykval-config.php configuration file: [source, sh] ---- user@val:~$ sudo sh -c 'cat > /etc/munin/plugin-conf.d/ykval' [ykval_ksmlatency] group www-data [ykval_vallatency] group www-data [ykval_queuelength] group www-data user@val:~$ ---- Then check that they are working properly: [source, sh] ---- user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength autoconf yes user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength config graph_title YK-VAL queue size graph_vlabel sync requests in queue graph_category ykval queuelength.label sync requests queuelength.draw AREA user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength queuelength.value 0 user@val:~$ ---- Enable the plugin as follows: [source, sh] ---- user@val:~$ sudo munin-node-configure --shell | sudo sh user@val:~$ sudo /etc/init.d/munin-node restart Stopping Munin-Node: done. Starting Munin-Node: done. user@val:~$ ---- After some time, you should see new graphs on your Munin master. yubikey-val-2.38/doc/Validation_Server_Algorithm.adoc0000644000175000017500000002512012726004025021344 0ustar jeanjean== Validation Server Algorithm This document describes how a validation server should be implemented, and the required steps it needs to perform in order to be secure. The client-to-server protocol is described in link:Validation_Protocol_V2.0.adoc[Validation Protocol V2.0] and the server-to-server protocol is described in lnk:Server_Replication_Protocol.adoc[Server Replication Protocol]. === Normal validation with Sync Val X receives an OTP verify request and needs to update the other validation servers on the last seen counter values. The procedure is as follows . Val X parses validation request, retrieves the client key for the client id from local database and checks the request signature. . Val X decrypts the OTP using a KSM and reads out the modified/counters from the internal database -- if the YubiKey identity doesn't exist in the database, add it with counter/use/high/low=-1. . Val X checks the OTP/Nonce against local database, and replies with REPLAYED_REQUEST if local information is identical. . Val X checks the OTP counters against local counters, and rejects OTP as replayed if local counters are higher than or equal to OTP counters. . Val X updates the internal database with counters/nonce from request. . Val X queues a sync request in a sync queue for each validation server in the validation server pool (manually configured). . Val X requests the queued requests (otp, modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) to be sent out, by sending parallel sync requests to all other validation servers. . Each validation server receiving a sync request updates its own internal database with received information to use the highest counter. . Each remote server responds with a sync response (modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) using data from its internal database. . Val X waits for a sync response (up until timeout, or when sufficient number of sync responses indicating valid OTP and no sync response indicating invalid OTP) from the other validation servers to which it sent a sync request. For each response that arrives the corresponding entry in the sync queue is removed and the following is checked .. If the sync response counters have higher values than val X internal database, the internal database is updated with new information, AND .. If the sync response counter have higher values as val X internal database the response is considered to mark the OTP as invalid, AND .. If the sync response have equal counter values and nonce as val X internal database the response is considered to mark the OTP as valid, AND .. If the sync response have equal counter values and different nonce as val X internal database the response is considered to mark the OTP as invalid, AND .. If the sync response counter have smaller values than val X had in its internal database before the validation attempt the server logs a warning, and the response is considered to mark the OTP as valid. . Val X construct validation response. Validation is successful if the Verification Algorithm below is successful. . Val X marks the remaining entries in the sync queue as marked with timestamp=NULL. Any remaining sync requests in the sync queue are from now on handled by a background daemon which re-sends them at regular intervals (described below). ==== Verification algorithm .... Input: otp - the otp nonce - the nonce from the request yk:counter - the session counter yk:use - the session use counter yk:high - the high timestamp yk:low - the low timestamp modified - when the counters were last modified Output: Error code. .... Val X requires that SL % of the sent sync requests gives a response marking the OTP as valid, and that none of the responses indicate the OTP is invalid, in order to consider the OTP to be valid. . If internal database counters are equal to otp counters AND nonce is identical, then return REPLAYED_REQUEST. . If internal database counters are higher/equal to otp counters, then return REPLAYED_OTP. . If any counter in sync response are higher/equal to otp counters, then return REPLAYED_OTP. . If insufficient number of sync responses are received, then return NOT_ENOUGH_ANSWERS. . (optional: if phishing test fails, return DELAYED_OTP) . return OK ==== Warning algorithm Warn if any of these are true: * If received sync response have lower counters than locally saved last counters (indicating that remote server wasn't synced) * If received sync response have higher counters than locally saved last counters (indicating that local server wasn't synced) * If received sync response have counters higher than or equal to the OTP counters (indicating that the OTP is replayed) * If received sync request have counters equal to local counters and modified field equal to local modified field (sync request has been unnecessarily resent). * If received sync request have counters equal to local counters and modified field different to local modified field (We might have a replay. 2 events at different times have generated the same counters) * If received sync request have lower counters than local (indicating that remote server is not synced) * If received sync request have identical counters but different nonce (indicating that remote server received a request to validate an already validated OTP) ==== Update validation server that has been offline Val X has been out of function and its internal database needs to be updated. This case is handled automatically since the sync requests which did not succeed immediately in the previous point are queued. When val X is accessible again, all the sync requests in queue are re-sent and val X database is updated. Responses which would have caused the sender of the sync request to consider the OTP as invalid will give raise to a warning on the sender validation server. === Sync queue daemon There is one queue daemon that is responsible for sending all the queued requests. The sync queue will loop the following algorithm. . Get a list of all remote server from the database; S1, S2, ... . For each remote server S in the list S1, S2, ... do .. For each entry in the queue table for S which have a queued_time==NULL or a timestamp older than a configured period (e.g., one minute) do ... Send one request, using a configured timeout value (e.g., 30 seconds). ... If the request is unsuccessful (or times out), quit to the outer loop. ... The request was successful so the sync daemon receives counter/nonce values from the remote server. ... If the sync response counters are lower, give a warning ... If the sync response counters are equal and nonce different, give a warning ... If the sync response counter have higher than or equal values as val X internal database had at the moment of request creation a warning is logged. ... The sync daemon updates the internal database to use the highest counter values: {{{UPDATE yubikeys SET counter = X, sessionUse = Y, high = P, low = Q, nonce = N, accessed = D WHERE publicName = ID AND ((counter < X) OR (counter = X AND sessionUse < Y))}}} ... The corresponding entry in the sync queue is removed. === Logging matrix Available parameters in comparisons are the following. |================ | local | Local parameters at time of comparison | otp | Parameters from OTP provided in validation request | response | Parameters in sync respone | request | Parameters in sync request | validation | Local parameters when OTP vaildation request arrived |================ Parameters could be counters, modified, nonce. === Non-queued Sync response logging We compare reponse parameters against validation parameters since we are interested in if the server is in sync at the moment when the validation request arrives. [options="header"] |============= | condition |level |action |message | response.counters < validation.counters | Notice | None | Remote server out of sync. | response.counters > validation.counters | Notice | None |Local server out of sync. | response.counters = validation.counters and response.nonce != validation.nonce | Notice | None | Servers out of sync. Nonce differs. | response.counters = validation.counters and response.modified != validation.modified | Notice | None | Servers out of sync. Modified differs. | response.counters > otp.counters | Warning | OTP marked as invalid |OTP is replayed. Sync response counters higher than OTP counters | response.counter = otp.counters and response.nonce != otp.nonce | Warning | OTP marked as invalid | OTP is replayed. Sync response counters equal to OTP counters and nonce differs. |============= === Sync request logging Both an original sync and a queued sync looks the same so we can not determine if the sync is original or queued. Therefore the logging is the same in both cases. [options="header"] |============== | condition |level |message |note | request.counters < local.counters | Warning | Remote server out of sync. | | request.counters = local.counters and request.modified = local.modifed and request.nonce = local.nonce | Notice | Sync request has been unnecessarily resent. | This could happen frequently whenever a syncentry is queued but the syncprocess terminates before the resonse to the syncentry arrives (since SL level was already achived). | request.counters = local.counters and request.modified != local.modified and request.nonce = local.nonce | Warning | We might have a replay. 2 events at different times have generated the same counters. The time difference is X seconds | | request.counters = local.counters and request.nonce != local.nonce | Warning | Remote server has received a request to validate an already validated OTP | |=================== === Queued sync response logging What do we want to warn for here. Out of sync at time of OTP validation request or out of sync compared to current local counters? [options="header"] |============== | condition |level |message |note | response.counters < validation.counters | Notice | Remote server out of sync compared to counters at validation request time. | | response.counters > validation.counters | Notice | Local server out of sync compared to counters at validation request time. | | response.counters < local.counters | Warning | Remote server out of sync compared to current local counters. | | response.counters > local.counters | Warning | Local server out of sync compared to current local counters. Local server updated. | | response.counters > otp.counters | Error | Remote server has higher counters than OTP. This response would have marked the OTP as invalid. | | response.counter = otp.counters and response.nonce != otp.nonce | Error | Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid. | |=============== yubikey-val-2.38/doc/Troubleshooting.adoc0000644000175000017500000000145712726004025017114 0ustar jeanjean== Troubleshooting First check if the web server is working. Check that PHP is working. Create a foo.php script containing '' to debug PHP configuration. Next make sure you serve the YK-VAL code under the URL you want, and that accesssing the URL reaches the YK-VAL code. PHP error log in the file set by php.ini error_log, by default /var/log/apache2/error.log. Database errors will also be logged into it. The database needs to be started. Make sure you can access it and the tables. If 'ykval-export' crashes, you may be running into a compatibility problem between PHP, curl and libpq. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=411982 for more information. The workaround is simple: [source, sh] user@val:~$ sudo mv /etc/php5/conf.d/curl.ini /etc/php5/conf.d/z_curl.ini yubikey-val-2.38/ykval-munin-queuelength.php0000755000175000017500000000521312726004025017634 0ustar jeanjean#!/usr/bin/php 0) { echo "yes\n"; exit(0); } echo "no (sync pool not configured)\n"; exit(0); } if (($endpoints = endpoints($urls)) === FALSE) { echo "Cannot parse URLs from sync pool list\n"; exit(1); } if ($argc == 2 && strcmp($argv[1], 'config') == 0) { echo "graph_title YK-VAL queue size\n"; echo "graph_vlabel sync requests in queue\n"; echo "graph_category ykval\n"; foreach ($endpoints as $endpoint) { list ($internal, $label, $url) = $endpoint; echo "${internal}_queuelength.label sync ${label}\n"; echo "${internal}_queuelength.draw AREASTACK\n"; echo "${internal}_queuelength.type GAUGE\n"; } exit(0); } $sync = new SyncLib('ykval-synclib:munin'); $queuelength = $sync->getQueueLengthByServer(); foreach ($endpoints as $endpoint) { list ($internal, $label, $url) = $endpoint; $count = 0; if (array_key_exists($url, $queuelength)) $count = $queuelength[$url]; echo "${internal}_queuelength.value $count\n"; } exit(0); yubikey-val-2.38/ykval-export0000755000175000017500000000445212726004025014721 0ustar jeanjean#!/usr/bin/php 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 = $db->fetchArray($result)){ echo (int)$row['active'] . "," . $row['created'] . "," . $row['modified'] . "," . $row['yk_publicname'] . "," . $row['yk_counter'] . "," . $row['yk_use'] . "," . $row['yk_low'] . "," . $row['yk_high'] . "," . $row['nonce'] . "," . $row['notes'] . "\n"; } $db->closeCursor($result); $db->disconnect(); $result=null; $db=null; yubikey-val-2.38/ykval-common.php0000644000175000017500000002371612726004025015457 0ustar jeanjeanlog(LOG_INFO, $str); die($str . "\n"); } function getHttpVal ($key, $default, $a) { if (array_key_exists($key, $a)) { $val = $a[$key]; } else { $val = $default; } $val = trim($val); $val = str_replace('\\', '', $val); return $val; } // Sign a http query string in the array of key-value pairs // return b64 encoded hmac hash function sign($a, $apiKey, $logger) { ksort($a); $qs = http_build_query($a); $qs = urldecode($qs); $qs = utf8_encode($qs); // base64 encoded binary digest $hmac = hash_hmac('sha1', $qs, $apiKey, TRUE); $hmac = base64_encode($hmac); $logger->log(LOG_DEBUG, "SIGN: $qs H=$hmac"); return $hmac; } function curl_settings($logger, $ident, $ch, $url, $timeout, $opts) { $logger->log(LOG_DEBUG, "$ident adding URL : $url"); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_USERAGENT, 'YK-VAL'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_FAILONERROR, TRUE); if (is_array($opts) === FALSE) { $logger->log(LOG_WARN, $ident . 'curl options must be an array'); return; } foreach ($opts as $key => $val) if (curl_setopt($ch, $key, $val) === FALSE) $logger->log(LOG_WARN, "$ident failed to set " . curl_opt_name($key)); } // returns the string name of a curl constant, // or "curl option" if constant not found. // e.g. // curl_opt_name(CURLOPT_URL) returns "CURLOPT_URL" // curl_opt_name(CURLOPT_BLABLA) returns "curl option" function curl_opt_name($opt) { $consts = get_defined_constants(true); $consts = $consts['curl']; $name = array_search($opt, $consts, TRUE); // array_search may return either on failure... if ($name === FALSE || $name === NULL) return 'curl option'; return $name; } // This function takes a list of URLs. It will return the content of // the first successfully retrieved URL, whose content matches ^OK. // 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 // (defaults to ^OK) is returned, or if all URLs failed, false. function retrieveURLasync($ident, $urls, $logger, $ans_req=1, $match="^OK", $returl=False, $timeout=10, $curlopts) { $mh = curl_multi_init(); $ch = array(); foreach ($urls as $url) { $handle = curl_init(); curl_settings($logger, $ident, $handle, $url, $timeout, $curlopts); curl_multi_add_handle($mh, $handle); $ch[(int) $handle] = $handle; } $ans_arr = array(); do { while (curl_multi_exec($mh, $active) == CURLM_CALL_MULTI_PERFORM); while ($info = curl_multi_info_read($mh)) { $logger->log(LOG_DEBUG, "$ident curl multi info : ", $info); if ($info['result'] == CURLE_OK) { $str = curl_multi_getcontent($info['handle']); $logger->log(LOG_DEBUG, "$ident curl multi content : $str"); if (preg_match("/$match/", $str)) { $logger->log(LOG_DEBUG, "$ident response matches $match"); $error = curl_error($info['handle']); $errno = curl_errno($info['handle']); $cinfo = curl_getinfo($info['handle']); $logger->log(LOG_INFO, "$ident errno/error: $errno/$error", $cinfo); if ($returl) $ans_arr[] = "url=" . $cinfo['url'] . "\n" . $str; else $ans_arr[] = $str; } if (count($ans_arr) >= $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[(int) $info['handle']]); } curl_multi_select($mh); } } while($active); foreach ($ch as $h) { curl_multi_remove_handle($mh, $h); curl_close($h); } curl_multi_close($mh); if (count($ans_arr) > 0) return $ans_arr; return false; } function KSMdecryptOTP($urls, $logger, $curlopts) { $response = retrieveURLasync('YK-KSM', $urls, $logger, $ans_req=1, $match='^OK', $returl=False, $timeout=10, $curlopts); if ($response === FALSE) return false; $response = array_shift($response); $logger->log(LOG_DEBUG, "YK-KSM response: $response"); $ret = array(); if (sscanf($response, 'OK counter=%04x low=%04x high=%02x use=%02x', $ret['session_counter'], $ret['low'], $ret['high'], $ret['session_use']) !== 4) { return false; } return $ret; } function sendResp($status, $logger, $apiKey = '', $extra = null) { if ($logger->request !== NULL) $logger->request->set('status', $status); $a['status'] = $status; // 2008-11-21T06:11:55Z0711 $t = substr(microtime(false), 2, 3); $t = gmdate('Y-m-d\TH:i:s\Z0') . $t; $a['t'] = $t; if ($extra) foreach ($extra as $param => $value) $a[$param] = $value; $h = sign($a, $apiKey, $logger); $str = ""; $str .= "h=" . $h . "\r\n"; $str .= "t=" . $a['t'] . "\r\n"; if ($extra) foreach ($extra as $param => $value) $str .= $param . "=" . $value . "\r\n"; $str .= "status=" . $a['status'] . "\r\n"; $str .= "\r\n"; $logger->log(LOG_INFO, "Response: " . $str . " (at " . gmdate("c") . " " . microtime() . ")"); if ($logger->request !== NULL) $logger->request->write(); echo $str; exit; } // backport from PHP 5.6 if (function_exists('hash_equals') === FALSE) { function hash_equals($a, $b) { // hashes are a (known) fixed length, // so this doesn't leak anything. if (strlen($a) != strlen($b)) return false; $result = 0; for ($i = 0; $i < strlen($a); $i++) $result |= ord($a[$i]) ^ ord($b[$i]); return (0 === $result); } } /** * Return the total time taken to receive a response from a URL. * * @argument $url string * @return float|bool seconds or false on failure */ function total_time ($url) { $opts = array( CURLOPT_URL => $url, CURLOPT_TIMEOUT => 3, CURLOPT_FORBID_REUSE => TRUE, CURLOPT_FRESH_CONNECT => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_USERAGENT => 'ykval-munin-vallatency/1.0', ); if (($ch = curl_init()) === FALSE) return false; if (curl_setopt_array($ch, $opts) === FALSE) return false; // we don't care about the actual response if (curl_exec($ch) === FALSE) return false; $total_time = curl_getinfo($ch, CURLINFO_TOTAL_TIME); curl_close($ch); if (is_float($total_time) === FALSE) return false; return $total_time; } /** * Given a list of urls, create internal and label names for munin. * * @argument $urls array * @return array|bool array or false on failure. */ function endpoints ($urls) { $endpoints = array(); foreach ($urls as $url) { // internal munin name must be a-zA-Z0-9_, // so sha1 hex should be fine. // // munin also truncates at some length, // so we just take the first few characters of the hashsum. $internal = substr(sha1($url), 0, 20); // actual label name shown for graph values if (($label = hostport($url)) === FALSE) { return false; } $endpoints[] = array($internal, $label, $url); } // check for truncated sha1 collisions (or actual duplicate URLs!) $internal = array(); foreach($endpoints as $endpoint) { $internal[] = $endpoint[0]; } if (count(array_unique($internal)) !== count($endpoints)) return false; return $endpoints; } /** * Given a URL, if the port is defined or can be determined from the scheme, * return the hostname and port. * Otherwise just return the hostname. * * @argument $url string * @return string|bool string or false on failure */ function hostport ($url) { if (($url = parse_url($url)) === FALSE) return false; if (array_key_exists('host', $url) === FALSE || $url['host'] === NULL) return false; if (array_key_exists('port', $url) === TRUE && $url['port'] !== NULL) return $url['host'].':'.$url['port']; if (array_key_exists('scheme', $url) === TRUE && strtolower($url['scheme']) === 'http') return $url['host'].':80'; if (array_key_exists('scheme', $url) === TRUE && strtolower($url['scheme']) === 'https') return $url['host'].':443'; return $url['host']; } yubikey-val-2.38/ykval-gen-clients.10000644000175000017500000000475712726004025015754 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-gen-clients "1" "January 2013" "yubico-val" .SH NAME ykval-gen-clients - Generate Yubikey API clients. .SH SYNOPSIS .B ykval-gen-clients [ OPTIONS ] [ num_clients ] .SH DESCRIPTION Generates clients and client secrets, and inserts them into the yubikey-val database. They are also printed to stdout as comma separated lines containing client_id, secret. .PP Database configuration is read from /etc/yubico/val/ykval-config.php .PP \fB\-\-urandom\fR Use /dev/urandom instead of /dev/random as entropy source. .PP \fB\-\-email\fR=EMAIL Sets the e-mail field of the created clients .PP \fB\-\-notes\fR=NOTES Sets the notes field of the created clients .PP \fB\-\-otp\fR=OTP Sets the otp field of the created clients .SH BUGS Report ykval-gen-clients bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-import-clients (1) .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-log-verify.php0000644000175000017500000001070212726004025016241 0ustar jeanjean NULL, 'time_end' => NULL, 'time_taken' => NULL, 'ip' => NULL, 'client' => NULL, 'public_id' => NULL, 'otp' => NULL, 'status' => NULL, 'nonce' => NULL, 'signed' => NULL, 'counter' => NULL, 'low' => NULL, 'high' => NULL, 'use' => NULL, 'tls' => NULL, 'protocol' => NULL, 'sl' => NULL, 'timeout' => NULL, ); /** * Set field value. * * @param $name string * @param $value mixed * @return bool */ public function set($name, $value) { // not settable from outside if ($name === 'time_end' || $name === 'time_taken') return false; if (array_key_exists($name, $this->fields) === FALSE) return false; $this->fields[$name] = $value; return true; } /** * Write verify request log line to syslog. * * @return bool */ public function write() { if ($this->format === NULL) return false; $values = array(); foreach ($this->sanitized() as $key => $val) { $values['%'.$key.'%'] = $val; } $message = strtr($this->format, $values); if (!is_string($message)) return false; return syslog(LOG_INFO, $message); } /** * Sanitize untrusted values from clients before writing them to syslog. * * P.S. signed, status, time_start, tls are assumed safe, * since they are set internally. * * @return array sanitized $this->fields */ private function sanitized() { $a = $this->fields; if (preg_match('/^[cbdefghijklnrtuv]+$/', $a['public_id']) !== 1 || strlen($a['public_id']) < 1 || strlen($a['public_id']) > (OTP_MAX_LEN - TOKEN_LEN)) { $a['public_id'] = '-'; } if (preg_match('/^[cbdefghijklnrtuv]+$/', $a['otp']) !== 1 || strlen($a['otp']) < TOKEN_LEN || strlen($a['otp']) > OTP_MAX_LEN) { $a['otp'] = '-'; } if (preg_match('/^[0-9]+$/', $a['client']) !== 1) $a['client'] = '-'; if (filter_var($a['ip'], FILTER_VALIDATE_IP) === FALSE) $a['ip'] = '-'; if (is_int($a['counter']) === FALSE) $a['counter'] = '-'; if (is_int($a['low']) === FALSE) $a['low'] = '-'; if (is_int($a['high']) === FALSE) $a['high'] = '-'; if (is_int($a['use']) === FALSE) $a['use'] = '-'; if (preg_match('/^[a-zA-Z0-9]{16,40}$/', $a['nonce']) !== 1) $a['nonce'] = '-'; if (is_float($a['protocol']) === TRUE) $a['protocol'] = sprintf('%.1f', $a['protocol']); else $a['protocol'] = '-'; if ( $a['sl'] !== 'fast' && $a['sl'] !== 'secure' && (preg_match('/^[0-9]{1,3}$/', $a['sl']) !== 1 || (((int) $a['sl']) > 100))) { $a['sl'] = '-'; } if (preg_match('/^[0-9]+$/', $a['timeout']) !== 1) $a['timeout'] = '-'; $start = explode(' ', $a['time_start']); $start_msec = $start[0]; $start_sec = $start[1]; $start = bcadd($start_sec, $start_msec, 8); unset($start_sec, $start_msec); $end = explode(' ', microtime()); $end_msec = $end[0]; $end_sec = $end[1]; $end = bcadd($end_sec, $end_msec, 8); unset($end_sec, $end_msec); $taken = bcsub($end, $start, 8); $a['time_start'] = $start; $a['time_end'] = $end; $a['time_taken'] = $taken; return $a; } } yubikey-val-2.38/ykval-db-pdo.php0000644000175000017500000001537712726004025015340 0ustar jeanjeandb_dsn=$db_dsn; $this->db_username=$db_username; $this->db_password=$db_password; $this->db_options=$db_options; $this->result = null; $this->myLog=new Log($name); } /** * function to connect to database defined in config.php * * @return boolean True on success, otherwise false. * */ public function connect(){ try { $this->dbh = new PDO($this->db_dsn, $this->db_username, $this->db_password, $this->db_options); } catch (PDOException $e) { $this->myLog->log(LOG_CRIT, "Database connection error: " . $e->getMessage()); $this->dbh=Null; return false; } return true; } protected function query($query, $returnresult=false) { if(!$this->isConnected()) { $this->connect(); } if($this->isConnected()) { $this->myLog->log(LOG_DEBUG, 'DB query is: ' . $query); try { $this->result = $this->dbh->query($query); } catch (PDOException $e) { $this->myLog->log(LOG_INFO, 'Database query error: ' . preg_replace('/\n/',' ',print_r($this->dbh->errorInfo(), true))); $this->dbh = Null; return false; } if ($returnresult) return $this->result; else return true; } else { $this->myLog->log(LOG_CRIT, 'No database connection'); return false; } } /** * function to get a row from the query result * Once all rows have been fetch, function closeCursor needs to be called * * @param object $result Query result object or null to use the current one * @return array a query row * */ public function fetchArray($result=null){ if(!$result) $result = $this->result; if(!$result) return null; return $result->fetch(PDO::FETCH_ASSOC); } /** * function to close the cursor after having fetched rows * * @param object $result Query result object or null to use the current one * */ public function closeCursor($result=null){ if(!$result) $result = $this->result; if($result) $result->closeCursor(); } /** * 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 * @param int $nr Number of rows to collect. NULL=>inifinity. Default=NULL. * @param int $rev rev=1 indicates order should be reversed. Default=NULL. * @param string distinct Select rows with distinct columns, Default=NULL * * @return mixed Array with values from Db row or 2d-array with multiple rows */ public function findByMultiple($table, $where, $nr=NULL, $rev=NULL, $distinct=NULL) { $value = ''; $match = NULL; $query = 'SELECT'; if ($distinct != NULL) $query.= " DISTINCT " . $distinct; else $query.= " *"; $query.= " FROM " . $table; if ($where != NULL) { foreach ($where as $key => $value) { if ($key != NULL) { if ($value != NULL) $match .= " ". $key . " = '" . $value . "' and"; else $match .= " ". $key . " is NULL and"; } } if ($match != NULL) $query .= " WHERE" . $match; $query = rtrim($query, "and"); $query = rtrim($query); } if ($rev == 1) $query.= " ORDER BY id DESC"; if ($nr != NULL) $query.= " LIMIT " . $nr; $result = $this->query($query, true); if (!$result) return false; if ($nr == 1) { $row = $this->fetchArray($result); $this->closeCursor($result); return $row; } $collection = array(); while($row = $this->fetchArray($result)) $collection[] = $row; $this->closeCursor($result); return $collection; } /** * 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 * @param int $nr Number of rows to collect. NULL=>inifinity. Default=NULL. * @param int $rev rev=1 indicates order should be reversed. Default=NULL. * @param string distinct Select rows with distinct columns, Default=NULL * @return boolean True on success, otherwise false. * */ public function deleteByMultiple($table, $where, $nr=null, $rev=null) { $query="DELETE"; $query.= " FROM " . $table; if ($where!=null){ $query.= " WHERE"; foreach ($where as $key=>$value) { $query.= " ". $key . " = '" . $value . "' and"; } $query=rtrim($query, "and"); $query=rtrim($query); } if ($rev==1) $query.= " ORDER BY id DESC"; if ($nr!=null) $query.= " LIMIT " . $nr; return $this->query($query, false); } /** * Function to get the number of rows * * @param object $result Query result object or null to use the current one * @return int number of rows affected by last statement or 0 if database connection is not functional. * */ public function rowCount($result=null) { if(!$result) $result = $this->result; if($result) { $count=$result->rowCount(); $result->closeCursor(); return $count; } else { return 0; } } } yubikey-val-2.38/ykval-db-oci.php0000644000175000017500000001641612726004025015323 0ustar jeanjeandb_dsn=$db_dsn; $this->db_username=$db_username; $this->db_password=$db_password; $this->db_options=$db_options; if(substr($db_dsn, 0, 4) == 'oci:') { # "oci:" prefix needs to be removed before passing db_dsn to OCI $this->db_dsn = substr($this->db_dsn, 4); } $this->myLog=new Log($name); } /** * function to connect to database defined in config.php * * @return boolean True on success, otherwise false. * */ public function connect(){ $this->dbh = oci_connect($this->db_username, $this->db_password, $this->db_dsn); if (!$this->dbh) { $error = oci_error(); $this->myLog->log(LOG_CRIT, "Database connection error: " . $error["message"]); $this->dbh=Null; return false; } return true; } protected function query($query, $returnresult=false) { if(!$this->isConnected()) { $this->connect(); } if($this->isConnected()) { $this->myLog->log(LOG_DEBUG, 'DB query is: ' . $query); # OCI mode $result = oci_parse($this->dbh, $query); if(!oci_execute($result)) { $this->myLog->log(LOG_INFO, 'Database query error: ' . preg_replace('/\n/',' ',print_r(oci_error($result), true))); $this->dbh = Null; return false; } $this->result = $result; if ($returnresult) return $this->result; else return true; } else { $this->myLog->log(LOG_CRIT, 'No database connection'); return false; } } /** * function to get a row from the query result * Once all rows have been fetch, function closeCursor needs to be called * * @param object $result Query result object or null to use the current one * @return array a query row * */ public function fetchArray($result=null){ if(!$result) $result = $this->result; if(!$result) return null; $res = oci_fetch_array($result, OCI_ASSOC); return array_change_key_case($res, CASE_LOWER); } /** * function to close the cursor after having fetched rows * * @param object $result Query result object or null to use the current one * */ public function closeCursor($result=null){ } /** * 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 * @param int $nr Number of rows to collect. NULL=>inifinity. Default=NULL. * @param int $rev rev=1 indicates order should be reversed. Default=NULL. * @param string distinct Select rows with distinct columns, Default=NULL * @return mixed Array with values from Db row or 2d-array with multiple rows * */ public function findByMultiple($table, $where, $nr=null, $rev=null, $distinct=null) { $value=""; /* quiet the PHP Notice */ $match=null; /* quiet the PHP Notice */ $query="SELECT"; if($nr!=null){ # LIMIT doesn't exist in Oracle, so we encapsulate the query to be # able to filter a given number of rows afterwars (after ordering) $query.= " * FROM (SELECT"; } if ($distinct!=null) { $query.= " DISTINCT " . $distinct; } else { $query.= " *"; } $query.= " FROM " . $table; if ($where!=null){ foreach ($where as $key=>$value) { if ($key!=null) { if ($value!=null) $match.= " ". $key . " = '" . $value . "' and"; else $match.= " ". $key . " is NULL and"; } } if ($match!=null) $query .= " WHERE" . $match; $query=rtrim($query, "and"); $query=rtrim($query); } if ($rev==1) $query.= " ORDER BY id DESC"; if ($nr!=null) { $query .= ") WHERE rownum < " . ($nr+1); } $result = $this->query($query, true); if (!$result) return false; if ($nr==1) { $row = $this->fetchArray($result); $this->closeCursor($result); return $row; } else { $collection=array(); while($row = $this->fetchArray($result)){ $collection[]=$row; } $this->closeCursor($result); return $collection; } } /** * 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 * @param int $nr Number of rows to collect. NULL=>inifinity. Default=NULL. * @param int $rev rev=1 indicates order should be reversed. Default=NULL. * @param string distinct Select rows with distinct columns, Default=NULL * @return boolean True on success, otherwise false. * */ public function deleteByMultiple($table, $where, $nr=null, $rev=null) { $query="DELETE"; $query.= " FROM " . $table; $query .= " WHERE id IN (SELECT id FROM " . $table; if ($where!=null){ $query.= " WHERE"; foreach ($where as $key=>$value) { $query.= " ". $key . " = '" . $value . "' and"; } $query=rtrim($query, "and"); $query=rtrim($query); } if ($rev==1) $query.= " ORDER BY id DESC"; $query .= ")"; if ($nr!=null) $query.= " and rownum < " . ($nr+1); return $this->query($query, false); } /** * Function to get the number of rows * * @param object $result Query result object or null to use the current one * @return int number of rows affected by last statement or 0 if database connection is not functional. * */ public function rowCount($result=null) { if(!$result) $result = $this->result; if($result) { return oci_num_rows($result); } else { return 0; } } } yubikey-val-2.38/ykval-ping.php0000644000175000017500000000261712726004025015121 0ustar jeanjeangetQueueLength (); $message = "Queue length is $len"; if($len > $critical) { print("CRITICAL: $message\n"); exit (2); } elseif($len > $warning) { print("WARNING: $message\n"); exit (1); } else { print("OK: $message\n"); exit (0); } yubikey-val-2.38/ykval-checksum-deactivated.10000644000175000017500000000451212726004025017606 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-checksum-deactivated "1" "January 2013" "yubico-val" .SH NAME ykval-checksum-deactivated - Calculate a checksum of deactivated YubiKeys .SH SYNOPSIS .B ykval-checksum-deactivated .SH DESCRIPTION Calculates a checksum of the state of all deactivated YubiKey Info data in the yubikey-val server database. This checksum can be used to easily compare the state of disabled YubiKeys in two yubikey-val servers in the same sync pool. Database configuration is read from /etc/yubico/val/ykval-config.php .SH BUGS Report ykval-checksum-deactivated bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" .BR ykval-checksum-clients (1) The .URL "https://github.com/Yubico/yubikey-val" "yubikey-val home page" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/NEWS0000644000175000017500000002402312726004025013021 0ustar jeanjean* Version 2.38 (released 2016-06-08) * Silence PHP notice when using curl handles as array keys. * Version 2.37 (released 2016-05-17) * Avoid PHP notices/warnings when receiving empty verify requests. * Version 2.36 (released 2016-05-16) * Commit to either $_GET or $_POST early in request handling. * Use CURLINFO_EFFECTIVE_URL instead of CURLINFO_PRIVATE in synclib. * Run tests for PHP 7.0. * Version 2.35 (released 2016-04-19) * Fixed install target in Makefile to include ykval-log-verify.php * Version 2.34 (released 2016-04-18) * Added __YKVAL_VERIFY_LOGFORMAT__ to optionally provide a single line to log verify requests. * ykval-synclib does parallel sync with peers. i.e. instead of totally draining a peer queue before moving to the next peer, we drain a bit of each peer on each run. * Documentation fixes. * Version 2.33 (released 2015-10-05) * Modified a LOG_INFO message, multiple key=val are separated by two spaces instead of one. * Added http://127.0.0.1:80 to default ksm service. * Refactoring and internal improvements. * Version 2.32 (released 2015-09-14) * Fixed erroneous log messages and whitespace output. * Refactoring and internal improvements. * Version 2.31 (released 2015-09-10) * Fix issues introduced in 2.30. * PHP Fatal error when receiving an empty sync request, due to not initialising the logging boiler plate early enough. * PHP Notice when writing a LOG_INFO message, due to an incorrect sprintf argument passing. * Version 2.30 (released 2015-09-09) * Refactoring and internal improvements. * Better robustness and minor performance improvements. * Bug fixes in logging framework and message output. * Preference towards TLS by default. * ykval-queue exits automatically on single node configurations. * Rewrote ksmlatency, vallatency & queuelength munin plugins. * Munin plugins use libcurl rather than curl system binaries. * Version 2.29 (released 2015-05-27) * Allow curl options to be set from config file. * Version 2.28 (released 2015-02-11) * Refactor munin quelenegth plugin to show what is queued. * Add ykval-nagios-queuelength. * Use constant time string comparisson for validating HMAC signature. * Version 2.27 (released 2014-09-25) * Further logging updates. * ykval-munin-responses: Make log file configurable. * ykval-munin-ksmresponses: New munin probe. * Version 2.26 (released 2014-09-24) * Logging updates. * Optimization fix in the checksum scripts. * Documentation fixes. * Version 2.25 (released 2014-08-18) * Now works with 'allow_url_fopen' == false. * Always verifies SSL peer when syncing between servers via HTTPS. * Version 2.24 (released 2013-09-18) * Removed space after comma in the output of ykval-gen-clients. * Include README in tarball. * Version 2.23 (released 2013-04-17) * Removed initial empty line from output for all commands. * Use LF as EOL consistently. * Updated release procedure. * Version 2.22 (released 2013-03-12) * Added the ability to send yk=all to ykval-resync.php to queue sync of all known active YubiKeys. * Added ykval-synchronize to easily call ykval-resync.php on a remote server. * Added ykval-gen-clients to generate API clients. * Log query for POST requests too. * Version 2.21 (released 2013-02-05) * Fixed a problem that caused ykval-queue to terminate if the database was not available initially. * Version 2.20 (released 2013-01-31) * Add ChangeLog generation using git2cl. * Changed location of files to /usr/share/yubikey-val, etc. * Changed location of configuration files to /etc/yubico/val/. * Made import/export scripts use comma separation, instead of tabs. * Added a working ykval-config.php that looks for a ksm on localhost. * Removed System_Daemon dependency and made ykval-queue a simple backgroundable process that can be daemonized using for instance and init.d script. * Added man pages for executables. * Version 2.19 (released 2012-07-05) * Refactor database code, allowing for other underlying implementations than PDO. Add a PDO and an Oracle (through php_oci) implementation. Based on patch from Remi Mollon * Fix for ykval-export running on postgres. * Add resync.php to request new sync of public id. * Add munin plugin for statistics. * Version 2.18 (released 2012-06-15) * Logging misstakes that broke 2.17 fixed. * Version 2.17 (released 2012-06-15) * Logging improvements. use ykval-verify/ykval-sync correctly for whole flow clarify/degrade various logging messages * Fix mysql error introduced in 2.14, also logs database updated/not updated correctly. * Accept sync for disabled keys, but still answer BAD_OTP. * Remove from sync queue on BAD_OTP answer. * Add munin plugin for response types. * Version 2.16 (released 2012-06-13) * Improved logging. * Improved performance of large sync queues. * Version 2.15 (released 2012-05-24) * Add export/import scripts for clients table. * Insert default values in $sl and $timeout if they are empty. And they will be empty if the client didn't request them. * Version 2.14 (released 2012-05-22) * Add support for reconnecting to database after errors. * Fixes for PHP warnings. * Detect timeouts and errors in munin checks. * Version 2.13 (released 2012-05-16) * Fix signature checking broken in 2.12 and for dvorak OTPs. * Fixes for ykval-checksum-clients.php * Version 2.12 (released 2012-05-09) * Fix using 'fast' or 'secure' as sync level. * Fix database setup script to make nonce max 40 characters. * Version 2.11 (released 2011-11-16) * Silence PHP warnings. Patch from Hiroki Nose. * Include munin scripts in tarball. From Fredrik Thulin. * Support for DESTDIR in 'make install'. From Fredrik Thulin. * Reorder include's to allow for dbi-settings through ykval-config.php. From Fredrik Thulin. * Install non-bin PHP files with --mode 644 to avoid executable bit. From Fredrik Thulin. * Fix two remaining non-portable uses of rowCount. * Version 2.10 (released 2011-08-18) * Don't echo (unsanitized) OTP/NONCE values back to client when sending error codes. Reported by Paul van Empelen. Resolving this problem protects (arguably buggy) clients against an attack. Prior versions of the Yubico C and PHP clients do not appear to exhibit this bug. We provide an analysis of the issue below so that you can review client implementations for the problem. Note that you do not have to fix clients if you are using this server version (or later), although we recommend it anyway. If the client sends a OTP value that ends with '%0astatus=OK' the server output will contain a line 'status=ok' before the real status code status=MISSING_PARAMETER. Note lower-casing of the injected status code, so that it doesn't match a correct 'status=OK' response. Note also that the OTP value would fail normal input validation checks in the client. If the client sends a NONCE value that ends with '%0astatus=OK' the output will contain a line consisting of 'status=OK' before the correct status=MISSING_PARAMETER. However, the NONCE value is generated by client code internally and does not come from any untrusted source, thus the impact here is limited -- if an attacker is able to trick a client into sending a crafted NONCE value the attacker is normally able to modify the client code somehow, and can thus trick the client in other ways as well. Similar issues apply to the ID field, which is normally also under control of the trusted client code and not something an attacker could influence. Thus, this server-side fix solve a client-side issue that we believe would only occur when both of these conditions are true: 1) the client does not do proper input validation of the OTP, and 2) the client incorrectly parses 'status=ok' as 'status=OK'. or when the following condition is true A) the client can be tricked into sending a crafted NONCE or ID value. * Version 2.9 (released 2011-05-09) * Support multiple IP authorizations in ykval-revoke.php. * Version 2.8 (released 2011-01-06) * Support YubiKey OTPs filtered through a US Dvorak keyboard layout. * Added ykval_-vallatency Munin probe to measure latency to other validation instances, for both IPv4 and IPv6. * Version 2.7 (released 2010-09-12) * Sanity check input OTP variable to avoid any chance of SQL injections. Reported by Ricky Zhou. * Timestamp request and response because syslog doesn't record year nor sub-second resolution. * Log whether HTTPS is used or not. * Version 2.6 (released 2010-08-02) * Don't use rowCount in ykval-revoke, there seems to be some problem with the rowCount function. * Add Munin plugin to measure KSM latency and queue length. * Version 2.5 (released 2010-05-17) * Fix undefined warnings, issue #8. * Don't use PDO rowCount function to get number of rows returned because that isn't portable. Patch from arte42.ripe in issue #7 (yubikey-val-2.1-php-rowcount.patch). * When number of sync servers equals zero, set sync result to success. Patch from arte42.ripe in issue #7 (yubikey-val-2.1-syncres.patch). * When there is only one KSM, use more portable code without async. Patch from arte42.ripe in issue #7 (yubikey-val-2.1-php-curl.patch). * Add files COPYING and AUTHORS. * Version 2.4 (released 2010-03-16) * Fix bug in ykval-checksum-clients.php when used with PostgreSQL. * Version 2.3 (released 2010-03-12) * Add ykval-checksum-clients.php, see doc/SyncMonitor.wiki. * Version 2.2 (released 2010-02-22) * Minor cleanups and fixes. * Add ykval-revoke.php service, see doc/RevocationService.wiki. * Version 2.1 (released 2010-01-29) * Minor cleanups and fixes. * Version 2.0 (released 2010-01-18) * Major re-design to support a new architecture with replicated servers. * Version 1.1 (released 2009-11-19) * Stable release of non-replicated server. yubikey-val-2.38/ykval-synchronize.10000644000175000017500000000545712726004025016115 0ustar jeanjean.\" Copyright (c) 2011-2015 Yubico AB .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" * Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" * Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" The following commands are required for all man pages. .de URL \\$2 \(laURL: \\$1 \(ra\\$3 .. .if \n[.g] .mso www.tmac .TH ykval-synchronize "1" "January 2013" "yubico-val" .SH NAME ykval-synchronize - Request synchronization from servers in a yubikey-val sync pool. .SH SYNOPSIS .B ykval-synchronize .SH DESCRIPTION Sends a request to a remote server in the sync pool to synchronize YubiKey counters with the sender. Can be used to synchronize a specific key, or all keys. The remote server must be configured to allow resync requests from the machine the command is run from, and the machine running the command must be configured to accept sync requests from the remote server. The synchronization is queued remotely and handled by the ykval-queue daemon. .SH EXAMPLES Request sync for a specific YubiKey: $ ykval-synchronize http://1.2.3.4/wsapi/2.0/resync ccccccdndndn If the URL follows the default format (as in the example above) you can skip the protocol and just give the hostname directly, or as an IP address. Request sync for all (active) YubiKeys from server using the default path: $ ykval-synchronize example.com all .SH BUGS Report ykval-synchronize bugs in .URL "https://github.com/Yubico/yubikey-val/issues" "the issue tracker" .SH "SEE ALSO" The .URL "https://github.com/Yubico/yubikey-val" "yubikey-val home page" .PP YubiKeys can be obtained from .URL "https://www.yubico.com/" "Yubico" "." yubikey-val-2.38/ykval-munin-yubikeystats.php0000755000175000017500000000620012726004025020043 0ustar jeanjean#!/usr/bin/php connect()) logdie($myLog, 'ERROR Database connect error (1)'); function get_count($db, $table, $conditions) { $res = $db->customQuery("SELECT count(1) as count FROM $table WHERE $conditions"); if ($res) { $r = $res->fetch(PDO::FETCH_ASSOC); return $r['count']; } return Null; } if ($count = get_count($db, 'yubikeys', 'active=true')) echo "yubikeys_enabled.value $count\n"; if ($count = get_count($db, 'yubikeys', 'active=false')) echo "yubikeys_disabled.value $count\n"; if ($count = get_count($db, 'yubikeys', 'modified >= ' . (time() - (31 * 86400)))) echo "yubikeys_1month.value $count\n"; if ($count = get_count($db, 'clients', 'active=true')) echo "clients_enabled.value $count\n"; if ($count = get_count($db, 'clients', 'active=false')) echo "clients_disabled.value $count\n";