Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > dca483b59ba61f3fa092de932ddd570e > files > 240

nuface-2.0.14-2mdv2009.1.i586.rpm

<?php
# Copyright(C) 2004-2006 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: index_func.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('desc.class.php');
require_once('ruleset.class.php');
require_once('bichain.php');

function generate_firewall_rules($ruleset_filename)
{
  global $nuface_dir, $network_desc_file, $datadir, $support_duplication;

  if (!check_filename($ruleset_filename))
  {
      log_error(sprintf(_('Invalid filename: "%s".'), $ruleset_filename));
      return null;
  }

  $desc_mtime = filemtime("$nuface_dir/$network_desc_file");
  $ruleset_mtime = filemtime("$datadir/$ruleset_filename");
  if ($desc_mtime > $ruleset_mtime)
  {
      log_error(sprintf(
        _('The networks definition is more recent than the ruleset: try to load and then save the ruleset "%s"!'),
        filenameWithoutXml($ruleset_filename)));
      return null;
  }

  // Load ruleset to make sure that it's consistent
  $ruleset = read_ruleset_file($ruleset_filename);
  if (!$ruleset)
      return null;

  // Check that networks definition exists in the ruleset
  $used_desc = find_build_desc($ruleset, false);
  if (is_null($used_desc))
  {
      log_error(sprintf(
        _('Error: unable to find used networks definition: try to load and then save the ruleset "%s"!'),
        $ruleset->name));
      return null;
  }

  // Execute nupyf, nuperiod and nulayer7
  $ok = execute_nupyf_and_friends($ruleset_filename, $used_desc);
  if (!$ok)
  {
      log_error(_('Firewall rules were not updated!'));
      return null;
  }

  rename_firewall_files();
  return $ruleset;
}

function execute_nupyf_and_friends($ruleset_filename, $used_desc)
{
    global $l7_firewall;

    $ok = execute_nupyf($ruleset_filename, $used_desc);
    if (!$ok)
        return false;

    $ok = execute_nuperiod($ruleset_filename);
    if (!$ok)
        return false;

    $l7_filename = remove_layer7_rules();

    if ($l7_firewall)
    {
        $ok = execute_nulayer7($ruleset_filename, $l7_filename);
        if (!$ok)
            return false;
    }
    return true;
}

function execute_nupyf($file, $used_desc)
{
    global $nufw_firewall;
    global $etc_dir, $datadir, $nuface_dir, $rules_dir, $std_rules_dir, $nufw_rules_dir;
    global $nupyf_command, $nupyf_conf_file, $nupyf_ldap_file, $network_desc_file;

    $desc_file = "$nuface_dir/$network_desc_file";

    $input_rules = 'input_rules.tmp';
    $output_rules = 'output_rules.tmp';
    $nat_rules = 'nat_rules.tmp';
    $mangle_rules = 'mangle_rules.tmp';
    $nupyf_args = gen_nupyf_args($nufw_rules_dir, 'dispatch_targets.tmp', 'default_estrel_invalid.tmp','dispatch_rules.tmp', 'forward_rules.tmp', $input_rules, $output_rules, $nat_rules, false, $mangle_rules);
    $nupyf_args.= " --sortid $used_desc";
    if ($nufw_firewall)
    {
        $nufw_cmd  = $nupyf_command . $nupyf_args;
        $nufw_cmd .= " --conf ".$etc_dir."/".$nupyf_conf_file;
        $nufw_cmd .= " --dumpldap ".$rules_dir."/".$nupyf_ldap_file;
        $nufw_cmd .= " ".$desc_file;
        $nufw_cmd .= " ".$datadir."/".$file;
        if (!nupyf($nufw_cmd))
            return false;
    }

    //generate rescue rules
    $nupyf_args = gen_nupyf_args($std_rules_dir, 'dispatch_targets.tmp', 'default_estrel_invalid.tmp', 'dispatch_rules.tmp', 'forward_rules.tmp', $input_rules, $output_rules, $nat_rules, true, $mangle_rules);
    $nupyf_args.= " --sortid $used_desc";
    $nupyf_cmd = $nupyf_command.$nupyf_args." $desc_file $datadir/$file";
    if (!nupyf($nupyf_cmd))
        return false;
    return true;
}

