yubikey-val-2.24/0000755000175000017500000000000012216341221012010 5ustar jasjasyubikey-val-2.24/ykval-gen-clients.10000644000175000017500000000475612216341221015442 0ustar jasjas.\" Copyright (c) 2011-2013 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 "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/NEWS0000644000175000017500000001654612216341221012523 0ustar jasjas* 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.24/ykval-munin-responses.pl0000755000175000017500000000476512216341221016655 0ustar jasjas#!/usr/bin/perl #%# family=auto #%# capabilities=autoconf # Copyright (c) 2012-2013 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; 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 = "/var/log/syslog"; 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 (LOGFILE, "grep 'ykval-verify.*Response' $logfile |"); while() { next unless /$reg/; $statuses{$1}++; } close LOGFILE; print "multigraph ykval_responses\n"; foreach my $type (@types) { print "${type}.value ${statuses{$type}}\n"; } exit 0 yubikey-val-2.24/COPYING0000644000175000017500000000245112216341221013045 0ustar jasjasCopyright (c) 2006-2013 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.24/ykval-log.php0000644000175000017500000000437412216341221014436 0ustar jasjasname=$name; $this->fields=array(); $this->LOG_LEVELS = array(LOG_EMERG=>'LOG_EMERG', LOG_ALERT=>'LOG_ALERT', LOG_CRIT=>'LOG_CRIT', LOG_ERR=>'LOG_ERR', LOG_WARNING=>'LOG_WARNING', LOG_NOTICE=>'LOG_NOTICE', LOG_INFO=>'LOG_INFO', LOG_DEBUG=>'LOG_DEBUG'); openlog("ykval", LOG_PID, LOG_LOCAL0); } function addField($name, $value) { $this->fields[$name]=$value; } function log($priority, $message, $arr=null){ if (is_array($arr)) { foreach($arr as $key=>$value){ $message.=" $key=$value "; } } # Add fields $msg_fields = ""; foreach ($this->fields as $field=>$value) { $msg_fields .= "[" . $value . "] "; } syslog($priority, $this->LOG_LEVELS[$priority] . ':' . $this->name . ':' . $msg_fields . $message); } } ?> yubikey-val-2.24/doc/0000755000175000017500000000000012216341221012555 5ustar jasjasyubikey-val-2.24/doc/ClientInfoFormat.wiki0000644000175000017500000000170112216341221016644 0ustar jasjas=Format of Client Info Data= This file holds data used in the YubiKey OTP validation phase. Each of the lines in the file follows the following format: ``` id,active,created,secret,email,notes,otp ``` Any empty line, or a line beginning with a # is ignored. The meaning are as follows: ;id: : the client identity, decimal integer ;active : the client state, 1 if active, 0 if not ;created : unix timestamp of when the client was created, decimal integer ;secret : printable ascii string with shared HMAC secret for client id ;email : the email address used by the client, printable ascii string ;notes : not used, printable ascii string ;otp : the YubiKey OTP used to create the client, modhex string An examples of a valid data line: ``` 1,1,1359550387,foobar,user@example.com,,cccccccccccbubfncnklbknnkrfvfkbubftlfliikdrt ``` For an example of importing and exporting Client Info data, please see [[ImportExportData|Importing and Exporting Data]]. yubikey-val-2.24/doc/ServerReplicationProtocol.wiki0000644000175000017500000000506012216341221020625 0ustar jasjas= 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 {| ! 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 ```sh 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: {| ! 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.24/doc/Installation.wiki0000644000175000017500000004310112216341221016102 0ustar jasjas== 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 Python-PyHSM: [https://github.com/Yubico/python-pyhsm] Otherwise we recommend the "soft" YK-KSM: [https://github.com/Yubico/yubikey-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 == This following steps applies 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 12.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: ```sh user@val:~$ sudo apt-get install git make ... user@val:~$ git clone git://github.com/Yubico/yubikey-val.git ... user@val:~$ cd yubikey-val user@val:~/yubikey-val$ sudo make install ``` 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. ```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: ```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: ```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: ```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': ```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(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: ```sh user@val:~$ sudo apt-get install postgresql php5-pgsql ... user@val:~$ ``` The database needs to be initialized as follows: ```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': ```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 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 ```sh postgres@val:~$ exit user@val:~$ ``` During installation and debugging it may be useful to watch the database log entries: ```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: ```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: ```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: ```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. ```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: ```php $baseParams['__YKVAL_DB_DSN__'] = "mysql:dbname=ykval;host=127.0.0.1"; ``` An example DSN for a PostgreSQL setup: ```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: ```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: ```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: ``` user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval' 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: ```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: ``` user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl' 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. ```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. ``` user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl' 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. ```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: ```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: ```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): ``` *.=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: ``` *.=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: ```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: ```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: ```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: ```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://github.com/Yubico/yubikey-ksm/wiki/ServerHardening] on how to improve security of your system. yubikey-val-2.24/doc/RevocationService.wiki0000644000175000017500000000263612216341221017103 0ustar jasjas= 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 = ```sh user@val:~/yubikey-val$ sudo make revoke user@val:~/yubikey-val$ ``` = Configuration = Add the following to your /etc/yubico/val/ykval-config.php: ```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: ``` 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: ``` postgres@val:~$ psql ykval -q ykval=# GRANT UPDATE ON yubikeys TO ykval_verifier; ykval=# \q postgres@val:~$ ``` = Testing = Test the installation like this: ```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.24/doc/SyncMonitor.wiki0000644000175000017500000000234212216341221015727 0ustar jasjas= 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. ```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.24/doc/Troubleshooting.wiki0000644000175000017500000000145512216341221016636 0ustar jasjas= 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: ``` user@val:~$ sudo mv /etc/php5/conf.d/curl.ini /etc/php5/conf.d/z_curl.ini ``` yubikey-val-2.24/ykval-export.10000644000175000017500000000433412216341221014543 0ustar jasjas.\" Copyright (c) 2011-2013 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://github.com/Yubico/yubikey-val/wiki/YubiKeyInfoFormat" "YubiKey Info data format" .PP YubiKeys can be obtained from .URL "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-revoke.php0000644000175000017500000000514412216341221015144 0ustar jasjasaddField('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.24/ykval-db.sql0000644000175000017500000000144712216341221014250 0ustar jasjasCREATE TABLE clients ( id INT NOT NULL UNIQUE, active BOOLEAN DEFAULT TRUE, created INT NOT NULL, secret VARCHAR(60) NOT NULL DEFAULT '', email VARCHAR(255), notes VARCHAR(100) DEFAULT '', otp VARCHAR(100) DEFAULT '', PRIMARY KEY (id) ); CREATE TABLE yubikeys ( active BOOLEAN DEFAULT TRUE, created INT NOT NULL, modified INT NOT NULL, yk_publicname VARCHAR(16) UNIQUE 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.24/ykval-config.php0000644000175000017500000001031112216341221015106 0ustar jasjas PDO::ERRMODE_EXCEPTION); # For the validation server sync $baseParams['__YKVAL_SYNC_POOL__'] = array(/*"http://api2.example.com/wsapi/2.0/sync",*/ /*"http://api3.example.com/wsapi/2.0/sync",*/ /* "http://api4.example.com/wsapi/2.0/sync"*/); # An array of IP addresses allowed to issue sync requests # NOTE: You must use IP addresses here. $baseParams['__YKVAL_ALLOWED_SYNC_POOL__'] = array(/*"1.2.3.4",*/ /*"2.3.4.5",*/ /*"3.4.5.6"*/); # 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; // otp2ksmurls: Return array of YK-KSM URLs for decrypting OTP for // CLIENT. The URLs must be fully qualified, i.e., contain the OTP // itself. function otp2ksmurls ($otp, $client) { //if ($client == 42) { // return array("http://another-ykkms.example.com/wsapi/decrypt?otp=$otp"); //} //if (preg_match ("/^dteffujehknh/", $otp)) { // return array("http://different-ykkms.example.com/wsapi/decrypt?otp=$otp"); //} return array( //"http://ykkms1.example.com/wsapi/decrypt?otp=$otp", //"http://ykkms2.example.com/wsapi/decrypt?otp=$otp", "http://127.0.0.1/wsapi/decrypt?otp=$otp" ); } ?> yubikey-val-2.24/ykval-gen-clients0000755000175000017500000001007712216341221015277 0ustar jasjas#!/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.24/ykval-verify.php0000644000175000017500000003060012216341221015150 0ustar jasjasaddField('ip', $_SERVER['REMOTE_ADDR']); $query_string = ''; if ($_POST) { $kv = array(); foreach ($_POST as $key => $value) { $kv[] = "$key=$value"; } $query_string = "POST: " . join("&", $kv); } else { $query_string = "Request: " . $_SERVER['QUERY_STRING']; } $myLog->log(LOG_INFO, $query_string . " (at " . date("c") . " " . microtime() . ") " . (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on" ? "HTTPS" : "HTTP")); /* 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->log(LOG_DEBUG, "found protocol version " . $protocol_version); /* Extract values from HTTP request */ $h = getHttpVal('h', ''); $client = getHttpVal('id', 0); $otp = getHttpVal('otp', ''); $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; } $timestamp = getHttpVal('timestamp', 0); /* 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', ''); $timeout = getHttpVal('timeout', ''); $nonce = getHttpVal('nonce', ''); /* Add nonce to response parameters */ $extra['nonce']= $nonce; /* Nonce is required from protocol 2.0 */ if(!$nonce) { $myLog->log(LOG_NOTICE, 'Nonce is missing and protocol version >= 2.0'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } } /* 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 (!isset($timeout) || $timeout == '') { $timeout=$baseParams['__YKVAL_SYNC_DEFAULT_TIMEOUT__']; } if ($otp == '') { $myLog->log(LOG_NOTICE, 'OTP is missing'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } if (strlen($otp) < TOKEN_LEN || strlen ($otp) > OTP_MAX_LEN) { $myLog->log(LOG_NOTICE, 'Incorrect OTP length: ' . $otp); sendResp(S_BAD_OTP, $myLog); exit; } if (preg_match("/^[cbdefghijklnrtuv]+$/", $otp)==0) { $myLog->log(LOG_NOTICE, 'Invalid OTP: ' . $otp); sendResp(S_BAD_OTP, $myLog); exit; } if (preg_match("/^[0-9]+$/", $client)==0){ $myLog->log(LOG_NOTICE, 'id provided in request must be an integer'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } if ($timeout && preg_match("/^[0-9]+$/", $timeout)==0) { $myLog->log(LOG_NOTICE, 'timeout is provided but not correct'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } 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); exit; } if (isset($nonce) && (strlen($nonce) < 16 || strlen($nonce) > 40)) { $myLog->log(LOG_NOTICE, 'Nonce too short or too long'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) { $myLog->log(LOG_NOTICE, 'SL is provided but not correct'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } // NOTE: Timestamp parameter is not checked since current protocol says that 1 means request timestamp // and anything else is discarded. //// Get Client info from DB // if ($client <= 0) { $myLog->log(LOG_NOTICE, 'Client ID is missing'); sendResp(S_MISSING_PARAMETER, $myLog); exit; } /* 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', $_SERVER['REMOTE_ADDR']); $sync->addField('otp', $otp); if (! $sync->isConnected()) { sendResp(S_BACKEND_ERROR, $myLog); exit; } $cd=$sync->getClientData($client); if(!$cd) { $myLog->log(LOG_NOTICE, 'Invalid client id ' . $client); sendResp(S_NO_SUCH_CLIENT, $myLog); exit; } $myLog->log(LOG_DEBUG,"Client data:", $cd); //// Check client signature // $apiKey = base64_decode($cd['secret']); if ($h != '') { // Create the signature using the API key $a; if($_GET) { $a = $_GET; } elseif($_POST) { $a = $_POST; } else { sendRest(S_BACKEND_ERROR); exit; } unset($a['h']); $hmac = sign($a, $apiKey, $myLog); // Compare it if ($hmac != $h) { $myLog->log(LOG_DEBUG, 'client hmac=' . $h . ', server hmac=' . $hmac); sendResp(S_BAD_SIGNATURE, $myLog, $apiKey); exit; } } /* 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); exit; } //// Decode OTP from input // $otpinfo = KSMdecryptOTP($urls, $myLog); if (!is_array($otpinfo)) { sendResp(S_BAD_OTP, $myLog, $apiKey); exit; } $myLog->log(LOG_DEBUG, "Decrypted OTP:", $otpinfo); //// Get Yubikey from DB // $devId = substr($otp, 0, strlen ($otp) - TOKEN_LEN); $yk_publicname=$devId; $localParams = $sync->getLocalParams($yk_publicname); if (!$localParams) { $myLog->log(LOG_NOTICE, 'Invalid Yubikey ' . $yk_publicname); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); exit; } $myLog->log(LOG_DEBUG, "Auth data:", $localParams); if ($localParams['active'] != 1) { $myLog->log(LOG_NOTICE, 'De-activated Yubikey ' . $devId); sendResp(S_BAD_OTP, $myLog, $apiKey); exit; } /* Build OTP params */ $otpParams=array('modified'=>time(), 'otp'=>$otp, 'nonce'=>$nonce, 'yk_publicname'=>$devId, 'yk_counter'=>$otpinfo['session_counter'], 'yk_use'=>$otpinfo['session_use'], 'yk_high'=>$otpinfo['high'], 'yk_low'=>$otpinfo['low']); /* 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); exit; } /* 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); exit; } /* 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); exit; } /* Queue sync requests */ if (!$sync->queue($otpParams, $localParams)) { $myLog->log(LOG_CRIT, "ykval-verify:critical:failed to queue sync requests"); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); exit; } $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, "ykval-verify:notice: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, "ykval-verify:notice:Sync failed"); if ($nr_valid_answers!=$nr_answers) { sendResp(S_REPLAYED_OTP, $myLog, $apiKey, $extra); exit; } else { $extra['sl']=$sl_success_rate; sendResp(S_NOT_ENOUGH_ANSWERS, $myLog, $apiKey, $extra); exit; } } /* Recreate parameters to make phising test work out TODO: use timefunctionality in deltatime library instead */ $sessionCounter = $otpParams['yk_counter']; $sessionUse = $otpParams['yk_use']; $seenSessionCounter = $localParams['yk_counter']; $seenSessionUse = $localParams['yk_use']; $ad['high']=$localParams['yk_high']; $ad['low']=$localParams['yk_low']; $ad['accessed']=$sync->unixToDbTime($localParams['modified']); //// Check the time stamp // if ($sessionCounter == $seenSessionCounter && $sessionUse > $seenSessionUse) { $ts = ($otpinfo['high'] << 16) + $otpinfo['low']; $seenTs = ($ad['high'] << 16) + $ad['low']; $tsDiff = $ts - $seenTs; $tsDelta = $tsDiff * TS_SEC; //// Check the real time // $lastTime = strtotime($ad['accessed']); $now = time(); $elapsed = $now - $lastTime; $deviation = abs($elapsed - $tsDelta); // Time delta server might verify multiple OTPS in a row. In such case validation server doesn't // have time to tick a whole second and we need to avoid division by zero. if ($elapsed != 0) { $percent = $deviation/$elapsed; } else { $percent = 1; } $myLog->log(LOG_INFO, "Timestamp seen=" . $seenTs . " this=" . $ts . " delta=" . $tsDiff . ' secs=' . $tsDelta . ' accessed=' . $lastTime .' (' . $ad['accessed'] . ') now=' . $now . ' (' . strftime("%Y-%m-%d %H:%M:%S", $now) . ') elapsed=' . $elapsed . ' deviation=' . $deviation . ' secs or '. round(100*$percent) . '%'); if ($deviation > TS_ABS_TOLERANCE && $percent > TS_REL_TOLERANCE) { $myLog->log(LOG_NOTICE, "OTP failed phishing test"); if (0) { sendResp(S_DELAYED_OTP, $myLog, $apiKey, $extra); exit; } } } /* Fill up with more respone parameters */ if ($protocol_version>=2.0) { $extra['sl'] = $sl_success_rate; } if ($timestamp==1){ $extra['timestamp'] = ($otpinfo['high'] << 16) + $otpinfo['low']; $extra['sessioncounter'] = $sessionCounter; $extra['sessionuse'] = $sessionUse; } sendResp(S_OK, $myLog, $apiKey, $extra); ?> yubikey-val-2.24/ykval-checksum-clients0000755000175000017500000000522312216341221016325 0ustar jasjas#!/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 = $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.24/ykval-synclib.php0000644000175000017500000004312112216341221015311 0ustar jasjasmyLog = 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())); } function addField($name, $value) { $this->myLog->addField($name, $value); $this->db->addField($name, $value); } function isConnected() { return $this->isConnected; } function DbTimeToUnix($db_time) { $unix=strptime($db_time, '%F %H:%M:%S'); return mktime($unix[tm_hour], $unix[tm_min], $unix[tm_sec], $unix[tm_mon]+1, $unix[tm_mday], $unix[tm_year]+1900); } function UnixToDbTime($unix) { return date('Y-m-d H:i:s', $unix); } function getServer($index) { if (isset($this->syncServers[$index])) return $this->syncServers[$index]; else return ""; } 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; else return false; } public function getQueueLength() { return count($this->db->findBy('queue', null, null, null)); } public function createInfoString($otpParams, $localParams) { 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']; } public function otpParamsFromInfoString($info) { $out=explode(",", $info); parse_str($out[0], $params); return $params; } public function otpPartFromInfoString($info) { $out=explode(",", $info); return $out[0]; } public function localParamsFromInfoString($info) { $out=explode(",", $info); parse_str($out[1], $params); return array('yk_counter'=>$params['local_counter'], 'yk_use'=>$params['local_use']); } public function queue($otpParams, $localParams) { $info=$this->createInfoString($otpParams, $localParams); $this->otpParams = $otpParams; $this->localParams = $localParams; $queued=time(); $res=True; foreach ($this->syncServers as $server) { if(! $this->db->save('queue', array('queued'=>$queued, 'modified'=>$otpParams['modified'], 'otp'=>$otpParams['otp'], 'server'=>$server, 'server_nonce'=>$this->server_nonce, 'info'=>$info))) $res=False; } return $res; } public function getNumberOfServers() { if (is_array($this->syncServers)) return count($this->syncServers); else return 0; } public function log($priority, $msg, $params=NULL) { $logMsg=$msg; if ($params) $logMsg .= ' modified=' . $params['modified'] . ' nonce=' . $params['nonce'] . ' yk_publicname=' . $params['yk_publicname'] . ' yk_counter=' . $params['yk_counter'] . ' yk_use=' . $params['yk_use'] . ' yk_high=' . $params['yk_high'] . ' yk_low=' . $params['yk_low']; if ($this->myLog) $this->myLog->log($priority, $logMsg); else error_log("Warning: myLog uninitialized in ykval-synclib.php. Message is " . $logMsg); } function getLocalParams($yk_publicname) { $this->log(LOG_INFO, "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; } else { $this->log(LOG_NOTICE, 'params for yk_publicname ' . $yk_publicname . ' not found in database'); return false; } } 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]; 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]; 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]; preg_match("/^nonce=([[:alnum:]]+)/m", $str, $out); if ($i != 1) { $this->log(LOG_ALERT, "cannot parse counter value: $str"); } $resParams['nonce']=$out[1]; return $resParams; } public function updateDbCounters($params) { if (isset($params['yk_publicname'])) { $condition='('.$params['yk_counter'].'>yk_counter or ('.$params['yk_counter'].'=yk_counter and ' . $params['yk_use'] . '>yk_use))' ; if(! $this->db->conditionalUpdateBy('yubikeys', 'yk_publicname', $params['yk_publicname'], array('modified'=>$params['modified'], 'yk_counter'=>$params['yk_counter'], 'yk_use'=>$params['yk_use'], 'yk_low'=>$params['yk_low'], 'yk_high'=>$params['yk_high'], 'nonce'=>$params['nonce']), $condition)) { $this->log(LOG_CRIT, 'failed to update internal DB with new counters'); return false; } else { if ($this->db->rowCount()>0) $this->log(LOG_INFO, "updated database ", $params); else $this->log(LOG_INFO, 'database not updated', $params); return true; } } else return false; } public function countersHigherThan($p1, $p2) { if ($p1['yk_counter'] > $p2['yk_counter'] || ($p1['yk_counter'] == $p2['yk_counter'] && $p1['yk_use'] > $p2['yk_use'])) return true; else return false; } public function countersHigherThanOrEqual($p1, $p2) { if ($p1['yk_counter'] > $p2['yk_counter'] || ($p1['yk_counter'] == $p2['yk_counter'] && $p1['yk_use'] >= $p2['yk_use'])) return true; else return false; } public function countersEqual($p1, $p2) { return ($p1['yk_counter']==$p2['yk_counter']) && ($p1['yk_use']==$p2['yk_use']); } public 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)); } public function reSync($older_than=60, $timeout) { $this->log(LOG_INFO, '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"); while ($my_server=$this->db->fetchArray($server_res)) { $this->log(LOG_INFO, "Processing queue for server " . $my_server['server']); $res=$this->db->customQuery("select * from queue WHERE (queued < " . $queued_limit . " or queued is null) and server='" . $my_server['server'] . "'"); $ch = curl_init(); while ($entry=$this->db->fetchArray($res)) { $this->log(LOG_INFO, "server=" . $entry['server'] . ", server_nonce=" . $entry['server_nonce'] . ", info=" . $entry['info']); $url=$entry['server'] . "?otp=" . $entry['otp'] . "&modified=" . $entry['modified'] . "&" . $this->otpPartFromInfoString($entry['info']); /* Send out sync request */ $this->log(LOG_DEBUG, 'url is ' . $url); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERAGENT, "YK-VAL"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_FAILONERROR, true); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $response = curl_exec($ch); if ($response==False) { $this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $entry['server']); break; } if (preg_match("/status=OK/", $response)) { $resParams=$this->parseParamsFromMultiLineString($response); $this->log(LOG_DEBUG, "response contains ", $resParams); /* Update database counters */ $this->updateDbCounters($resParams); /* Retrieve info from entry info string */ /* 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_INFO, '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."); } } /* End of loop over each queue entry for a server */ curl_close($ch); $this->db->closeCursor($res); } /* End of loop over each distinct server in queue */ $this->db->closeCursor($server_res); return true; } public function sync($ans_req, $timeout=1) { /* Construct URLs */ $urls=array(); $res=$this->db->findByMultiple('queue', array("modified"=>$this->otpParams['modified'], "server_nonce"=>$this->server_nonce)); foreach($res as $row) { $urls[]=$row['server'] . "?otp=" . $row['otp'] . "&modified=" . $row['modified'] . "&" . $this->otpPartFromInfoString($row['info']); } /* Send out requests */ $ans_arr=$this->retrieveURLasync_wrap($urls, $ans_req, $timeout); if (!is_array($ans_arr)) { $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://github.com/Yubico/yubikey-val/wiki/ServerReplicationProtocol 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; else return False; } public function getNumberOfValidAnswers() { if (isset($this->valid_answers)) return $this->valid_answers; else return 0; } public function getNumberOfAnswers() { if (isset($this->answers)) return $this->answers; else return 0; } function retrieveURLasync_wrap ($urls, $ans_req=1, $timeout=1.0) { return retrieveURLasync("YK-VAL sync", $urls, $this->myLog, $ans_req, $match="status=OK", $returl=True, $timeout); } } ?> yubikey-val-2.24/ykval-export-clients.10000644000175000017500000000440412216341221016200 0ustar jasjas.\" Copyright (c) 2011-2013 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://github.com/Yubico/yubikey-val/wiki/ClientInfoFormat" "Client Info data format" .PP YubiKeys can be obtained from .URL "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/README0000644000175000017500000000200312216341221012663 0ustar jasjasyubikey-val =========== The YubiKey Validation Server (YK-VAL) is a server that validates Yubikey OTPs. YK-VAL is written in PHP, for use with web servers such as Apache. The server implements the Yubico API protocol as defined in doc/ValidationProtocol*. This server talks to another service for decrypting the OTPs, to avoid storing any AES keys within the validation server. One implementation of this service is YKKSM: https://github.com/Yubico/yubikey-ksm Another implementation of a KSM using the YubiHSM hardware is Python-PyHSM: https://github.com/Yubico/python-pyhsm Note that version 1.x is a minimal centralized server. Version 2.x is a replicated system that uses multiple machines. Releases are available from: http://yubico.github.com/yubikey-val/releases.html Documentation is in doc/ If you've checked out the source tree and the doc/ dir is empty, do $ git submodule init $ git submodule update The documentation is also available online at http://github.com/Yubico/yubikey-val/wiki yubikey-val-2.24/ykval-import0000755000175000017500000001014712216341221014377 0ustar jasjas#!/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]); $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.24/ykval-db-oci.php0000644000175000017500000001642412216341221015011 0ustar jasjasdb_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.24/ykval-synchronize.10000644000175000017500000000545612216341221015603 0ustar jasjas.\" Copyright (c) 2011-2013 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 "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-queue0000755000175000017500000000343712216341221014215 0ustar jasjas#!/usr/bin/php reSync($baseParams['__YKVAL_SYNC_OLD_LIMIT__'], $baseParams['__YKVAL_SYNC_RESYNC_TIMEOUT__']); } while(sleep($baseParams['__YKVAL_SYNC_INTERVAL__'])==0); ?> yubikey-val-2.24/ykval-export-clients0000755000175000017500000000417412216341221016050 0ustar jasjas#!/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.24/Makefile0000644000175000017500000001627212216341221013460 0ustar jasjas# Copyright (c) 2009-2013 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.24 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-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 MUNIN = ykval-munin-ksmlatency.php ykval-munin-vallatency.php \ ykval-munin-queuelength.php ykval-munin-responses.pl \ ykval-munin-yubikeystats.php DOCS = doc/ClientInfoFormat.wiki doc/Installation.wiki \ doc/RevocationService.wiki doc/ServerReplicationProtocol.wiki \ doc/SyncMonitor.wiki doc/Troubleshooting.wiki all: @echo "Try 'make install' or 'make symlink'." @echo "Docs: https://github.com/Yubico/yubikey-val/wiki/Installation" @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 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-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-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) git submodule init git submodule update mkdir $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION)/doc cp $(CODE) $(MANS) $(MUNIN) $(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.24/ykval-checksum-deactivated0000755000175000017500000000506612216341221017146 0ustar jasjas#!/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 = $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.24/ykval-checksum-deactivated.10000644000175000017500000000451112216341221017274 0ustar jasjas.\" Copyright (c) 2011-2013 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 "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-ping.php0000644000175000017500000000262312216341221014605 0ustar jasjas yubikey-val-2.24/ykval-common.php0000644000175000017500000001751512216341221015146 0ustar jasjaslog(LOG_INFO, $str); die($str . "\n"); } function unescape($s) { return str_replace('\\', "", $s); } function getHttpVal($key, $defaultVal) { $val = $defaultVal; if (array_key_exists($key, $_GET)) { $val = $_GET[$key]; } else if (array_key_exists($key, $_POST)) { $val = $_POST[$key]; } $v = unescape(trim($val)); return $v; } function log_format() { $str = ""; foreach (func_get_args() as $msg) { if (is_array($msg)) { foreach($msg as $key => $value){ $str .= "$key=$value "; } } else { $str .= $msg . " "; } } return $str; } // Return eg. 2008-11-21T06:11:55Z0711 // function getUTCTimeStamp() { date_default_timezone_set('UTC'); $tiny = substr(microtime(false), 2, 3); return date('Y-m-d\TH:i:s\Z0', time()) . $tiny; } # NOTE: When we evolve to using general DB-interface, this functinality # should be moved there. function DbTimeToUnix($db_time) { $unix=strptime($db_time, '%F %H:%M:%S'); return mktime($unix[tm_hour], $unix[tm_min], $unix[tm_sec], $unix[tm_mon]+1, $unix[tm_mday], $unix[tm_year]+1900); } function UnixToDbTime($unix) { return date('Y-m-d H:i:s', $unix); } // 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 = urldecode(http_build_query($a)); // the TRUE at the end states we want the raw value, not hexadecimal form $hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true); $hmac = base64_encode($hmac); $logger->log(LOG_DEBUG, 'SIGN: ' . $qs . ' H=' . $hmac); return $hmac; } // sign an array of query string function hex2b64 ($hex_str) { $bin = pack("H*", $hex_str); return base64_encode($bin); } function modhex2b64 ($modhex_str) { $hex_str = strtr ($modhex_str, "cbdefghijklnrtuv", "0123456789abcdef"); return hex2b64($hex_str); } // 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) { $mh = curl_multi_init(); $ch = array(); foreach ($urls as $id => $url) { $handle = curl_init(); $logger->log(LOG_DEBUG, $ident . " adding URL : " . $url); curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL"); curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($handle, CURLOPT_FAILONERROR, true); curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); curl_multi_add_handle($mh, $handle); $ch[$handle] = $handle; } $str = false; $ans_count = 0; $ans_arr = array(); do { while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM) ; while ($info = curl_multi_info_read($mh)) { $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_DEBUG, $ident . " errno/error: " . $errno . "/" . $error, $cinfo); $ans_count++; if ($returl) $ans_arr[]="url=" . $cinfo['url'] . "\n" . $str; else $ans_arr[]=$str; } if ($ans_count >= $ans_req) { foreach ($ch as $h) { curl_multi_remove_handle ($mh, $h); curl_close ($h); } curl_multi_close ($mh); return $ans_arr; } curl_multi_remove_handle ($mh, $info['handle']); curl_close ($info['handle']); unset ($ch[$info['handle']]); } curl_multi_select ($mh); } } while($active); foreach ($ch as $h) { curl_multi_remove_handle ($mh, $h); curl_close ($h); } curl_multi_close ($mh); if ($ans_count>0) return $ans_arr; return $str; } function retrieveURLsimple ($url, $match="^OK") { foreach (file($url) as $line) { if (preg_match("/".$match."/", $line)) { return $line; } } return false; } // $otp: A yubikey OTP function KSMdecryptOTP($urls, $logger) { $ret = array(); if (!is_array($urls)) { $response = retrieveURLsimple ($urls); } elseif (count($urls) == 1) { $response = retrieveURLsimple ($urls[0]); } else { $response = retrieveURLasync ("YK-KSM", $urls, $logger, $ans_req=1, $match="^OK", $returl=False, $timeout=10); if (is_array($response)) { $response = $response[0]; } } if ($response) { $logger->log(LOG_DEBUG, log_format("YK-KSM response: ", $response)); } 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; } // End decryptOTP function sendResp($status, $logger, $apiKey = '', $extra = null) { if ($status == null) { $status = S_BACKEND_ERROR; } $a['status'] = $status; $a['t'] = getUTCTimeStamp(); if ($extra){ foreach ($extra as $param => $value) $a[$param] = $value; } $h = sign($a, $apiKey, $logger); $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 " . date("c") . " " . microtime() . ")"); echo $str; } ?> yubikey-val-2.24/ykval-import-clients.10000644000175000017500000000442012216341221016167 0ustar jasjas.\" Copyright (c) 2011-2013 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://github.com/Yubico/yubikey-val/wiki/ClientInfoFormat" "Client Info data format" .PP YubiKeys can be obtained from .URL "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-db.php0000644000175000017500000002215112216341221014233 0ustar jasjasmyLog->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; } public function truncateTable($name) { $this->query("TRUNCATE TABLE " . $name); } /** * 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); } /** * helper function used to get rows from Db table in reversed order. * defaults to obtaining 1 row. * * @param string $table Database table to update row in * @param string $key Column to select rows by * @param string $value Value to select rows by * @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 lastBy($table, $key, $value, $nr=1) { return Db::findBy($table, $key, $value, $nr, 1); } /** * helper function used to get rows from Db table in standard order. * defaults to obtaining 1 row. * * @param string $table Database table to update row in * @param string $key Column to select rows by * @param string $value Value to select rows by * @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 firstBy($table, $key, $value, $nr=1) { return Db::findBy($table, $key, $value, $nr); } } ?> yubikey-val-2.24/ykval-db-pdo.php0000644000175000017500000001567012216341221015023 0ustar jasjasdb_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(); } public function truncateTable($name) { $this->query("TRUNCATE TABLE " . $name); } /** * 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 ($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; } 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; 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.24/ykval-db.oracle.sql0000644000175000017500000000161712216341221015513 0ustar jasjas-- 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.24/ykval-queue.10000644000175000017500000000422312216341221014343 0ustar jasjas.\" Copyright (c) 2011-2013 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 "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-munin-ksmlatency.php0000755000175000017500000000551212216341221017151 0ustar jasjas#!/usr/bin/php yubikey-val-2.24/ykval-checksum-clients.10000644000175000017500000000450512216341221016463 0ustar jasjas.\" Copyright (c) 2011-2013 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 "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-synchronize0000755000175000017500000000444012216341221015437 0ustar jasjas#!/usr/bin/php yubikey-val-2.24/ykval-sync.php0000644000175000017500000001504112216341221014622 0ustar jasjasaddField('ip', $_SERVER['REMOTE_ADDR']); if(empty($_SERVER['QUERY_STRING'])) { sendResp(S_MISSING_PARAMETER, $myLog, $apiKey); exit; } $myLog->log(LOG_INFO, "Request: " . $_SERVER['QUERY_STRING']); $sync = new SyncLib('ykval-sync:synclib'); $sync->addField('ip', $_SERVER['REMOTE_ADDR']); if (! $sync->isConnected()) { sendResp(S_BACKEND_ERROR, $myLog, $apiKey); exit; } # # Verify that request comes from valid server # $myLog->log(LOG_INFO, 'Received request from ' . $_SERVER['REMOTE_ADDR']); $allowed = in_array($_SERVER['REMOTE_ADDR'], $baseParams['__YKVAL_ALLOWED_SYNC_POOL__']); if (!$allowed) { $myLog->log(LOG_NOTICE, 'Operation not allowed from IP ' . $_SERVER['REMOTE_ADDR']); $myLog->log(LOG_DEBUG, 'Remote IP ' . $_SERVER['REMOTE_ADDR'] . ' not listed in allowed sync pool : ' . implode(', ', $baseParams['__YKVAL_ALLOWED_SYNC_POOL__'])); sendResp(S_OPERATION_NOT_ALLOWED, $myLog, $apiKey); exit; } # # 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); if ($value==Null) { $myLog->log(LOG_NOTICE, "Received request with parameter[s] (" . $param . ") missing value"); sendResp(S_MISSING_PARAMETER, $myLog, $apiKey); exit; } $syncParams[$param]=$value; $tmp_log .= "$param=$value "; } $myLog->log(LOG_INFO, $tmp_log); # # 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') as $param) { if (preg_match("/^[0-9]+$/", $syncParams[$param])==0) { $myLog->log(LOG_NOTICE, 'Input parameters ' . $param . ' not correct'); sendResp(S_MISSING_PARAMETER, $myLog, $apiKey); exit; } } foreach (array('yk_counter', 'yk_use', 'yk_high', 'yk_low') as $param) { if (preg_match("/^(-1|[0-9]+)$/", $syncParams[$param])==0) { $myLog->log(LOG_NOTICE, 'Input parameters ' . $param . ' not correct'); sendResp(S_MISSING_PARAMETER, $myLog, $apiKey); exit; } } # # Get local counter data # $yk_publicname = $syncParams['yk_publicname']; $localParams = $sync->getLocalParams($yk_publicname); if (!$localParams) { $myLog->log(LOG_NOTICE, 'Invalid Yubikey ' . $yk_publicname); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); exit; } /* Conditional update local database */ $sync->updateDbCounters($syncParams); $myLog->log(LOG_DEBUG, 'Local params ' , $localParams); $myLog->log(LOG_DEBUG, 'Sync request params ' , $syncParams); # # Compare sync and local counters and generate warnings according to # # https://github.com/Yubico/yubikey-val/wiki/ServerReplicationProtocol # 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, $apiKey); exit; } $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, $apiKey, $extra); ?> yubikey-val-2.24/ykval-import.10000644000175000017500000000435312216341221014535 0ustar jasjas.\" Copyright (c) 2011-2013 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://github.com/Yubico/yubikey-val/wiki/YubiKeyInfoFormat" "YubiKey Info data format" .PP YubiKeys can be obtained from .URL "http://www.yubico.com/" "Yubico" "." yubikey-val-2.24/ykval-munin-vallatency.php0000755000175000017500000000634512216341221017146 0ustar jasjas#!/usr/bin/php yubikey-val-2.24/ykval-munin-queuelength.php0000755000175000017500000000420712216341221017325 0ustar jasjas#!/usr/bin/php addField('ip', $_SERVER['REMOTE_ADDR']); } $len = $sync->getQueueLength (); echo "queuelength.value $len\n"; #%# family=auto #%# capabilities=autoconf ?> yubikey-val-2.24/ykval-export0000755000175000017500000000443012216341221014404 0ustar jasjas#!/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.24/ChangeLog0000644000175000017500000015406512216341221013575 0ustar jasjas2013-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.24/ykval-resync.php0000644000175000017500000000645212216341221015157 0ustar jasjasaddField('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) { $localParams = $sync->getLocalParams($key); if (!$localParams) { 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.24/ykval-import-clients0000755000175000017500000000566012216341221016042 0ustar jasjas#!/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.24/ykval-munin-yubikeystats.php0000755000175000017500000000642112216341221017537 0ustar jasjas#!/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"; } #%# family=auto #%# capabilities=autoconf ?>