diff options
author | jim-p <jimp@pfsense.org> | 2012-09-13 21:15:43 -0400 |
---|---|---|
committer | jim-p <jimp@pfsense.org> | 2012-09-13 21:15:43 -0400 |
commit | 1f1a08c85b7e8ddc6473795534ed5422a2c5aaaf (patch) | |
tree | abc8057a57e98803fe99ddb8c70f3e7fdf7d01b3 | |
parent | e288ddb111d0d7b00ec33b0672ed7ea2c417f629 (diff) | |
download | pfsense-1f1a08c85b7e8ddc6473795534ed5422a2c5aaaf.zip pfsense-1f1a08c85b7e8ddc6473795534ed5422a2c5aaaf.tar.gz |
Allow/deny access to DHCP by partial MAC matching.
-rw-r--r-- | etc/inc/services.inc | 18 | ||||
-rw-r--r-- | etc/inc/util.inc | 5 | ||||
-rwxr-xr-x | usr/local/www/services_dhcp.php | 44 |
3 files changed, 64 insertions, 3 deletions
diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 6cea972..ffc15e8 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -535,6 +535,14 @@ EOPP; $dnscfg .= " option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";"; } + /* Create classes */ + $all_mac_list = array_unique(explode(',', $dhcpifconf['mac_allow'] . ',' . $dhcpifconf['mac_deny'])); + foreach ($all_mac_list as $mac) { + $dhcpdconf .= 'class "' . str_replace(':', '', $mac) . '" {' . "\n"; + $dhcpdconf .= ' match if substring (hardware, 1, ' . (substr_count($mac, ':') + 1) . ') = ' . $mac . ';' . "\n"; + $dhcpdconf .= '}' . "\n"; + } + $dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n"; $dhcpdconf .= " pool {\n"; @@ -546,6 +554,16 @@ EOPP; $dhcpdconf .= ";\n"; } + /* allow/deny MACs */ + $mac_allow_list = array_unique(explode(',', $dhcpifconf['mac_allow'])); + foreach ($mac_allow_list as $mac) { + $dhcpdconf .= " allow members of \"" . str_replace(':', '', $mac) . "\";\n"; + } + $mac_deny_list = array_unique(explode(',', $dhcpifconf['mac_deny'])); + foreach ($mac_deny_list as $mac) { + $dhcpdconf .= " deny members of \"" . str_replace(':', '', $mac) . "\";\n"; + } + if($dhcpifconf['failover_peerip'] <> "") $dhcpdconf .= " deny dynamic bootp clients;\n"; diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 881537f..e7a0734 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -604,8 +604,9 @@ function is_domain($domain) { } /* returns true if $macaddr is a valid MAC address */ -function is_macaddr($macaddr) { - return preg_match('/^[0-9A-F]{2}(?:[:][0-9A-F]{2}){5}$/i', $macaddr) == 1 ? true : false; +function is_macaddr($macaddr, $partial=false) { + $repeat = ($partial) ? '1,5' : '5'; + return preg_match('/^[0-9A-F]{2}(?:[:][0-9A-F]{2}){'.$repeat.'}$/i', $macaddr) == 1 ? true : false; } /* returns true if $name is a valid name for an alias */ diff --git a/usr/local/www/services_dhcp.php b/usr/local/www/services_dhcp.php index ba95897..078d099 100755 --- a/usr/local/www/services_dhcp.php +++ b/usr/local/www/services_dhcp.php @@ -141,6 +141,8 @@ if (is_array($config['dhcpd'][$if])){ $pconfig['staticarp'] = isset($config['dhcpd'][$if]['staticarp']); $pconfig['ddnsdomain'] = $config['dhcpd'][$if]['ddnsdomain']; $pconfig['ddnsupdate'] = isset($config['dhcpd'][$if]['ddnsupdate']); + $pconfig['mac_allow'] = $config['dhcpd'][$if]['mac_allow']; + $pconfig['mac_deny'] = $config['dhcpd'][$if]['mac_deny']; list($pconfig['ntp1'],$pconfig['ntp2']) = $config['dhcpd'][$if]['ntpserver']; $pconfig['tftp'] = $config['dhcpd'][$if]['tftp']; $pconfig['ldap'] = $config['dhcpd'][$if]['ldap']; @@ -183,6 +185,16 @@ function is_inrange($test, $start, $end) { return false; } +function validate_partial_mac_list($maclist) { + $macs = explode(',', $maclist); + + // Loop through and look for invalid MACs. + foreach ($macs as $mac) + if (!is_macaddr($mac, true)) + return false; + return true; +} + if ($_POST) { unset($input_errors); @@ -241,7 +253,13 @@ if ($_POST) { } } } - + + // Validate MACs + if (!empty($_POST['mac_allow']) && !validate_partial_mac_list($_POST['mac_allow'])) + $input_errors[] = gettext("If you specify a mac allow list, it must contain only valid partial MAC addresses."); + if (!empty($_POST['mac_deny']) && !validate_partial_mac_list($_POST['mac_deny'])) + $input_errors[] = gettext("If you specify a mac deny list, it must contain only valid partial MAC addresses."); + if (($_POST['ntp1'] && !is_ipaddrv4($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv4($_POST['ntp2']))) $input_errors[] = gettext("A valid IP address must be specified for the primary/secondary NTP servers."); if (($_POST['domain'] && !is_domain($_POST['domain']))) @@ -368,6 +386,8 @@ if ($_POST) { $config['dhcpd'][$if]['staticarp'] = ($_POST['staticarp']) ? true : false; $config['dhcpd'][$if]['ddnsdomain'] = $_POST['ddnsdomain']; $config['dhcpd'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false; + $config['dhcpd'][$if]['mac_allow'] = $_POST['mac_allow']; + $config['dhcpd'][$if]['mac_deny'] = $_POST['mac_deny']; unset($config['dhcpd'][$if]['ntpserver']); if ($_POST['ntp1']) @@ -482,6 +502,8 @@ include("head.inc"); document.iform.dhcpleaseinlocaltime.disabled = endis; document.iform.ddnsdomain.disabled = endis; document.iform.ddnsupdate.disabled = endis; + document.iform.mac_allow.disabled = endis; + document.iform.mac_deny.disabled = endis; document.iform.ntp1.disabled = endis; document.iform.ntp2.disabled = endis; document.iform.tftp.disabled = endis; @@ -505,6 +527,12 @@ include("head.inc"); aodiv.style.display = "block"; } + function show_maccontrol_config() { + document.getElementById("showmaccontrolbox").innerHTML=''; + aodiv = document.getElementById('showmaccontrol'); + aodiv.style.display = "block"; + } + function show_ntp_config() { document.getElementById("showntpbox").innerHTML=''; aodiv = document.getElementById('showntp'); @@ -772,6 +800,20 @@ include("head.inc"); </td> </tr> <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("MAC Address Control");?></td> + <td width="78%" class="vtable"> + <div id="showmaccontrolbox"> + <input type="button" onClick="show_maccontrol_config()" value="<?=gettext("Advanced");?>"></input> - <?=gettext("Show MAC Address Control");?></a> + </div> + <div id="showmaccontrol" style="display:none"> + <input name="mac_allow" type="text" class="formfld unknown" id="mac_allow" size="20" value="<?=htmlspecialchars($pconfig['mac_allow']);?>"><br /> + <?=gettext("Enter a list of partial MAC addresses to allow, comma separated, no spaces, such as ");?>00:00:00,01:E5:FF + <input name="mac_deny" type="text" class="formfld unknown" id="mac_deny" size="20" value="<?=htmlspecialchars($pconfig['mac_deny']);?>"><br /> + <?=gettext("Enter a list of partial MAC addresses to deny access, comma separated, no spaces, such as ");?>00:00:00,01:E5:FF + </div> + </td> + </tr> + <tr> <td width="22%" valign="top" class="vncell"><?=gettext("NTP servers");?></td> <td width="78%" class="vtable"> <div id="showntpbox"> |