function nupyf($command)
{
    global $debug_nuface;
    $stdout = report_execute($command, $exit_code);
    if ($exit_code!=0)
    {
        /* display specific error messages */
        log_error(_('Error of nupyf program:'));
        add_log_pre($stdout);
        return false;
    } else if ($debug_nuface and $stdout) {
        add_log(_('Output of nupyf program:'));
        add_log_pre($stdout);
    }
    return true;
}

function remove_layer7_rules()
{
    global $rules_dir;

    $l7_rules = $rules_dir."/".'l7_rules';
    if (file_exists($l7_rules) and (!unlink($l7_rules)))
    {
        add_log(sprintf(_('Warning: could not delete file "%s".'), $l7_rules));
    }

    $l7_rules_tmp = $l7_rules.'.tmp';
    if (file_exists($l7_rules_tmp) and (!unlink($l7_rules_tmp)))
    {
        add_log(sprintf(_('Warning: could not delete file "%s".'), $l7_rules_tmp));
    }

    return $l7_rules_tmp;
}

function execute_nulayer7($file, $output_filename)
{
    global $l7_command, $datadir;

    $l7_cmd = $l7_command." --output=$output_filename $datadir/$file";
    $l7_res = report_execute ($l7_cmd, $result0);
    if ($result0 != 0)
    {
        /* display specific error messages */
        log_error(_('Error of nulayer7 program:'));
        add_log_pre($l7_res);
        return false;
    }
    return true;
}

function execute_nuperiod($file)
{
    global $rules_dir, $datadir, $nuperiod_command;
    global $periods_file; # FIXME: Remove this global variable!

    /* run nuperiod to generate nuauth xml periods file */
    $periods_file = $rules_dir.'/periods.xml.tmp';
    $nuperiod_cmd = "$nuperiod_command -f $datadir/$file -o $periods_file";
    $nuperiod_res = report_execute($nuperiod_cmd, $result_periods);
    if ($result_periods != 0) {
        log_error(_('Error of nuperiod program:'));
        add_log_pre($nuperiod_res);
        return false;
    }
    return true;
}

function rename_firewall_files()
{
    global $rules_dir, $nufw_rules_dir, $std_rules_dir, $support_duplication;

    rename_if_exists("$rules_dir/l7_rules.tmp","$rules_dir/l7_rules");
    foreach(array($nufw_rules_dir,$std_rules_dir) as $the_dir){
        rename_if_exists("$the_dir/nat_rules.tmp","$the_dir/nat_rules");
        rename_if_exists("$the_dir/dispatch_targets.tmp","$the_dir/dispatch_targets");
        rename_if_exists("$the_dir/default_estrel_invalid.tmp","$the_dir/default_estrel_invalid");
        rename_if_exists("$the_dir/dispatch_rules.tmp","$the_dir/dispatch_rules");
        rename_if_exists("$the_dir/forward_rules.tmp","$the_dir/forward_rules");
        rename_if_exists("$the_dir/input_rules.tmp","$the_dir/input_rules");
        rename_if_exists("$the_dir/output_rules.tmp","$the_dir/output_rules");
        rename_if_exists("$the_dir/mangle_rules.tmp","$the_dir/mangle_rules");
    }
    rename_if_exists("$rules_dir/periods.xml.tmp","$rules_dir/periods.xml");
}

