<?php # Copyright(C) 2004-2007 INL # Written by Eric Leblond <regit@inl.fr> # Vincent Deffontaines <gryzor@inl.fr> # Jean Gillaux <jean@inl.fr> # Damien Boucard <damien.boucard AT inl.fr> # # $Id: elt.class.php 17927 2009-02-16 13:16:09Z haypo $ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see <http://www.gnu.org/licenses/>. require_once('pear/Net/IPv4.php'); # Net_IPv4 class require_once('html.php'); # createLink() require_once('function.php'); # modifiedTimestamp() $L7RULE_ACTIONS = Array( 'accept', 'ulogaccept', 'ulogdrop', 'logaccept', 'logdrop', ); class elt { var $datas; function elt($data, $data_type='xml', $id=0, $element_type=null) { if ($data_type == 'xml') { $struct=$data->attributes(); $this->datas = Array(); if ($element_type) $this->datas['type'] = $element_type; foreach($struct as $attr) { $this->datas[$attr->name()] = $attr->value(); } }else{ $data["ID"]=$id; if ($element_type and !array_key_exists('type', $data)) $data['type'] = $element_type; $this->datas = $data; } if (!array_key_exists('modified', $this->datas)) { $this->datas['modified'] = modifiedTimestamp(); } # Set value of $this->defaultaction if it's not set # Hack needed for ruleset created on nuface older than version 2.0.11 if ($this->datas['type'] == 'l7rule' && (!array_key_exists('action', $this->datas) || $this->datas['action'] == '')) { $this->datas['action'] = 'accept'; add_log(sprintf( _("Set action of %s to %s."), $this->str(), $this->datas['action'])); } $errmsg = $this->check_consistency(); if ($errmsg) { $errmsg = sprintf(_('%s consistency error: %s!'), $this->str(), $errmsg); throw new Exception($errmsg); } } function xmldump($xml,$curelt){ $node=$xml->create_element( 'elt' ); foreach($this->datas as $key=>$data){ if (($data != '--') and ($data != '') and ($key!='invalid')) $node->set_attribute($key,$data); } $curelt->append_child($node); } function express($base=null) { $result=array(); if (($this->datas['type'] == 'link')){ $base->express_elt($this->datas['linkid'],'all',$base); } else { foreach($this->datas as $key=>$data){ $result[$key]=$data; } } return($result); } function str() { $text = _('Element'); if (array_key_exists('name', $this->datas)) $text .= ' "'.$this->datas['name'].'"'; $info = Array(); if (array_key_exists('ID', $this->datas) and $this->datas['ID']) $info[] = '#'.$this->datas['ID']; if (array_key_exists('type', $this->datas)) $info[] = 'type "'.$this->datas['type'].'"'; if ($info) $text .= ' ('.implode(', ', $info).')'; return $text; } function check_consistency() { global $L7RULE_ACTIONS; $type = array_get($this->datas, 'type', ''); if (!check_element_type($type)) { return sprintf(_('Invalid element type: "%s"'), $type); } // desc.xml elements have no identifier if (!in_array($type, Array('ipv4', 'connection', 'address', 'mark')) && !$this->datas['ID']) { return _("Invalid identifier"); } if ($type == 'ipv4' or $type == 'address') { return $this->check_address_consistency(); } else if ($type == 'periodicity') { return $this->check_periodicity_consistency(); } else if ($type == 'nufw') { $group = array_get($this->datas, 'group', ''); if (!check_nb($group, false)) return sprintf(_('Invalid NuFW user group: "%s"'), $group); } else if ($type == 'l7rule') { $action = array_get($this->datas, 'action', ''); if (!in_array($action, $L7RULE_ACTIONS)) return sprintf(_('Invalid action: "%s"'), $action); } else if ($type == 'proto') { return $this->check_protocol_consistency(); } return ''; } function check_periodicity_consistency() { # Check hour $starthour = (int)array_get($this->datas, 'starthour', '-1'); $stophour= (int)array_get($this->datas, 'stophour', '-1'); if ($starthour < 0 or 24 < $starthour) { return sprintf(_('Invalid start hour value (%s)'), $starthour); } if ($stophour < 0 or 24 < $stophour) { return sprintf(_('Invalid start hour value (%s)'), $starthour); } if ($stophour < $starthour) { return _('Stop hour is before start hour'); } if ($stophour == $starthour) { return _('Period duration is nul: start hour = stop hour'); } # Check days $startday = (int)array_get($this->datas, 'startday', '0'); $stopday = (int)array_get($this->datas, 'stopday', '0'); if ($startday < 1 or 7 < $startday) { return sprintf(_('Invalid start day value (%s)'), $startday); } if ($stopday < 1 or 7 < $stopday) { return sprintf(_('Invalid stop day value (%s)'), $stopday); } if ($stopday < $startday) { return _('Stop day is before start day'); } return ''; } function check_address_consistency() { // Get IPv4 address if (array_key_exists('net', $this->datas)) { // acls.xml <elt> $ip = $this->datas['net']; } else if (array_key_exists('addr', $this->datas)) { // desc.xml <net> $ip = $this->datas['addr']; } else { return _('Empty IPv4 address'); } if (trim($ip) == '') return _('Empty IPv4 address'); // Reject loopback address if (Net_IPv4::ipInNetwork($ip, '127.0.0.0/8')) return sprintf(_('Local IPv4 address ("%s") is forbidden'), $ip); return ''; } function check_protocol_consistency() { // Check protocol $protocol = array_get($this->datas, 'proto', ''); if (!$protocol || !check_protocol($protocol)) { return sprintf(_('Invalid protocol: "%s"'), $protocol); } // Check source and destination port ranges if ($protocol == 'tcp' or $protocol == 'udp') { $syntax = _('a valid range is a port in 1..65535 (eg. "80) or a range of two ports (eg. "1024:65535")'); $value = array_get($this->datas, 'sport', ''); if ($value and !check_port_range($value)) { return sprintf(_('Invalid port range for %s: "%s"; %s'), 'source port', $value, $syntax); } $value = array_get($this->datas, 'dport', ''); if (!check_port_range($value)) { return sprintf(_('Invalid port range for %s: "%s"; %s'), 'destination port', $value, $syntax); } } else { $sport = array_get($this->datas, 'sport'); $dport = array_get($this->datas, 'dport'); if ($sport or $dport) { return sprintf(_('The protocol "%s" has no source nor destination port'), $protocol); } } // Check ICMP type if ($protocol == 'icmp') { $value = array_get($this->datas, 'icmptype', ''); if ($value and !check_icmp_types($value)) { return sprintf(_('Invalid ICMP type: "%s"'), $value); } } else { $value = array_get($this->datas, 'icmptype'); if ($value and $value != '--') { return sprintf(_('The protocol "%s" has no ICMP type'), $protocol); } } return ''; } function get_id(){ return $this->datas["ID"]; } function get_obj() { $result=array(); foreach ($this->datas as $key=>$obj) { $result{$key}=$obj; } return $result; } } function max_elt($array) { $max=0; if (isset($array) and ($array!='')) foreach ($array as $elt) { $local=$elt->get_ID(); if ($local>$max) $max=$local; } return($max); } function create_check_element_link($page, $obj, $elt=null, $use_url=true) { if ($use_url) { $text = $obj->name; if ($elt) { $text .= " -> ".$elt->datas['name']; } $url = $page.'?elt='.$obj->ID; if ($elt) { $url .= '&sub_elt='.$elt->datas['ID']; } return createLink($url, $text); } else { $text = $obj->name.' (#'.$obj->ID.')'; if ($elt) { $text .= " -> ".$elt->datas['name'].' (#'.$elt->datas['ID'].')'; } return htmlspecialchars($text); } } ?>