From 2caea6a2cca2cbc37f1d99ebd8e5ea8277661d77 Mon Sep 17 00:00:00 2001 From: Anders Lind Date: Mon, 18 Jan 2016 20:50:23 +0100 Subject: Bugfixes & handling $duid and $type, Fixes #4206 This patch addresses: 1. Handling of IA_NA and IA_PD strings (that contain IAID+DUID content) using only the DUID part. 2. Fixing regular expression matching with respect to the IAID+DUID string regarding the legal \" substring (used in ISC DHCPv6 leases). 3. Checking the $duid variable before use. Default case for $type in the switch case statement. Please see the ticket for further information. --- src/usr/local/sbin/prefixes.php | 66 +++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/usr/local/sbin/prefixes.php b/src/usr/local/sbin/prefixes.php index 118bd9e..048fc11 100644 --- a/src/usr/local/sbin/prefixes.php +++ b/src/usr/local/sbin/prefixes.php @@ -10,9 +10,22 @@ $fd = fopen($leases_file, 'r'); $duid_arr = array(); while (( $line = fgets($fd, 4096)) !== false) { // echo "$line"; - if (preg_match("/^(ia-[np][ad])[ ]+\"(.*?)\"/i", $line, $duidmatch)) { + + /* Originally: preg_match("/^(ia-[np][ad])[ ]+\"(.*?)\"/i", $line, $duidmatch) + That is: \"(.*?)\" + , which is a non-greedy matching. However that does not go well with the legal + substring \" in the IAID+DUID lease string format of ISC DHCPDv6, + because it truncates before we reach the end of the IAID+DUID string! + Instead we use: \"(.*)\" + (Might fail if content of the lease file is not well formed.) + + Maybe someone would argue to e.g. use \"(.*?)\"[ \t]*{[ \t]*$ + instead + (Either we get a valid result or nothing at all.) + , but I'll leave it to others to decide! */ + if (preg_match("/^(ia-[np][ad])[ ]+\"(.*)\"/i", $line, $duidmatch)) { $type = $duidmatch[1]; - $duid = $duidmatch[2]; + $duid = extract_duid($duidmatch[2]); continue; } @@ -34,13 +47,17 @@ while (( $line = fgets($fd, 4096)) !== false) { /* closing bracket */ if (preg_match("/^}/i", $line)) { - switch ($type) { - case "ia-na": - $duid_arr[$duid][$type] = $ia_na; - break; - case "ia-pd": - $duid_arr[$duid][$type] = $ia_pd; - break; + if (isset($duid) && $duid !== false) { + switch ($type) { + case "ia-na": + $duid_arr[$duid][$type] = $ia_na; + break; + case "ia-pd": + $duid_arr[$duid][$type] = $ia_pd; + break; + default: + break; + } } unset($type); unset($duid); @@ -90,4 +107,35 @@ if (count($expires) > 0) { } } +/* handle quotify_buf - https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=blob;f=common/print.c */ +function extract_duid($ia_string) { + for ($i = 0, $iaid_counter = 0, $len = strlen($ia_string); $i < $len && $iaid_counter < 4; $i++, $iaid_counter++) { + if ($ia_string[$i] !== '\\') { + continue; + } + else if ($len - $i >= 2) { + if (($ia_string[$i+1] === '\\') || ($ia_string[$i+1] === '"')) { + $i += 1; + continue; + } + else if ($len - $i >= 4) { + if (preg_match('/[0-7]{3}/', substr($ia_string, $i+1, $i+4))) { + $i += 3; + continue; + } + } + } + + return false; + } + + /* Return anything after the first 4 octets! */ + if ($iaid_counter === 4) { + /* substr returns false when $len == $i */ + return substr($ia_string, $i); + } + + return false; +} + ?> -- cgit v1.1