function apply_firewall_rules($ruleset, $with_nufw)
{
    global $nufw_firewall;
    global $rules_dir;
    global $sudo_command;
    global $firewall_script;
    global $sync_enabled;
    global $debug_nuface;

    if ($nufw_firewall and $with_nufw) {
        $farg = 'nufw';
    } else {
        $farg = 'nonufw';
    }

    if ($sync_enabled) {
        if( sync_firewall_rules($ruleset, $farg)) {
            add_log(sprintf(
                _('The firewall rules "%s" were successfully propagated.'),
                $ruleset->name));
        }else{
            log_error(sprintf(
                _('The firewall rules "%s" could not be propagated!'),
                $ruleset->name));
            add_log_pre($ret);
            return;
        }
    }

    $cmd = "$sudo_command $firewall_script $farg";
    if ($debug_nuface)
        $cmd .= ' --debug';
    $ret = report_execute($cmd,$result);

    if ($result!=0) {
        log_error(sprintf(
            _('The firewall rules "%s" could not be applied!'),
            $ruleset->name));
        add_log_pre($ret);
        return;
    }

    if ($nufw_firewall and !$with_nufw) {
        add_log(sprintf(
            _('The firewall rules "%s" (without NuFW authentication) were successfully applied.'),
            $ruleset->name));
    } else {
        add_log(sprintf(
            _('The firewall rules "%s" were successfully applied.'),
            $ruleset->name));
    }
}

function sync_firewall_rules($ruleset, $farg)
{
    global $rules_dir;
    global $sudo_command;
    global $sync_user;
    global $sync_script;
    global $sync_remote_rules_dir;
    global $sync_remote_sudo_command;
    global $sync_remote_firewall_script;
    global $sync_stop_apply_on_fail;
    global $sync_hosts;

    foreach ($sync_hosts as $index=>$host) {
        // Check host name
        $hostname = array_get($host, 'hostname');
        if (!$hostname) {
            log_error(sprintf(
                _('Hostname is not set in $host number %s!'),
                $index));
            if ($sync_stop_apply_on_fail)
                return false;
            else
                continue;
        }

        // Set default values
        $host = array_merge(Array(
            'user' => $sync_user,
            'remote_rules_dir' => $rules_dir,
            'remote_sudo_command' =>  $sudo_command,
            'remote_firewall_script' => $sync_remote_firewall_script,
        ), $host);

        // Create the command line
        $cmd = array_map('escapeshellarg', Array(
            $rules_dir,  $host['user'], $hostname,
            $host['remote_rules_dir'],
            $host['remote_sudo_command'],  $host['remote_firewall_script'],
            $farg
        ));
        $cmd = escapeshellcmd($sync_script).' '.implode(' ', $cmd);

        // Run remote command
        $stdout = report_execute($cmd, $result);
        if ($result != 0)
        {
            log_error(sprintf(
                _('The firewall rules "%s" on host "%s" could not be propagated!'),
                $ruleset->name, $hostname));
            add_log_pre($stdout);

            if ($sync_stop_apply_on_fail)
                return false;
            else
                continue;
        }

        add_log(sprintf(
            _('The firewall rules "%s" on host "%s" were successfully propagated.'),
            $ruleset->name, $hostname));
    }
    return true;
}

function firewall_rules($ruleset_filename)
{
    global $apply_firewall_rules;

    if (getHttp('save_ruleset') == 1)
    {
        // Load ruleset
        $ruleset = getSession('document');
        if (!$ruleset)
        {
            log_error(_("Unable to retrieve active ruleset! Your session may have expired."));
            return;
        }

        // Save ruleset
        $filename = basename($ruleset->filename);
        $result = write_ruleset_file($ruleset, $filename);
        if (!$result)
            return;
    }

    $with_nufw = getHttpCheckbox('with_nufw');
    $ruleset = generate_firewall_rules($ruleset_filename);
    if (!$ruleset) {
        return;
    }
    if ($apply_firewall_rules) {
        apply_firewall_rules($ruleset, $with_nufw);
    } else {
        log_error(_("Warning: Don't apply firewall rules (disabled in NuFace configuration)."));
    }
}

