diff options
author | Anders Lind <anders.lind@gmail.com> | 2016-01-18 20:50:23 +0100 |
---|---|---|
committer | Anders Lind <anders.lind@gmail.com> | 2016-01-18 20:50:23 +0100 |
commit | 2caea6a2cca2cbc37f1d99ebd8e5ea8277661d77 (patch) | |
tree | b6b32ac4eabd9ba12a5fe03c4dd1b988587dafa9 /src | |
parent | 7d759989e585cfec0ad62ea1373fbf61da71999e (diff) | |
download | pfsense-2caea6a2cca2cbc37f1d99ebd8e5ea8277661d77.zip pfsense-2caea6a2cca2cbc37f1d99ebd8e5ea8277661d77.tar.gz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/local/sbin/prefixes.php | 66 |
1 files 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; +} + ?> |