function copyUserXML($file)
{
    global $datadir;

    $basename = basename($file['name']);

    if (!check_filename($basename)) {
        log_error(sprintf(_('Invalid filename: "%s".'), $basename));
        return false;
    }

    $dest = $datadir . "/" . $basename;
    if (file_exists($dest)) {
        $name = filenameWithoutXml($basename);
        log_error (sprintf(_('Sorry, a ruleset called "%s" already exists.'), $name));
        return false;
    }

    $ok = @move_uploaded_file($file['tmp_name'], $dest);
    if (!$ok) {
        log_error(sprintf(_('Unable to copy uploaded file "%s"!'), $basename));
        return false;
    }
    return true;
}

function validateUserXML($file)
{
    if (basename($file['name'],'.xml') == $file['name'])
    {
        add_log(_('The file is not in an XML document!'));
        return false;
    }

    if ($file['type'] != '' && $file['type'] != 'text/xml')
    {
        add_log(_('The file is not in an XML document!'));
        return false;
    }

    try {
        $policy = new policy($file['tmp_name'], false, $file['name']);
    } catch (Exception $err) {
        log_exception($err);
        return false;
    }

    return true;
}

function uploadUserXML()
{
    global $tmpdir;

    $file = getFile('userfile');
    if (!$file) {
        // no file uploaded, just exit
        return;
    }

    if (validateUserXML($file)) {
        $ok = copyUserXML($file);
        if ($ok) {
            $name = basename($file['name']);
            $name = filenameWithoutXml($name);
            add_log(sprintf(_('The ruleset "%s" was correctly uploaded.'), $name));
        }
    }

    if(file_exists($file['tmp_name']))
        unlink($file['tmp_name']);
}

function loadNewRuleset()
{
    global $datadir;
    $filename = "$datadir/fixed/empty.xml";

    try {
        $policy = new policy($filename);
        $policy->name = sprintf("[%s]", _("template"));
        $policy->filename = null;
        handleLoadedDocument($policy);
    } catch (Exception $err) {
        $msg = sprintf(_("Unable to load ruleset file %s: %s"), $filename, $err->getMessage());
        log_error($msg, $err->getTrace());
    }
}

function loadUserXML($input)
{
    try {
        return _loadUserXML($input);
    } catch (Exception $err) {
        log_exception($err);
        return false;
    }
}

function _loadUserXML($input)
{
    if (!check_filename($input))
    {
        log_error(sprintf(_('Invalid filename: "%s".'), $input));
        return false;
    }

    $_SESSION['modified'] = 0;


    // read file includes checking on filename
    $document=read_ruleset_file($input);
    if (!$document)
    {
        log_error(sprintf(_('An error occured when reading the ruleset "%s"!'), filenameWithoutXml($input)));
        return false;
    }
    return handleLoadedDocument($document);
}

function handleLoadedDocument($document) {
    $descs= &$document->descs;

    $used_desc = find_build_desc($document);
    if (is_null($used_desc)) {
        return false;
    }

    $desc = $descs->elts[$used_desc];
    $bichains = build_bichains($desc);
    $bichains = populate_bichains_max($bichains, $document->acls);

    $resources=&$document->resources;
    check_objects_from_desc($resources, $desc);

    $_SESSION['used_desc']=$used_desc;
    sessionSaveRuleset($document);
    $_SESSION['bichains']=serialize($bichains);

    check_acls_order_scheme($document->acls);
    recompute_all_descsorts($document, $desc);

    // Let us check at least one group exists. If not, let us create it
    $groups = &$document->groups;
    if ((!isset($groups)) or ($groups->elts == array()))
    {
        $new_group = array();
        $new_group{'name'} = 'default';
        $new_group{'enabled'} = 1;
        $new_group{'comment'} = '';
        $group=new group($new_group,'data',$groups->new_id());
        $groups->add_elt($group);
    }

    if (! $document){
        display_openfile_menu();
    }else{
        sessionSaveRuleset($document);
	if ($document->name) {
	    add_log(sprintf(_('The ruleset "%s" was successfully loaded.'),
                $document->name));
	} else {
	     add_log(sprintf(_('The new ruleset was successfully created.')));
	}
    }
    if (complete_resources_from_desc($document,$used_desc))
    {
      saveRuleset($document);
    }
    return true;
}

function writeUserXML($output)
{
    global $datadir;

    $ruleset = getSession('document');
    if (!$ruleset) {
        return;
    }

    if (!$output) {
        if ($ruleset->filename) {
            $filename = basename($ruleset->filename);
        } else {
            $filename = 'ruleset.xml';
        }
        $GLOBALS['USE_EXIT_NUFACE'] = false;
        header('Content-type: binary/data');
        header('Content-Disposition: attachment; filename='.$filename);
        write_ruleset_file($ruleset, $output, false, false);
        exit(0);
    }else{
        if (!check_filename($output))
        {
            log_error(sprintf(_('Invalid filename: "%s".'), $output));
            return;
        }
        $name = filenameWithoutXml($output);
        $filename = "$datadir/$output";

        $save_copy = basename($ruleset->filename) != $output;
        if ($save_copy and file_exists($filename)) {
            log_error (sprintf(_('Sorry, the ruleset "%s" already exists.'), $name));
            return;
        }

	if (!$ruleset->filename) {
	    $ruleset->name = $name;
	    $ruleset->filename = $filename;
            sessionSaveRuleset($ruleset);
            $_SESSION['modified'] = 0;
	}

        write_ruleset_file($ruleset, $output, true, !$save_copy);
    }
}

function complete_resources_from_desc(&$document,$used_desc)
{
  $result = false;
  $resources = &$document->resources;
  $seen_nets = array();
  foreach($resources->elts as $resource)
  {
    foreach ($resource->elts as $sub)
    {
      if ((isset($sub->datas['type'])) and ($sub->datas['type'] == 'ipv4') and (isset($sub->datas['net'])))
      {
	array_push($seen_nets,$sub->datas['net']);
      }
    }
  }
  $descs = $document->descs;
  $desc = $descs->elts[$used_desc];
  $c_desc = clone($desc);
  $special_internet->datas['addr'] = "0.0.0.0/0";
  $special_internet->datas['name'] = "INTERNET";
  $special_internet->datas['dftroute'] = 0;
  array_push($c_desc->networks->elts, $special_internet);
  foreach ($c_desc->networks->elts as $desc_network)
  {
      if (!isset($desc_network->datas['addr']))
          continue;

      // Check if this network is already defined.
      $seen_this = 0;
      foreach($seen_nets as $already_net)
      {
          if (Net_IPv4::compare($already_net, $desc_network->datas['addr']))
          {
              $seen_this++;
              break;
          }
      }
      if ($seen_this != 0)
          continue;

      // Add the network
      try
      {
          $myres = array();
          $myres['name'] = $desc_network->datas['name'];
          if ($desc_network->datas['dftroute'] == 1)
          {
              $myres['name'] .= '_interco_'.$desc_network->datas['addr'];
          }
          $new_res = new resource($myres,'toto',$resources->get_max_id()+1);
          $myelt = array();
          $myelt['name']='ip';
          $myelt['net'] = $desc_network->datas['addr'];
          $myelt['type'] = 'ipv4';
          $new_elt = new elt($myelt,'toto',$resources->get_max_elt_id()+1);
          $new_res->add_elt($new_elt);
          $count = 1;
          $format = $new_res->name."-%s";
          do
          {
              $found = $resources->getByName($new_res->name);
              if ($found) {
                $count += 1;
                $new_res->name = sprintf($format, $count);
              }
          } while ($found);
          add_log(sprintf(_('Create the new resource "%s" (%s) from the network description.'),
            $new_res->name,
            $myelt['net']));
          $resources->add_elt($new_res);
          $result = true;
        } catch (Exception $err) {
            log_exception($err);
            $result = false;
        }
  }
  array_pop($c_desc->networks->elts);
  return($result);
}

?>