Esempio n. 1
0
list<int> Helper::getAllInterfaceIDs()
{
    Firewall *fw = compiler->fw;
    list<int> intf_id_list;
    FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME);
    for ( ; i!=i.end(); ++i)
    {
        Interface *ifs = Interface::cast(*i);
        assert(ifs);
        if (ifs->isUnprotected()) continue;   // skip!
        intf_id_list.push_back( (*i)->getId() );
    }
    return intf_id_list;
}
Esempio n. 2
0
void clusterMembersDialog::getPossibleMembers()
{
    t_fwList fwlist;

    mw->findAllFirewalls(fwlist);

    Firewall *fw;
    for (t_fwList::iterator it = fwlist.begin(); it != fwlist.end(); it++)
    {
        // does host_OS and platform match?
        fw = *it;
        if (fw->getStr("host_OS").c_str() != host_os ||
            fw->getStr("platform").c_str() != platform)
        {
            continue;
        }

        // does the firewall provide at least one phys. interface?
        FWObjectTypedChildIterator iface_i = fw->findByType(Interface::TYPENAME);
        if (iface_i == iface_i.end())
        {
            continue;
        }
        else
        {
            // previously selected? skip
            PredFindFw pred;
            pred.setSearchString(fw->getName().c_str());
            t_memberList::iterator it = find_if(selected.begin(),
                                                selected.end(), pred);
            if (it != selected.end())
            {
                continue;
            }

            // valid member, add to member list
            ClusterMember *new_member = createMember(fw);
            if (new_member == NULL)
            {
                qWarning() << "clusterMembersDialog: could not create new "
                    "cluster member";
                return;
            }
            available.push_back(new_member);
        }
    }
    fwlist.sort(FWObjectNameCmpPredicate());
}
Esempio n. 3
0
File: main.cpp Progetto: anrs/mesos
int main(int argc, char** argv)
{
  // The order of initialization of various master components is as follows:
  // * Validate flags.
  // * Log build information.
  // * Libprocess.
  // * Logging.
  // * Version process.
  // * Firewall rules: should be initialized before initializing HTTP endpoints.
  // * Modules: Load module libraries and manifests before they
  //   can be instantiated.
  // * Anonymous modules: Later components such as Allocators, and master
  //   contender/detector might depend upon anonymous modules.
  // * Hooks.
  // * Allocator.
  // * Registry storage.
  // * State.
  // * Master contendor.
  // * Master detector.
  // * Authorizer.
  // * Slave removal rate limiter.
  // * `Master` process.
  //
  // TODO(avinash): Add more comments discussing the rationale behind for this
  // particular component ordering.

  GOOGLE_PROTOBUF_VERIFY_VERSION;

  master::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip,
            "ip",
            "IP address to listen on. This cannot be used in conjunction\n"
            "with `--ip_discovery_command`.");

  uint16_t port;
  flags.add(&port,
            "port",
            "Port to listen on.",
            MasterInfo().port());

  Option<string> advertise_ip;
  flags.add(&advertise_ip,
            "advertise_ip",
            "IP address advertised to reach this Mesos master.\n"
            "The master does not bind using this IP address.\n"
            "However, this IP address may be used to access this master.");

  Option<string> advertise_port;
  flags.add(&advertise_port,
            "advertise_port",
            "Port advertised to reach Mesos master (along with\n"
            "`advertise_ip`). The master does not bind to this port.\n"
            "However, this port (along with `advertise_ip`) may be used to\n"
            "access this master.");

  Option<string> zk;
  flags.add(&zk,
            "zk",
            "ZooKeeper URL (used for leader election amongst masters)\n"
            "May be one of:\n"
            "  `zk://host1:port1,host2:port2,.../path`\n"
            "  `zk://username:password@host1:port1,host2:port2,.../path`\n"
            "  `file:///path/to/file` (where file contains one of the above)\n"
            "NOTE: Not required if master is run in standalone mode (non-HA).");

  // Optional IP discover script that will set the Master IP.
  // If set, its output is expected to be a valid parseable IP string.
  Option<string> ip_discovery_command;
  flags.add(&ip_discovery_command,
            "ip_discovery_command",
            "Optional IP discovery binary: if set, it is expected to emit\n"
            "the IP address which the master will try to bind to.\n"
            "Cannot be used in conjunction with `--ip`.");

  Try<flags::Warnings> load = flags.load("MESOS_", argc, argv);

  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.version) {
    cout << "mesos" << " " << MESOS_VERSION << endl;
    return EXIT_SUCCESS;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  if (ip_discovery_command.isSome() && ip.isSome()) {
    EXIT(EXIT_FAILURE) << flags.usage(
        "Only one of `--ip` or `--ip_discovery_command` should be specified");
  }

  if (ip_discovery_command.isSome()) {
    Try<string> ipAddress = os::shell(ip_discovery_command.get());

    if (ipAddress.isError()) {
      EXIT(EXIT_FAILURE) << ipAddress.error();
    }

    os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get()));
  } else if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  if (advertise_ip.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get());
  }

  if (advertise_port.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get());
  }

  if (zk.isNone()) {
    if (flags.master_contender.isSome() ^ flags.master_detector.isSome()) {
      EXIT(EXIT_FAILURE)
        << flags.usage("Both --master_contender and --master_detector should "
                       "be specified or omitted.");
    }
  } else {
    if (flags.master_contender.isSome() || flags.master_detector.isSome()) {
      EXIT(EXIT_FAILURE)
        << flags.usage("Only one of --zk or the "
                       "--master_contender/--master_detector "
                       "pair should be specified.");
    }
  }

  // Log build information.
  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;
  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  // This should be the first invocation of `process::initialize`. If it returns
  // `false`, then it has already been called, which means that the
  // authentication realm for libprocess-level HTTP endpoints was not set to the
  // correct value for the master.
  if (!process::initialize(
          "master",
          READWRITE_HTTP_AUTHENTICATION_REALM,
          READONLY_HTTP_AUTHENTICATION_REALM)) {
    EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the master's "
                       << "`main()` was not the function's first invocation";
  }

  logging::initialize(argv[0], flags, true); // Catch signals.

  // Log any flag warnings (after logging is initialized).
  foreach (const flags::Warning& warning, load->warnings) {
    LOG(WARNING) << warning.message;
  }

  spawn(new VersionProcess(), true);

  // Initialize firewall rules.
  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
Esempio n. 4
0
int main(int argc, char** argv)
{
  // The order of initialization is as follows:
  // * Windows socket stack.
  // * Validate flags.
  // * Log build information.
  // * Libprocess
  // * Logging
  // * Version process
  // * Firewall rules: should be initialized before initializing HTTP endpoints.
  // * Modules: Load module libraries and manifests before they
  //   can be instantiated.
  // * Anonymous modules: Later components such as Allocators, and master
  //   contender/detector might depend upon anonymous modules.
  // * Hooks.
  // * Systemd support (if it exists).
  // * Fetcher and Containerizer.
  // * Master detector.
  // * Authorizer.
  // * Garbage collector.
  // * Status update manager.
  // * Resource estimator.
  // * QoS controller.
  // * `Agent` process.
  //
  // TODO(avinash): Add more comments discussing the rationale behind for this
  // particular component ordering.

#ifdef __WINDOWS__
  // Initialize the Windows socket stack.
  process::Winsock winsock;
#endif

  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::Flags flags;

  Try<flags::Warnings> load = flags.load("MESOS_", argc, argv);

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  if (flags.version) {
    cout << "mesos" << " " << MESOS_VERSION << endl;
    return EXIT_SUCCESS;
  }

  // TODO(marco): this pattern too should be abstracted away
  // in FlagsBase; I have seen it at least 15 times.
  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.master.isNone() && flags.master_detector.isNone()) {
    cerr << flags.usage("Missing required option `--master` or "
                        "`--master_detector`.") << endl;
    return EXIT_FAILURE;
  }

  if (flags.master.isSome() && flags.master_detector.isSome()) {
    cerr << flags.usage("Only one of --master or --master_detector options "
                        "should be specified.");
    return EXIT_FAILURE;
  }

  // Initialize libprocess.
  if (flags.ip_discovery_command.isSome() && flags.ip.isSome()) {
    EXIT(EXIT_FAILURE) << flags.usage(
        "Only one of `--ip` or `--ip_discovery_command` should be specified");
  }

  if (flags.ip_discovery_command.isSome()) {
    Try<string> ipAddress = os::shell(flags.ip_discovery_command.get());

    if (ipAddress.isError()) {
      EXIT(EXIT_FAILURE) << ipAddress.error();
    }

    os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get()));
  } else if (flags.ip.isSome()) {
    os::setenv("LIBPROCESS_IP", flags.ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(flags.port));

  if (flags.advertise_ip.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_IP", flags.advertise_ip.get());
  }

  if (flags.advertise_port.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_PORT", flags.advertise_port.get());
  }

  // Log build information.
  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;
  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  const string id = process::ID::generate("slave"); // Process ID.

  // If `process::initialize()` returns `false`, then it was called before this
  // invocation, meaning the authentication realm for libprocess-level HTTP
  // endpoints was set incorrectly. This should be the first invocation.
  if (!process::initialize(
          id,
          READWRITE_HTTP_AUTHENTICATION_REALM,
          READONLY_HTTP_AUTHENTICATION_REALM)) {
    EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's "
                       << "`main()` was not the function's first invocation";
  }

  logging::initialize(argv[0], flags, true); // Catch signals.

  // Log any flag warnings (after logging is initialized).
  foreach (const flags::Warning& warning, load->warnings) {
    LOG(WARNING) << warning.message;
  }

  spawn(new VersionProcess(), true);

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
Esempio n. 5
0
int main(int argc, char** argv)
{
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  slave::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip, "ip", "IP address to listen on");

  uint16_t port;
  flags.add(&port, "port", "Port to listen on", SlaveInfo().port());

  Option<string> master;
  flags.add(&master,
            "master",
            "May be one of:\n"
            "  zk://host1:port1,host2:port2,.../path\n"
            "  zk://username:password@host1:port1,host2:port2,.../path\n"
            "  file:///path/to/file (where file contains one of the above)");

  Try<Nothing> load = flags.load("MESOS_", argc, argv);

  // TODO(marco): this pattern too should be abstracted away
  // in FlagsBase; I have seen it at least 15 times.
  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  if (flags.version) {
    version();
    return EXIT_SUCCESS;
  }

  if (master.isNone()) {
    cerr << flags.usage("Missing required option --master") << endl;
    return EXIT_FAILURE;
  }

  // Initialize modules. Note that since other subsystems may depend
  // upon modules, we should initialize modules before anything else.
  if (flags.modules.isSome()) {
    Try<Nothing> result = ModuleManager::load(flags.modules.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
    }
  }

  // Initialize hooks.
  if (flags.hooks.isSome()) {
    Try<Nothing> result = HookManager::initialize(flags.hooks.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
    }
  }

  // Initialize libprocess.
  if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  process::initialize("slave(1)");

  logging::initialize(argv[0], flags, true); // Catch signals.

  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;

  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  Fetcher fetcher;

  Try<Containerizer*> containerizer =
    Containerizer::create(flags, false, &fetcher);

  if (containerizer.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a containerizer: " << containerizer.error();
  }

  Try<MasterDetector*> detector = MasterDetector::create(master.get());

  if (detector.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master detector: " << detector.error();
  }

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
QString CompilerDriver_pix::run(const std::string &cluster_id,
                                const std::string &firewall_id,
                                const std::string &single_rule_id)
{
    Cluster *cluster = NULL;
    Firewall *fw = NULL;

    getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw);

    // Copy rules from the cluster object
    populateClusterElements(cluster, fw);

    if (cluster)
    {
        // PIX failover is dfferent from VRRP and other failover protocols
        // in that it does not create new virtual address. Instead, each
        // unit is configured with two ip addresses, one for the active
        // unit and another for standby one. When active unit fails, the
        // other one assumes its address.
        //
        // This matters because when we use cluster object or one of its
        // interfaces in rules, compiler should expand it to the set of
        // addresses that includes addresses of the corresponding
        // interface of both member firewalls. Method
        // CompilerDriver::copyFailoverInterface adds a copy of firewall
        // interface to the cluster object. This works for all firewalls,
        // but for PIX we need to add copies of interfaces from both
        // members.
        // 
        FWObjectTypedChildIterator cl_iface = cluster->findByType(Interface::TYPENAME);
        for (; cl_iface != cl_iface.end(); ++cl_iface)
        {
            FailoverClusterGroup *failover_group =
                FailoverClusterGroup::cast(
                    (*cl_iface)->getFirstByType(FailoverClusterGroup::TYPENAME));
            if (failover_group)
            {
                //FWObject *this_member_interface = NULL; //UNUSED
                list<FWObject*> other_member_interfaces;
                for (FWObjectTypedChildIterator it =
                         failover_group->findByType(FWObjectReference::TYPENAME);
                     it != it.end(); ++it)
                {
                    FWObject *intf = FWObjectReference::getObject(*it);
                    assert(intf);
                    //if (intf->isChildOf(fw)) this_member_interface = intf; //UNUSED
                    //else other_member_interfaces.push_back(intf);
                    if (!intf->isChildOf(fw)) other_member_interfaces.push_back(intf);
                }

                if (!other_member_interfaces.empty())
                {
                    for (list<FWObject*>::iterator it=other_member_interfaces.begin();
                         it!=other_member_interfaces.end(); ++it)
                    {
                        cluster->addCopyOf(*it, true);
                    }
                }
            }
        }
    }

#if 0
    FWObjectTypedChildIterator iface = fw->findByType(Interface::TYPENAME);
    for (; iface != iface.end(); ++iface)
    {
        (*iface)->dump(true, true);
    }
#endif


    determineOutputFileNames(cluster, fw, !cluster_id.empty(),
                             QStringList(""), QStringList("fw"),
                             QStringList(""));

    FWOptions* options = fw->getOptionsObject();

    QString script_buffer;

    std::auto_ptr<NATCompiler_pix> n;
    std::auto_ptr<PolicyCompiler_pix> c;
    std::auto_ptr<RoutingCompiler_pix> r;


    try
    {
        clearReadOnly(fw);

        commonChecks2(cluster, fw);

        pixClusterConfigurationChecks(cluster, fw);

        // Note that fwobjectname may be different from the name of the
        // firewall fw This happens when we compile a member of a cluster
        current_firewall_name = fw->getName().c_str();

        bool pix_acl_basic = options->getBool("pix_acl_basic");
        bool pix_acl_no_clear = options->getBool("pix_acl_no_clear");
        bool pix_acl_substitution = options->getBool("pix_acl_substitution");
        bool pix_add_clear_statements = options->getBool("pix_add_clear_statements");

        if (!pix_acl_basic && !pix_acl_no_clear && !pix_acl_substitution)
        {
            if ( pix_add_clear_statements ) options->setBool("pix_acl_basic",true);
            else options->setBool("pix_acl_no_clear",true);
        }



        list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);

        pixSecurityLevelChecks(fw, all_interfaces);
        pixNetworkZoneChecks(fw, all_interfaces);

        /* Now that all checks are done, we can drop copies of cluster
         * interfaces that were added to the firewall by
         * CompilerDriver::populateClusterElements()
         */
        list<FWObject*> copies_of_cluster_interfaces;
        for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
        {
            Interface *iface = Interface::cast(*i);
            assert(iface);

            if (iface->getOptionsObject()->getBool("cluster_interface"))
                copies_of_cluster_interfaces.push_back(iface);
        }
        while (copies_of_cluster_interfaces.size())
        {
            fw->remove(copies_of_cluster_interfaces.front());
            copies_of_cluster_interfaces.pop_front();
        }

        NamedObjectsManagerPIX named_objects_manager(persistent_objects, fw);

        all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);

        for (std::list<FWObject*>::iterator i=all_interfaces.begin();
             i!=all_interfaces.end(); ++i)
        {
            Interface *iface = Interface::cast(*i);
            assert(iface);
/*
 * missing labels on interfaces
 *
 */
            if (iface->getLabel()=="")
            {
                string lbl;
                if (iface->isDedicatedFailover()) 
                {
                    // dedicated failover interface misses label. This
                    // interface can be used in failover cluster group
                    // or state sync group. Assign label depending on
                    // the function.
                    FWObjectTypedChildIterator it =
                        cluster->findByType(StateSyncClusterGroup::TYPENAME);
                    StateSyncClusterGroup *state_sync_group =
                        StateSyncClusterGroup::cast(*it);
                    if (state_sync_group && state_sync_group->hasMember(iface))
                        lbl = "state";

                    if (!iface->getOptionsObject()->getStr("failover_group_id").empty())
                        lbl = "failover";
                }

                if (lbl.empty())
                {
                    if (iface->getSecurityLevel()==0)   lbl="outside";
                    else
                    {
                        if (iface->getSecurityLevel()==100) lbl="inside";
                        else
                        {
                            QString l("dmz%1");
                            lbl = l.arg(iface->getSecurityLevel()).toStdString();
                        }
                    }
                }
                iface->setLabel(lbl);
            }



        }
        /*
         *  now sort interfaces by their network zone "width" (that
         *  is, more narrow network zone should go first, interface
         *  with network zone "any" should be the last)
         *
         std::sort(fw->begin(), fw->end(), sort_by_net_zone() );
        */


        try
        {
            AutomaticRules_cisco auto_rules(fw, persistent_objects);
            auto_rules.addSshAccessRule();
        } catch (FWException &ex)
        {
            abort(ex.toString());
        }

        std::auto_ptr<Preprocessor> prep(
            new Preprocessor(objdb , fw, false));
        if (inTestMode()) prep->setTestMode();
        if (inEmbeddedMode()) prep->setEmbeddedMode();
        prep->compile();

        std::auto_ptr<OSConfigurator> oscnf(
            new OSConfigurator_pix_os(objdb , fw, false));
        if (inTestMode()) oscnf->setTestMode();
        if (inEmbeddedMode()) oscnf->setEmbeddedMode();

        oscnf->prolog();
        oscnf->processFirewallOptions();

        bool have_named_objects = false;
        bool have_object_groups = false;

/* create compilers and run the whole thing */
        string version = fw->getStr("version");

        if (XMLTools::version_compare(version, "8.3")>=0)
            n = std::auto_ptr<NATCompiler_pix>(
                new NATCompiler_asa8(objdb, fw, false, oscnf.get()));
        else
            n = std::auto_ptr<NATCompiler_pix>(
                new NATCompiler_pix(objdb, fw, false, oscnf.get()));

        RuleSet *nat = RuleSet::cast(fw->getFirstByType(NAT::TYPENAME));
        if (nat)
        {
            nat->assignUniqueRuleIds();

            n->setNamedObjectsManager(&named_objects_manager);
            n->setSourceRuleSet(nat);
            n->setRuleSetName(nat->getName());
            n->setPersistentObjects(persistent_objects);

            if (inTestMode()) n->setTestMode();
            if (inEmbeddedMode()) n->setEmbeddedMode();
            n->setSingleRuleCompileMode(single_rule_id);
            n->setDebugLevel( dl );
            if (rule_debug_on) n->setDebugRule(  drn );
            n->setVerbose( verbose );

            if ( n->prolog() > 0 )
            {
                n->compile();
                n->epilog();

                preamble_commands += n->printPreambleCommands();
                clear_commands += n->printClearCommands();
                have_named_objects = (have_named_objects ||
                                      named_objects_manager.haveNamedObjects());
                have_object_groups = (have_object_groups ||
                                      named_objects_manager.haveObjectGroups());
                //named_objects_manager.saveObjectGroups();
            } else
                info(" Nothing to compile in NAT");
        }

        c = std::auto_ptr<PolicyCompiler_pix>(
            new PolicyCompiler_pix(objdb, fw, false, oscnf.get() , n.get()));

        RuleSet *policy = RuleSet::cast(fw->getFirstByType(Policy::TYPENAME));
        if (policy)
        {
            policy->assignUniqueRuleIds();

            c->setNamedObjectsManager(&named_objects_manager);
            c->setSourceRuleSet(policy);
            c->setRuleSetName(policy->getName());
            c->setPersistentObjects(persistent_objects);

            if (inTestMode()) c->setTestMode();
            if (inEmbeddedMode()) c->setEmbeddedMode();
            c->setSingleRuleCompileMode(single_rule_id);
            c->setDebugLevel( dl );
            if (rule_debug_on) c->setDebugRule(  drp );
            c->setVerbose( verbose );

            if ( c->prolog() > 0 )
            {
                c->compile();
                c->epilog();

                preamble_commands += c->printPreambleCommands();
                clear_commands += c->printClearCommands();
                have_named_objects = (have_named_objects ||
                                      named_objects_manager.haveNamedObjects());
                have_object_groups = (have_object_groups ||
                                      named_objects_manager.haveObjectGroups());
                //named_objects_manager.saveObjectGroups();
            } else
                info(" Nothing to compile in Policy");
        }

        r = std::auto_ptr<RoutingCompiler_pix>(
            new RoutingCompiler_pix(objdb, fw, false, oscnf.get()));

        RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME));
        if (routing)
        {
            routing->assignUniqueRuleIds();

            r->setNamedObjectsManager(&named_objects_manager);
            r->setSourceRuleSet(routing);
            r->setRuleSetName(routing->getName());
            r->setPersistentObjects(persistent_objects);
                
            if (inTestMode()) r->setTestMode();
            if (inEmbeddedMode()) r->setEmbeddedMode();
            r->setSingleRuleCompileMode(single_rule_id);
            r->setDebugLevel( dl );
            if (rule_debug_on) r->setDebugRule(  drp );
            r->setVerbose( verbose );

            if ( r->prolog() > 0 )
            {
                r->compile();
                r->epilog();
            } else
                info(" Nothing to compile in Routing");
        }

        /*
         * compilers detach persistent objects when they finish, this
         * means at this point library persistent_objects is not part
         * of any object tree.
         */
        objdb->reparent(persistent_objects);

        if (haveErrorsAndWarnings())
        {
            all_errors.push_front(getErrors("").c_str());
        }

        policy_script = c->getCompiledScript();
        nat_script = n->getCompiledScript();
        routing_script = r->getCompiledScript();

        named_objects_and_groups = named_objects_manager.getNamedObjectsDefinitions();

        if (c->haveErrorsAndWarnings())
            all_errors.push_back(c->getErrors("C ").c_str());
        if (n->haveErrorsAndWarnings())
            all_errors.push_back(n->getErrors("N ").c_str());
        if (r->haveErrorsAndWarnings())
            all_errors.push_back(r->getErrors("R ").c_str());

        if (single_rule_compile_on)
        {
            return formSingleRuleCompileOutput(
                QString::fromUtf8(
                    (named_objects_and_groups +
                     policy_script + nat_script + routing_script).c_str()));
        }

        system_configuration_script = oscnf->getCompiledScript();
        system_configuration_script += "\n";

        clear_commands += named_objects_manager.getClearCommands() + "\n";

        // system_configuration_script += preamble_commands;
        // system_configuration_script += clear_commands;


        script_buffer = assembleFwScript(
            cluster, fw, !cluster_id.empty(), oscnf.get());

        QString ofname = getAbsOutputFileName(file_names[FW_FILE]);

        info("Output file name: " + ofname.toStdString());
        QFile fw_file(ofname);
        if (fw_file.open(QIODevice::WriteOnly))
        {
            QTextStream fw_str(&fw_file);
            fw_str << script_buffer;
            fw_file.close();
            fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
                                   QFile::ReadGroup | QFile::ReadOther |
                                   QFile::ExeOwner | 
                                   QFile::ExeGroup |
                                   QFile::ExeOther );

            info(" Compiled successfully");
        } else
        {
            QString err(" Failed to open file %1 for writing: %2; Current dir: %3");
            abort(err.arg(fw_file.fileName())
                  .arg(fw_file.error()).arg(QDir::current().path()).toStdString());
        }

        if (!all_errors.isEmpty())
            status = BaseCompiler::FWCOMPILER_WARNING;

    }
    catch (FWException &ex)
    {
        status = BaseCompiler::FWCOMPILER_ERROR;
        return QString::fromUtf8(ex.toString().c_str());
    }

    return "";
}
QString CompilerDriver_junosacl::run(const string &cluster_id,
                                     const string &firewall_id,
                                     const string &single_rule_id)
{
    Cluster *cluster = NULL;
    Firewall *fw = NULL;

    getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw);

    try
    {
        clearReadOnly(fw);

        // Copy rules from the cluster object
        populateClusterElements(cluster, fw);

        commonChecks2(cluster, fw);

        // Note that fwobjectname may be different from the name of the
        // firewall fw This happens when we compile a member of a cluster
        current_firewall_name = fw->getName().c_str();

        determineOutputFileNames(cluster, fw, !cluster_id.empty(),
                                 QStringList(""), QStringList("fw"),
                                 QStringList(""));

        /* Now that all checks are done, we can drop copies of cluster
         * interfaces that were added to the firewall by
         * CompilerDriver::populateClusterElements()
         */
        list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
        list<FWObject*> copies_of_cluster_interfaces;
        for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
        {
            Interface *iface = Interface::cast(*i);
            assert(iface);

            if (iface->getOptionsObject()->getBool("cluster_interface"))
                copies_of_cluster_interfaces.push_back(iface);
        }
        while (copies_of_cluster_interfaces.size())
        {
            fw->remove(copies_of_cluster_interfaces.front());
            copies_of_cluster_interfaces.pop_front();
        }

        FWOptions* options = fw->getOptionsObject();

        string fwvers = fw->getStr("version");
        if (fwvers == "") fw->setStr("version", "11.2");
        if (fwvers == "11.x") fw->setStr("version", "11.2");

        string platform = fw->getStr("platform");

        std::auto_ptr<OSConfigurator_junos> oscnf(new OSConfigurator_junos(objdb, fw, false));

        oscnf->prolog();
        oscnf->processFirewallOptions();

        list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);

        // assign unique rule ids that later will be used to generate
        // chain names.  This should be done after calls to
        // findImportedRuleSets()
        // NB: these ids are not used by this compiler

        assignUniqueRuleIds(all_policies);

        vector<int> ipv4_6_runs;

        // // // // //NamedObjectsManager named_objects_manager(persistent_objects, fw);

        // command line options -4 and -6 control address family for which
        // script will be generated. If "-4" is used, only ipv4 part will
        // be generated. If "-6" is used, only ipv6 part will be generated.
        // If neither is used, both parts will be done.

        if (options->getStr("ipv4_6_order").empty() ||
            options->getStr("ipv4_6_order") == "ipv4_first")
        {
            if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
            if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
        }

        if (options->getStr("ipv4_6_order") == "ipv6_first")
        {
            if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
            if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
        }

        string object_groups_definitions;

        for (vector<int>::iterator i=ipv4_6_runs.begin();
             i!=ipv4_6_runs.end(); ++i)
        {
            int policy_af = *i;
            bool ipv6_policy = (policy_af == AF_INET6);

            // Count rules for each address family
            int policy_count = 0;

            for (list<FWObject*>::iterator p=all_policies.begin();
                 p!=all_policies.end(); ++p)
            {
                Policy *policy = Policy::cast(*p);
                if (policy->matchingAddressFamily(policy_af)) policy_count++;
            }
            if (policy_count)
            {
                std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb, fw, false));
                if (inTestMode()) prep->setTestMode();
                if (inEmbeddedMode()) prep->setEmbeddedMode();
                prep->compile();
            }

            for (list<FWObject*>::iterator p=all_policies.begin();
                 p!=all_policies.end(); ++p)
            {
                Policy *policy = Policy::cast(*p);

                if (!policy->matchingAddressFamily(policy_af)) continue;

                PolicyCompiler_junosacl c(objdb, fw, ipv6_policy, oscnf.get());

                // // // // //c.setNamedObjectsManager(&named_objects_manager);
                c.setSourceRuleSet( policy );
                c.setRuleSetName(policy->getName());
                c.setPersistentObjects(persistent_objects);

                c.setSingleRuleCompileMode(single_rule_id);
                if (inTestMode()) c.setTestMode();
                if (inEmbeddedMode()) c.setEmbeddedMode();
                c.setDebugLevel( dl );
                if (rule_debug_on) c.setDebugRule( drp );
                c.setVerbose( verbose );

                if ( c.prolog() > 0)
                {
                    c.compile();
                    c.epilog();

                    if (!single_rule_compile_on)
                    {
                        if (ipv6_policy)
                        {
                            policy_script += "\n\n";
                            policy_script += "# ================ IPv6\n";
                            policy_script += "\n\n";
                        } else {
                            policy_script += "\n\n";
                            policy_script += "# ================ IPv4\n";
                            policy_script += "\n\n";
                        }
                    }

                    if (c.haveErrorsAndWarnings())
                    {
                        all_errors.push_back(c.getErrors("").c_str());
                    }
                    policy_script += c.getCompiledScript();
                } else {
                    info(" Nothing to compile in Policy");
                }
            }
        }

        /*
             * compilers detach persistent objects when they finish, this
             * means at this point library persistent_objects is not part
             * of any object tree.
             */

        objdb->reparent(persistent_objects);

        if (haveErrorsAndWarnings())
        {
            all_errors.push_front(getErrors("").c_str());
        }

        // // // // //object_groups_definitions +=
        // // // // //        named_objects_manager.getNamedObjectsDefinitions();

        if (single_rule_compile_on)
        {
            return formSingleRuleCompileOutput(
                        QString::fromUtf8(
                            (object_groups_definitions +
                             policy_script).c_str()));
        }

        system_configuration_script += object_groups_definitions;

        QString script_buffer = assembleFwScript(
                    cluster, fw, !cluster_id.empty(), oscnf.get());

        QString ofname = getAbsOutputFileName(file_names[FW_FILE]);

        info("Output file name: " + ofname.toStdString());
        QFile fw_file(ofname);
        if (fw_file.open(QIODevice::WriteOnly))
        {
            QTextStream fw_str(&fw_file);
            fw_str << script_buffer;
            fw_file.close();
            fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
                                   QFile::ReadGroup | QFile::ReadOther |
                                   QFile::ExeOwner |
                                   QFile::ExeGroup |
                                   QFile::ExeOther );
            info(" Compiled successfully");
        } else {
            QString err(" Failed to open file %1 for writing: %2; Current dir: %3");
            abort(err.arg(fw_file.fileName())
                  .arg(fw_file.error()).arg(QDir::current().path()).toStdString());
        }

        if (!all_errors.isEmpty())
            status = BaseCompiler::FWCOMPILER_WARNING;

    }
    catch (FWException &ex)
    {
        status = BaseCompiler::FWCOMPILER_ERROR;
        return QString::fromUtf8((ex.toString().c_str()));
    }

    return "";
}
Esempio n. 8
0
void instDialog::fillCompileSelectList()
{
    if (fwbdebug) qDebug("instDialog::fillCompileSelectList");

    Firewall *fw;
    Cluster *cl;
    QDateTime dt;

    creatingTable = true;
    m_dialog->selectTable->clear();

    list<Firewall*> working_list_of_firewalls = firewalls;

    for (list<Cluster *>::iterator i=clusters.begin(); i!=clusters.end(); ++i)
    {
        cl = *i;

        QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl);
        m_dialog->selectTable->addTopLevelItem(cluster_item);

        list<Firewall*> members;
        cl->getMembersList(members);

        for (list<Firewall*>::iterator member=members.begin();
             member!=members.end(); ++member)
        {
            createTreeItem(cluster_item, *member);
            working_list_of_firewalls.remove(*member);
        }
        cluster_item->setExpanded(true);
    }

    for (list<Firewall *>::iterator i=working_list_of_firewalls.begin();
         i!=working_list_of_firewalls.end(); ++i)
    {
        fw = *i;
        QTreeWidgetItem* fw_item = createTreeItem(NULL, fw);
        m_dialog->selectTable->addTopLevelItem(fw_item);
    }

    QTreeWidgetItemIterator it(m_dialog->selectTable);
    while (*it)
    {
        setFlags(*it);
        ++it;
    }


    /* ticket #1305
     * check if any of the firewall objects are members of clusters but
     * the clusters are not requested for compile
     */

    QString warn1(
        tr("<b>You are trying to compile policy for a firewall object that is "
           "a member of a cluster, however you requested compilation of only "
           "this member firewall and not the cluster it belongs to. Assuming "
           "firewall is standalone and not cluster member. Rules and parts of "
           "the script specific for the cluster configuration will not be "
           "generated.</b>"));

    QStringList warn2;

    list<FWObject*> all_libs = project->db()->getByType(Library::TYPENAME);
    foreach(FWObject *lib, all_libs)
    {
        if (lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) continue;
        list<FWObject*> all_clusters = lib->getByTypeDeep(Cluster::TYPENAME);
        foreach(FWObject *_cl, all_clusters)
        {
            if (std::find(clusters.begin(), clusters.end(), _cl) == clusters.end())
            {
                Cluster *cluster = Cluster::cast(_cl);
                assert(cluster);
                foreach(FWObject *fw, firewalls)
                {
                    if (cluster->hasMember(Firewall::cast(fw)))
                    {
                        warn2 <<
                            QString(tr("Firewall '%1' is member of cluster '%2'")
                                    .arg(QString::fromUtf8(fw->getName().c_str()))
                                    .arg(QString::fromUtf8(cluster->getPath().c_str())));
                    }
                }
            }
        }
    }
Esempio n. 9
0
void FirewallDialog::applyChanges()
{
    if (fwbdebug)
        qDebug() << "FirewallDialog::applyChanges()";

    bool autorename_chidren = false;
    QString dialog_txt = tr(
        "The name of the object '%1' has changed. The program can also "
        "rename IP address objects that belong to this object, "
        "using standard naming scheme 'host_name:interface_name:ip'. "
        "This makes it easier to distinguish what host or a firewall "
        "given IP address object belongs to when it is used in "
        "the policy or NAT rule. The program also renames MAC address "
        "objects using scheme 'host_name:interface_name:mac'. "
        "Do you want to rename child IP and MAC address objects now? "
        "(If you click 'No', names of all address objects that belong to "
        "%2 will stay the same.)")
        .arg(QString::fromUtf8(obj->getName().c_str()))
        .arg(QString::fromUtf8(obj->getName().c_str()));

    if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData())
    {
        /*
         * when we open this warning dialog, FirewallDialog class
         * loses focus and obj_name lineEdit widget sends signal
         * "editingfinished" again.  To the user this looks like the
         * warning dialog popped up twice (in fact two copies of the
         * same warning dialog appear at the same time, one exactly on
         * top of another). To avoid this, block signals for the
         * duration while we show the dialog. Note that documentation
         * does not mention that QObject::blockSignals() affects not
         * only the widget but all its children, but it seems to work
         * that way. Tested with Qt 4.6.1. See #1171
         */
        blockSignals(true);
        autorename_chidren = (QMessageBox::warning(
                                  this,"Firewall Builder", dialog_txt,
                                  tr("&Yes"), tr("&No"), QString::null,
                                  0, 1 )==0 );
        blockSignals(false);
    }

    if (fwbdebug)
        qDebug() << "Sending FWCmdChange  autorename_chidren="
                 << autorename_chidren;

    std::unique_ptr<FWCmdChange> cmd(
        new FWCmdChange(m_project, obj, "", autorename_chidren));

    // new_state  is a copy of the fw object
    FWObject* new_state = cmd->getNewState();

    Firewall *s = dynamic_cast<Firewall*>(new_state);

#ifndef NDEBUG
    Management *mgmt = s->getManagementObject();
    assert(mgmt!=nullptr);
#endif

    string old_name = obj->getName();
    string new_name = string(m_dialog->obj_name->text().toUtf8().constData());
    string old_platform = obj->getStr("platform");
    string old_host_os = obj->getStr("host_OS");
    string old_version = obj->getStr("version");

    new_state->setName(new_name);
    m_dialog->commentKeywords->applyChanges(new_state);

    s->setInactive(m_dialog->inactive->isChecked());

    saveVersion(new_state);

    string new_version = new_state->getStr("version");

    string new_platform = readPlatform(m_dialog->platform).toLatin1().constData();
    if (new_platform.empty()) new_platform = "unknown";
    new_state->setStr("platform", new_platform );

    if (old_platform!=new_platform)
    {
        if (fwbdebug)
            qDebug() << "FirewallDialog::applyChanges() platform has changed"
                     << old_platform.c_str() << "->" << new_platform.c_str()
                     << "clearing option 'compiler'";
        platformChanged();
        FWOptions  *opt =s->getOptionsObject();
        opt->setStr("compiler", "");

        // Set default options for the new platform
        Resources::setDefaultTargetOptions(new_platform, s);
    }

    string new_host_os = readHostOS(m_dialog->hostOS).toLatin1().constData();
    if (new_host_os.empty()) new_host_os = "unknown_os";
    new_state->setStr("host_OS", new_host_os);

    if (old_host_os!=new_host_os)
    {
        if (fwbdebug)
            qDebug() << "FirewallDialog::applyChanges() host_OS has changed"
                     << old_host_os.c_str() << "->" << new_host_os.c_str();
        hostOSChanged();
        // Set default options for the new host os
        Resources::setDefaultTargetOptions(new_host_os, s);
    }

    if (new_platform.empty())
    {
        QMessageBox::critical(
            this, "Firewall Builder",
            tr("Platform setting can not be empty"),
            tr("&Continue"), nullptr, nullptr,
            0 );
        return;
    }

    if (new_host_os.empty())
    {
        QMessageBox::critical(
            this, "Firewall Builder",
            tr("Host OS setting can not be empty"),
            tr("&Continue"), nullptr, nullptr,
            0 );
        return;
    }

    if (old_platform!=new_platform || old_host_os!=new_host_os ||
        old_name!=new_name || old_version!=new_version)
    {
        if (fwbdebug)
            qDebug("FirewallDialog::applyChanges() scheduling call "
                   "to reopenFirewall()");
        m_project->registerRuleSetRedrawRequest();
    }

    if (!cmd->getOldState()->cmp(new_state, true))
    {
        if (obj->isReadOnly()) return;
        m_project->undoStack->push(cmd.release());
    }

    updateTimeStamps();
}
Esempio n. 10
0
int main(int argc, char** argv)
{
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  slave::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip,
            "ip",
            "IP address to listen on. This cannot be used in conjunction\n"
            "with `--ip_discovery_command`.");

  uint16_t port;
  flags.add(&port,
            "port",
            "Port to listen on.",
            SlaveInfo().port());

  Option<string> advertise_ip;
  flags.add(&advertise_ip,
            "advertise_ip",
            "IP address advertised to reach this Mesos agent.\n"
            "The agent does not bind to this IP address.\n"
            "However, this IP address may be used to access this agent.");

  Option<string> advertise_port;
  flags.add(&advertise_port,
            "advertise_port",
            "Port advertised to reach this Mesos agent (along with\n"
            "`advertise_ip`). The agent does not bind to this port.\n"
            "However, this port (along with `advertise_ip`) may be used to\n"
            "access this agent.");

  Option<string> master;
  flags.add(&master,
            "master",
            "May be one of:\n"
            "  `host:port`\n"
            "  `zk://host1:port1,host2:port2,.../path`\n"
            "  `zk://username:password@host1:port1,host2:port2,.../path`\n"
            "  `file:///path/to/file` (where file contains one of the above)");


  // Optional IP discover script that will set the slave's IP.
  // If set, its output is expected to be a valid parseable IP string.
  Option<string> ip_discovery_command;
  flags.add(&ip_discovery_command,
            "ip_discovery_command",
            "Optional IP discovery binary: if set, it is expected to emit\n"
            "the IP address which the agent will try to bind to.\n"
            "Cannot be used in conjunction with `--ip`.");

  Try<Nothing> load = flags.load("MESOS_", argc, argv);

  // TODO(marco): this pattern too should be abstracted away
  // in FlagsBase; I have seen it at least 15 times.
  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  if (flags.version) {
    version();
    return EXIT_SUCCESS;
  }

  if (master.isNone() && flags.master_detector.isNone()) {
    cerr << flags.usage("Missing required option `--master` or "
                        "`--master_detector`.") << endl;
    return EXIT_FAILURE;
  }

  if (master.isSome() && flags.master_detector.isSome()) {
    cerr << flags.usage("Only one of --master or --master_detector options "
                        "should be specified.");
    return EXIT_FAILURE;
  }

  // Initialize libprocess.
  if (ip_discovery_command.isSome() && ip.isSome()) {
    EXIT(EXIT_FAILURE) << flags.usage(
        "Only one of `--ip` or `--ip_discovery_command` should be specified");
  }

  if (ip_discovery_command.isSome()) {
    Try<string> ipAddress = os::shell(ip_discovery_command.get());

    if (ipAddress.isError()) {
      EXIT(EXIT_FAILURE) << ipAddress.error();
    }

    os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get()));
  } else if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  if (advertise_ip.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get());
  }

  if (advertise_port.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get());
  }

  const string id = process::ID::generate("slave"); // Process ID.

  // If `process::initialize()` returns `false`, then it was called before this
  // invocation, meaning the authentication realm for libprocess-level HTTP
  // endpoints was set incorrectly. This should be the first invocation.
  if (!process::initialize(id, DEFAULT_HTTP_AUTHENTICATION_REALM)) {
    EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's "
                       << "`main()` was not the function's first invocation";
  }

  logging::initialize(argv[0], flags, true); // Catch signals.

  // Initialize modules. Note that since other subsystems may depend
  // upon modules, we should initialize modules before anything else.
  if (flags.modules.isSome()) {
    Try<Nothing> result = ModuleManager::load(flags.modules.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
    }
  }

  // Initialize hooks.
  if (flags.hooks.isSome()) {
    Try<Nothing> result = HookManager::initialize(flags.hooks.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
    }
  }

  spawn(new VersionProcess(), true);

  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;

  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  Fetcher fetcher;

#ifdef __linux__
  // Initialize systemd if it exists.
  if (systemd::exists() && flags.systemd_enable_support) {
    LOG(INFO) << "Inializing systemd state";

    systemd::Flags systemdFlags;
    systemdFlags.enabled = flags.systemd_enable_support;
    systemdFlags.runtime_directory = flags.systemd_runtime_directory;
    systemdFlags.cgroups_hierarchy = flags.cgroups_hierarchy;

    Try<Nothing> initialize = systemd::initialize(systemdFlags);
    if (initialize.isError()) {
      EXIT(EXIT_FAILURE)
        << "Failed to initialize systemd: " + initialize.error();
    }
  }
#endif // __linux__

  Try<Containerizer*> containerizer =
    Containerizer::create(flags, false, &fetcher);

  if (containerizer.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a containerizer: " << containerizer.error();
  }

  Try<MasterDetector*> detector_ = MasterDetector::create(
      master, flags.master_detector);

  if (detector_.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master detector: " << detector_.error();
  }

  MasterDetector* detector = detector_.get();

  Option<Authorizer*> authorizer_ = None();

  string authorizerName = flags.authorizer;

  Result<Authorizer*> authorizer((None()));
  if (authorizerName != slave::DEFAULT_AUTHORIZER) {
    LOG(INFO) << "Creating '" << authorizerName << "' authorizer";

    // NOTE: The contents of --acls will be ignored.
    authorizer = Authorizer::create(authorizerName);
  } else {
    // `authorizerName` is `DEFAULT_AUTHORIZER` at this point.
    if (flags.acls.isSome()) {
      LOG(INFO) << "Creating default '" << authorizerName << "' authorizer";

      authorizer = Authorizer::create(flags.acls.get());
    }
  }

  if (authorizer.isError()) {
    EXIT(EXIT_FAILURE) << "Could not create '" << authorizerName
                       << "' authorizer: " << authorizer.error();
  } else if (authorizer.isSome()) {
    authorizer_ = authorizer.get();
  }

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
bool ProjectPanel::event(QEvent *event)
{
    if (event->type() >= QEvent::User)
    {
        fwbUpdateEvent *ev = dynamic_cast<fwbUpdateEvent*>(event);
        int event_code = event->type() - QEvent::User;
        QString data_file = ev->getFileName();
        int obj_id = ev->getObjectId();
        FWObject *obj = db()->findInIndex(obj_id);

        if (fwbdebug)
            qDebug() << this
                     << "rcs:"
                     << rcs
                     << "rcs->getFileName():"
                     << QString((rcs!=NULL) ? rcs->getFileName() : "")
                     << "file:"
                     << data_file
                     << "event:"
                     << ev->getEventName()
                     << "object:"
                     << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "")
                     << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")"
                     << "id=" << ((obj!=NULL) ? obj->getId() : -1);

        if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL)
        {
            m_panel->om->updateCreateObjectMenu(getCurrentLib());
            ev->accept();
            return true;
        }

        if ((rcs && rcs->getFileName() == data_file) ||
            (!rcs && data_file.isEmpty()))
        {
            switch (event_code)
            {
            case RELOAD_OBJECT_TREE_EVENT:
                registerTreeReloadRequest();
                ev->accept();
                return true;
                
            case RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT:
                m_panel->om->reload();
                ev->accept();
                return true;
                
            case RELOAD_RULESET_EVENT:
                registerRuleSetRedrawRequest();
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT:
            {
                RuleSetView* rsv = getCurrentRuleSetView();
                if (rsv) rsv->makeCurrentRuleVisible();
                ev->accept();
                return true;
            }
   
            case RELOAD_RULESET_IMMEDIATELY_EVENT:
                redrawRuleSets();
                //reopenFirewall();
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;
            }

            if (obj == NULL) return false;

            switch (event_code)
            {
            case DATA_MODIFIED_EVENT:
            {
                // This event does not trigger any updates in the UI,
                // this purely data structure update event. 

                FWObject *p = obj;
                while (p && Firewall::cast(p)==NULL) p = p->getParent();
                Firewall *f = Firewall::cast(p);
                // when user locks firewall object, this code tries to
                // update last_modified timestamp in it because it
                // depends on itself. Dont.
                if (f && !f->isReadOnly())
                {
                    f->updateLastModifiedTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, f->getId()));
                }
                registerModifiedObject(obj);

                QCoreApplication::postEvent(mw, new updateGUIStateEvent());

                ev->accept();
                return true;
            }

            case UPDATE_OBJECT_EVERYWHERE_EVENT:
            {
                Rule *rule = NULL;
                RuleSet* current_ruleset = NULL;
                RuleSetView* rsv = getCurrentRuleSetView();
                RuleSetModel* md = NULL;
                if (rsv)
                {
                    md = (RuleSetModel*)rsv->model();
                    current_ruleset = md->getRuleSet();
                }
                if (RuleElement::cast(obj)) rule = Rule::cast(obj->getParent());
                if (Rule::cast(obj)) rule = Rule::cast(obj);

                if (rule && current_ruleset && md && rule->isChildOf(current_ruleset))
                {
                    md->rowChanged(md->index(rule, 0));
                    ev->accept();
                    return true;
                }

                if (rule)
                {
                    QCoreApplication::postEvent(
                        this, new showObjectInRulesetEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }

                if (rsv) rsv->updateObject(obj);

                if (Library::cast(obj))
                {
                    m_panel->om->updateLibName(obj);
                    m_panel->om->updateLibColor(obj);
                }

                QCoreApplication::postEvent(
                    mw, new updateObjectInTreeEvent(data_file, obj_id));

                // QCoreApplication::postEvent(
                //     this, new reloadRulesetEvent(data_file));

                ev->accept();
                return true;
            }

            case OBJECT_NAME_CHANGED_EVENT:
            {
                objectNameChangedEvent *name_change_event =
                    dynamic_cast<objectNameChangedEvent*>(event);
                m_panel->om->updateObjectInTree(obj);
                if (name_change_event->rename_children)
                {
                    // This performs automatic renaming of child objects if necessary
                    m_panel->om->autoRenameChildren(obj, name_change_event->old_name);
                }
                ev->accept();
                return true;
            }

            case UPDATE_LAST_COMPILED_TIMESTAMP_EVENT:
                if (rcs && !rcs->isRO() &&
                    Firewall::cast(obj) && !obj->isReadOnly())
                {
                    Firewall::cast(obj)->updateLastCompiledTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }
                break;

            case UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT:
                if (rcs && !rcs->isRO() &&
                    Firewall::cast(obj) && !obj->isReadOnly())
                {
                    Firewall::cast(obj)->updateLastInstalledTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }
                break;
            }

            // Events below this should only be processed if
            // ProjectPanel has been attached to an MDI window.  There
            // is no MDI window right after project panel is created
            // but some operations may already be performed. See
            // FWWindow::fileOpen where ProjectPanel is cfeated and
            // file is opened before MDI window is attached. So the UI
            // update events below will only be processed if MDI
            // window exists.

            if (mdiWindow == NULL) return false;

            switch (event->type() - QEvent::User)
            {
            case INSERT_OBJECT_IN_TREE_EVENT:
            {
                FWObject *parent =
                    db()->findInIndex(
                        dynamic_cast<insertObjectInTreeEvent*>(event)->parent_id);
                m_panel->om->insertSubtree(parent, obj);
                ev->accept();
                return true;
            }

            case REMOVE_OBJECT_FROM_TREE_EVENT:
            {
                m_panel->om->removeObjectFromTreeView(obj);
                ev->accept();
                return true;
            }

            case ADD_TREE_PAGE_EVENT:
                m_panel->om->addLib(obj);
                ev->accept();
                return true;

            case REMOVE_TREE_PAGE_EVENT:
                m_panel->om->removeLib(obj);
                ev->accept();
                return true;

            case UPDATE_OBJECT_IN_TREE_EVENT:
                registerObjectToUpdateInTree(obj, false);
                ev->accept();
                return true;

            case UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT:
                registerObjectToUpdateInTree(obj, true);
                ev->accept();
                return true;

            case UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT:
                m_panel->om->updateObjectInTree(obj, true);
                ev->accept();
                return true;

            case OPEN_RULESET_EVENT:
                openRuleSet(obj);
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case OPEN_RULESET_IMMEDIATELY_EVENT:
                openRuleSet(obj, true);
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case SELECT_RULE_ELEMENT_EVENT:
            {
                RuleSetView* rsv = getCurrentRuleSetView();
                rsv->selectRE(Rule::cast(obj),
                              dynamic_cast<selectRuleElementEvent*>(event)->column_type);
                rsv->setFocus(Qt::OtherFocusReason);
                ev->accept();
                return true;
            }

            case SHOW_OBJECT_IN_RULESET_EVENT:
            {
                // if obj is child of RuleElement (i.e. a reference object)
                FWReference *ref = FWReference::cast(obj);
                if (ref)
                {
                    RuleSet* current_ruleset = NULL;
                    RuleSetView* rsv = getCurrentRuleSetView();
                    RuleSetModel* md = NULL;
                    if (rsv)
                    {
                        md = (RuleSetModel*)rsv->model();
                        current_ruleset = md->getRuleSet();
                    }

                    if (current_ruleset && obj->isChildOf(current_ruleset))
                    {
                        clearManipulatorFocus();
                        rsv->selectRE(ref);
                        rsv->setFocus(Qt::OtherFocusReason);
                    } else
                    {
                        FWObject *rs = obj;
                        while (rs && RuleSet::cast(rs)==NULL) rs = rs->getParent();
                        if (rs)
                        {
                            // reopen rule set right now, before we post event
                            // to show the object in it.
                            openRuleSet(rs);
                            QCoreApplication::postEvent(
                                this, new showObjectInRulesetEvent(data_file, obj_id));
                        }
                    }
                    ev->accept();
                    return true;
                }

                // if obj is RuleElement - select its first element
                RuleElement *re = RuleElement::cast(obj);
                if (re && re->size() > 0)
                {
                    QCoreApplication::postEvent(
                        this, new showObjectInRulesetEvent(data_file, obj->front()->getId()));
                    ev->accept();
                    return true;
                }

                // if obj is Rule - select its comment (the only common rule element)
                Rule *rule = Rule::cast(obj);
                if (rule)
                {
                    RuleSet* current_ruleset = NULL;
                    RuleSetView* rsv = getCurrentRuleSetView();
                    RuleSetModel* md = NULL;
                    if (rsv)
                    {
                        md = (RuleSetModel*)rsv->model();
                        current_ruleset = md->getRuleSet();
                    }
                    if (current_ruleset && rule->isChildOf(current_ruleset))
                    {
                        rsv->selectRE(rule, ColDesc::Comment);
                        rsv->setFocus(Qt::OtherFocusReason);
                        ev->accept();
                        return true;
                    } else
                    {
                        // this rule does not belong to the current ruleset
                        // reopen rule set right now, before we post event
                        // to show the object in it.
                        openRuleSet(rule->getParent(), true);
                        QCoreApplication::postEvent(
                            this, new showObjectInRulesetEvent(data_file, obj->getId()));
                    }
                    ev->accept();
                    return true;
                }

                ev->accept();
                return true;
            }

            case SHOW_OBJECT_IN_TREE_EVENT:
                //m_panel->om->setFocus();
                m_panel->om->openObjectInTree(obj);
                ev->accept();
                return true;

            case EXPAND_OBJECT_IN_TREE:
                m_panel->om->expandObjectInTree(obj);
                ev->accept();
                return true;

            case OPEN_LIBRARY_FOR_OBJECT_EVENT:
                m_panel->om->openLibForObject(obj);
                ev->accept();
                return true;

            case CLOSE_OBJECT_EVENT:
                if (RuleSet::cast(obj))
                {
                    if (visibleRuleSet == obj)
                    {
                        clearFirewallTabs();
                        closeRuleSet(obj);
                    }
                } else
                {
                    m_panel->om->closeObject();
                    mdiWindow->update();
                }
                ev->accept();
                return true;

            case ADD_USER_FOLDER_EVENT:
                m_panel->om->addUserFolderToTree(obj, dynamic_cast<addUserFolderEvent *>(event)->m_userFolder);
                ev->accept();
                return true;

            case REMOVE_USER_FOLDER_EVENT:
                m_panel->om->removeUserFolderFromTree(obj, dynamic_cast<removeUserFolderEvent *>(event)->m_userFolder);
                ev->accept();
                return true;

            case MOVE_TOFROM_USER_FOLDER_EVENT:
                moveToFromUserFolderEvent *moveEvent =
                    dynamic_cast<moveToFromUserFolderEvent *>(event);
                m_panel->om->moveToFromUserFolderInTree(obj, db()->findInIndex(moveEvent->m_objIdToMove), moveEvent->m_oldFolder, moveEvent->m_newFolder);
                ev->accept();
                return true;
            }
        }
        return false;
    }

    //if (fwbdebug) qDebug() << this << "event:" << event;
    
    return QWidget::event(event);
}
Esempio n. 12
0
/**
 * finds interface of the firewall associated with the netzone
 * that object 'obj' belongs to.  Returns interface ID
 *
 */
int  Helper::findInterfaceByNetzone(const InetAddr *addr, const InetAddr *nm)
    throw(FWException)
{
#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " matching to";
    cerr << " addr=" << addr;
    if (addr) cerr << " " << addr->toString();
    cerr << " nm=" << nm;
    if (nm) cerr << " " << nm->toString();
    cerr << endl;
#endif

    Firewall *fw = compiler->fw;
    map<int,FWObject*> zones;
    list<FWObject*> l2 = fw->getByTypeDeep(Interface::TYPENAME);
    for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i)
    {
        Interface *iface = Interface::cast(*i);
        if (iface->isDedicatedFailover()) continue;
        if (iface->isUnprotected()) continue;

        // NOTE: "network_zone" is globally unique string ID
        int netzone_id =
            FWObjectDatabase::getIntId(iface->getStr("network_zone"));

        if (netzone_id != -1)
        {
            FWObject *netzone = fw->getRoot()->findInIndex(netzone_id);
            list<FWObject*> nz;
            expand_group_recursive(netzone, nz);

#if DEBUG_NETZONE_OPS
            cerr << "Helper::findInterfaceByNetzone";
            cerr << "  netzone_id=" << netzone_id
                 << "  " << iface->getStr("network_zone")
                 << "  " << netzone->getName()
                 << endl;
#endif

            for (list<FWObject*>::iterator j=nz.begin(); j!=nz.end(); ++j)
            {
                Address *netzone_addr = Address::cast(*j);
                
                if (netzone_addr == NULL) continue;

#if DEBUG_NETZONE_OPS
                cerr << "Helper::findInterfaceByNetzone";
                cerr << "    " << netzone_addr->getName()
                     << "  " << netzone_addr->getAddressPtr()->toString()
                     << endl;
#endif

                // if addr==NULL, return id of the interfacce that has
                // net_zone=="any"
                if (addr==NULL)
                {
                    if (netzone_addr->getId()==FWObjectDatabase::ANY_ADDRESS_ID)
                        return iface->getId(); // id of the interface
                } else
                {
                    // see SF bug 3213019
                    // skip ipv6 addresses in network zone group
                    if (netzone_addr->getAddressPtr()->addressFamily() !=
                        addr->addressFamily()) continue;

                    const InetAddr *nz_addr = netzone_addr->getAddressPtr();
                    const InetAddr *nz_netm = netzone_addr->getNetmaskPtr();
                    if (nm != NULL && nz_netm != NULL)
                    {
                        InetAddrMask nz_subnet(*nz_addr, *nz_netm);
                        InetAddrMask other_subnet(*addr, *nm);
                        vector<InetAddrMask> ovr =
                            libfwbuilder::getOverlap(nz_subnet,
                                                     other_subnet);
#if DEBUG_NETZONE_OPS
                        cerr << "Helper::findInterfaceByNetzone";
                        cerr << " addr=" << other_subnet.toString();
                        cerr << " nz=" << nz_subnet.toString();
                        cerr << " overlap:";
                        cerr << " ovr.size()=" << ovr.size();
                        if (ovr.size() > 0)
                            cerr << " ovr.front()=" << ovr.front().toString();
                        cerr << endl;
#endif
                        if (ovr.size()==0) continue;
                        // if nz_subnet is equal or wider than other_subnet,
                        // getOverlap() returns subnet object equal to other_subnet
                        // If other_subnet is wider, returned object is equal
                        // to nz_subnet. If they intersect but one does not fit
                        // completely in the other, returned object is not equal
                        // to either.
                        if (ovr.front() == other_subnet)
                        {
                            zones[iface->getId()] = netzone_addr;
#if DEBUG_NETZONE_OPS
                            cerr << "Helper::findInterfaceByNetzone";
                            cerr << "    match" << endl;
#endif
                        }
                    } else
                    {
                        if (netzone_addr->belongs(*addr))
                        {
                            zones[iface->getId()] = netzone_addr;

#if DEBUG_NETZONE_OPS
                            cerr << "Helper::findInterfaceByNetzone";
                            cerr << "    match" << endl;
#endif
                        }
                    }
                }
            }
        }
    }

/*
 * now compare dimensions of all netzones that contain address obj and
 * pick the one with smallest dimension
 */    
    int  res_id = -1;
    unsigned long res_dim = LONG_MAX;
    for (map<int,FWObject*>::iterator i=zones.begin(); i!=zones.end(); ++i) 
    {
        int iface_id = (*i).first;
        FWObject *netzone = (*i).second;
        unsigned long dim = calculateDimension(netzone);

#if DEBUG_NETZONE_OPS
        cerr << "Helper::findInterfaceByNetzone";
        cerr << "    netzone=" << netzone->getName()
             << "  dim=" << dim
             << "  res_dim=" << res_dim
             << endl;
#endif

        if (dim<=res_dim) 
        {
            res_id = iface_id;
            res_dim = dim;
        }
    }

#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " Result after scanning network zones: " << res_id << endl;
#endif

/*
 * Subnets defined by addresses of interfaces are automatically part
 * of the corresponding network zones
 */
    if (res_id == -1)
        res_id = findInterfaceByAddress(addr, nm);

    if (res_id == -1)
    {
        QString err = QObject::tr("Can not find interface with network zone "
                                  "that includes address '%1%2'");
        throw(FWException(err
                          .arg((addr)?addr->toString().c_str():"NULL")
                          .arg((nm)?QString("/%1").arg(nm->toString().c_str()):"")
                          .toStdString()));
    }

#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " returning " << res_id << endl;
#endif

    return res_id;
}
Esempio n. 13
0
int  Helper::findInterfaceByAddress(const InetAddr *addr,
                                    const InetAddr *nm)
{
    if (addr==NULL) return -1;

#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByAddress";
    cerr << " addr=" << addr->toString();
    cerr << " nm=" << nm->toString();
    cerr << endl;
#endif

    Firewall *fw = compiler->fw;
    list<FWObject*> l2 = fw->getByTypeDeep(Interface::TYPENAME);
    for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i)
    {
	Interface *iface = Interface::cast(*i);
        if (iface->isDedicatedFailover()) continue;
        if (iface->isUnprotected()) continue;

#if DEBUG_NETZONE_OPS
        cerr << "Helper::findInterfaceByAddress";
        cerr << " intf=" << iface->getName();
        cerr << endl;
#endif

        FWObjectTypedChildIterator j =
            iface->findByType((addr->isV4())?IPv4::TYPENAME:IPv6::TYPENAME);
        for (; j!=j.end(); ++j)
        {
            const Address *i_addr = Address::constcast(*j);

#if DEBUG_NETZONE_OPS
            cerr << "Helper::findInterfaceByAddress";
            cerr << " i_addr=" << i_addr->getName();
            cerr << endl;
            cerr << "    " << i_addr->getAddressPtr()->toString();
            cerr << "    " << i_addr->getNetmaskPtr()->toString();
            cerr << endl;
#endif

            if (nm != NULL)
            {
                InetAddrMask interface_subnet(*(i_addr->getAddressPtr()),
                                              *(i_addr->getNetmaskPtr()));
                InetAddrMask other_subnet(*addr, *nm);

#if DEBUG_NETZONE_OPS
                cerr << "Helper::findInterfaceByAddress";
                cerr << " addr=" << other_subnet.toString();
                cerr << " intf=" << iface->getName()
                     << "  " << interface_subnet.toString();
                cerr << endl;
#endif

                vector<InetAddrMask> ovr =
                    libfwbuilder::getOverlap(interface_subnet, other_subnet);

#if DEBUG_NETZONE_OPS
                cerr << "Helper::findInterfaceByAddress";
                cerr << " overlap:";
                cerr << " ovr.size()=" << ovr.size();
                if (ovr.size() > 0)
                    cerr << " ovr.front()=" << ovr.front().toString();
                cerr << endl;
#endif
                if (ovr.size()==0) continue;

                // if interface_subnet is equal or wider than other_subnet,
                // getOverlap() returns subnet object equal to other_subnet
                // If other_subnet is wider, returned object is equal
                // to interface_subnet. If they intersect but one does not fit
                // completely in the other, returned object is not equal
                // to either.
                if (ovr.front() == other_subnet)
                {
                    return iface->getId();
                }
            } else
            {
                if ( i_addr->belongs(*addr) ) return iface->getId();
            }
        }
    }
    return -1;
}
Esempio n. 14
0
int main(int argc, char** argv)
{
  // The order of initialization is as follows:
  // * Windows socket stack.
  // * Validate flags.
  // * Log build information.
  // * Libprocess
  // * Logging
  // * Version process
  // * Firewall rules: should be initialized before initializing HTTP endpoints.
  // * Modules: Load module libraries and manifests before they
  //   can be instantiated.
  // * Anonymous modules: Later components such as Allocators, and master
  //   contender/detector might depend upon anonymous modules.
  // * Hooks.
  // * Systemd support (if it exists).
  // * Fetcher and Containerizer.
  // * Master detector.
  // * Authorizer.
  // * Garbage collector.
  // * Status update manager.
  // * Resource estimator.
  // * QoS controller.
  // * `Agent` process.
  //
  // TODO(avinash): Add more comments discussing the rationale behind for this
  // particular component ordering.

#ifdef __WINDOWS__
  // Initialize the Windows socket stack.
  process::Winsock winsock;
#endif

  GOOGLE_PROTOBUF_VERIFY_VERSION;

  slave::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip,
            "ip",
            "IP address to listen on. This cannot be used in conjunction\n"
            "with `--ip_discovery_command`.");

  uint16_t port;
  flags.add(&port,
            "port",
            "Port to listen on.",
            SlaveInfo().port());

  Option<string> advertise_ip;
  flags.add(&advertise_ip,
            "advertise_ip",
            "IP address advertised to reach this Mesos agent.\n"
            "The agent does not bind to this IP address.\n"
            "However, this IP address may be used to access this agent.");

  Option<string> advertise_port;
  flags.add(&advertise_port,
            "advertise_port",
            "Port advertised to reach this Mesos agent (along with\n"
            "`advertise_ip`). The agent does not bind to this port.\n"
            "However, this port (along with `advertise_ip`) may be used to\n"
            "access this agent.");

  Option<string> master;
  flags.add(&master,
            "master",
            "May be one of:\n"
            "  `host:port`\n"
            "  `zk://host1:port1,host2:port2,.../path`\n"
            "  `zk://username:password@host1:port1,host2:port2,.../path`\n"
            "  `file:///path/to/file` (where file contains one of the above)");


  // Optional IP discover script that will set the slave's IP.
  // If set, its output is expected to be a valid parseable IP string.
  Option<string> ip_discovery_command;
  flags.add(&ip_discovery_command,
            "ip_discovery_command",
            "Optional IP discovery binary: if set, it is expected to emit\n"
            "the IP address which the agent will try to bind to.\n"
            "Cannot be used in conjunction with `--ip`.");

  Try<flags::Warnings> load = flags.load("MESOS_", argc, argv);

  // TODO(marco): this pattern too should be abstracted away
  // in FlagsBase; I have seen it at least 15 times.
  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  if (flags.version) {
    cout << "mesos" << " " << MESOS_VERSION << endl;
    return EXIT_SUCCESS;
  }

  if (master.isNone() && flags.master_detector.isNone()) {
    cerr << flags.usage("Missing required option `--master` or "
                        "`--master_detector`.") << endl;
    return EXIT_FAILURE;
  }

  if (master.isSome() && flags.master_detector.isSome()) {
    cerr << flags.usage("Only one of --master or --master_detector options "
                        "should be specified.");
    return EXIT_FAILURE;
  }

  // Initialize libprocess.
  if (ip_discovery_command.isSome() && ip.isSome()) {
    EXIT(EXIT_FAILURE) << flags.usage(
        "Only one of `--ip` or `--ip_discovery_command` should be specified");
  }

  if (ip_discovery_command.isSome()) {
    Try<string> ipAddress = os::shell(ip_discovery_command.get());

    if (ipAddress.isError()) {
      EXIT(EXIT_FAILURE) << ipAddress.error();
    }

    os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get()));
  } else if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  if (advertise_ip.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get());
  }

  if (advertise_port.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get());
  }

  // Log build information.
  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;
  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  const string id = process::ID::generate("slave"); // Process ID.

  // If `process::initialize()` returns `false`, then it was called before this
  // invocation, meaning the authentication realm for libprocess-level HTTP
  // endpoints was set incorrectly. This should be the first invocation.
  if (!process::initialize(id, DEFAULT_HTTP_AUTHENTICATION_REALM)) {
    EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's "
                       << "`main()` was not the function's first invocation";
  }

  logging::initialize(argv[0], flags, true); // Catch signals.

  // Log any flag warnings (after logging is initialized).
  foreach (const flags::Warning& warning, load->warnings) {
    LOG(WARNING) << warning.message;
  }

  spawn(new VersionProcess(), true);

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
Esempio n. 15
0
void FirewallDialog::loadFWObject(FWObject *o)
{
    try
    {
        obj = o;
        Firewall *s = dynamic_cast<Firewall*>(obj);
        assert(s!=nullptr);

        init = true;

        QString platform = obj->getStr("platform").c_str();
/* fill in platform */
        setPlatform(m_dialog->platform, platform);

        fillVersion();

/* fill in host OS  */
        setHostOS(m_dialog->hostOS, platform, obj->getStr("host_OS").c_str());

/* ---------------- */
        updateTimeStamps();

#ifndef NDEBUG
        Management *mgmt=s->getManagementObject();
        assert(mgmt!=nullptr);
#endif

//    FWOptions  *opt =s->getOptionsObject();

        m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) );

        m_dialog->commentKeywords->loadFWObject(o);

        m_dialog->inactive->setChecked(s->getInactive());

        m_dialog->obj_name->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->obj_name);

        m_dialog->platform->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->platform);

        m_dialog->version->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->version);

        m_dialog->hostOS->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->hostOS);

        m_dialog->fwAdvanced->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->fwAdvanced);

        m_dialog->osAdvanced->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->osAdvanced);

//    snmpCommunity->setEnabled(!o->isReadOnly());
//    setDisabledPalette(snmpCommunity);

        m_dialog->inactive->setEnabled(!o->isReadOnly());
        setDisabledPalette(m_dialog->inactive);

    } catch (FWException &ex)
    {
        qDebug() << "Caught FWException:" << ex.toString().c_str();
    }

    init=false;
}
Esempio n. 16
0
int main(int argc, char** argv)
{
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  master::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip, "ip", "IP address to listen on");

  uint16_t port;
  flags.add(&port, "port", "Port to listen on", MasterInfo().port());

  Option<string> advertise_ip;
  flags.add(&advertise_ip,
            "advertise_ip",
            "IP address advertised to reach mesos master.\n"
            "Mesos master does not bind using this IP address.\n"
            "However, this IP address may be used to access Mesos master.");

  Option<string> advertise_port;
  flags.add(&advertise_port,
            "advertise_port",
            "Port advertised to reach mesos master (alongwith advertise_ip).\n"
            "Mesos master does not bind using this port.\n"
            "However, this port (alongwith advertise_ip) may be used to\n"
            "access Mesos master.");

  Option<string> zk;
  flags.add(&zk,
            "zk",
            "ZooKeeper URL (used for leader election amongst masters)\n"
            "May be one of:\n"
            "  zk://host1:port1,host2:port2,.../path\n"
            "  zk://username:password@host1:port1,host2:port2,.../path\n"
            "  file:///path/to/file (where file contains one of the above)");

  // Optional IP discover script that will set the Master IP.
  // If set, its output is expected to be a valid parseable IP string.
  Option<string> ip_discovery_command;
  flags.add(&ip_discovery_command,
      "ip_discovery_command",
      "Optional IP discovery binary: if set, it is expected to emit\n"
      "the IP address which Master will try to bind to.\n"
      "Cannot be used in conjunction with --ip.");

  Try<Nothing> load = flags.load("MESOS_", argc, argv);

  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.version) {
    version();
    return EXIT_SUCCESS;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  // Initialize modules. Note that since other subsystems may depend
  // upon modules, we should initialize modules before anything else.
  if (flags.modules.isSome()) {
    Try<Nothing> result = ModuleManager::load(flags.modules.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
    }
  }

  // Initialize hooks.
  if (flags.hooks.isSome()) {
    Try<Nothing> result = HookManager::initialize(flags.hooks.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
    }
  }

  if (ip_discovery_command.isSome() && ip.isSome()) {
    EXIT(EXIT_FAILURE) << flags.usage(
        "Only one of --ip or --ip_discovery_command should be specified");
  }

  if (ip_discovery_command.isSome()) {
    Try<string> ipAddress = os::shell(ip_discovery_command.get());

    if (ipAddress.isError()) {
      EXIT(EXIT_FAILURE) << ipAddress.error();
    }

    os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get()));
  } else if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  if (advertise_ip.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get());
  }

  if (advertise_port.isSome()) {
    os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get());
  }

  // Initialize libprocess.
  process::initialize("master");

  logging::initialize(argv[0], flags, true); // Catch signals.

  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;

  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  // Create an instance of allocator.
  const std::string allocatorName = flags.allocator;
  Try<Allocator*> allocator = Allocator::create(allocatorName);

  if (allocator.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create '" << allocatorName
      << "' allocator: " << allocator.error();
  }

  CHECK_NOTNULL(allocator.get());
  LOG(INFO) << "Using '" << allocatorName << "' allocator";

  state::Storage* storage = NULL;
  Log* log = NULL;

  if (flags.registry == "in_memory") {
    if (flags.registry_strict) {
      EXIT(EXIT_FAILURE)
        << "Cannot use '--registry_strict' when using in-memory storage"
        << " based registry";
    }
    storage = new state::InMemoryStorage();
  } else if (flags.registry == "replicated_log" ||
             flags.registry == "log_storage") {
    // TODO(bmahler): "log_storage" is present for backwards
    // compatibility, can be removed before 0.19.0.
    if (flags.work_dir.isNone()) {
      EXIT(EXIT_FAILURE)
        << "--work_dir needed for replicated log based registry";
    }

    Try<Nothing> mkdir = os::mkdir(flags.work_dir.get());
    if (mkdir.isError()) {
      EXIT(EXIT_FAILURE)
        << "Failed to create work directory '" << flags.work_dir.get()
        << "': " << mkdir.error();
    }

    if (zk.isSome()) {
      // Use replicated log with ZooKeeper.
      if (flags.quorum.isNone()) {
        EXIT(EXIT_FAILURE)
          << "Need to specify --quorum for replicated log based"
          << " registry when using ZooKeeper";
      }

      Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get());
      if (url.isError()) {
        EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error();
      }

      log = new Log(
          flags.quorum.get(),
          path::join(flags.work_dir.get(), "replicated_log"),
          url.get().servers,
          flags.zk_session_timeout,
          path::join(url.get().path, "log_replicas"),
          url.get().authentication,
          flags.log_auto_initialize);
    } else {
      // Use replicated log without ZooKeeper.
      log = new Log(
          1,
          path::join(flags.work_dir.get(), "replicated_log"),
          set<UPID>(),
          flags.log_auto_initialize);
    }
    storage = new state::LogStorage(log);
  } else {
    EXIT(EXIT_FAILURE)
      << "'" << flags.registry << "' is not a supported"
      << " option for registry persistence";
  }

  CHECK_NOTNULL(storage);

  state::protobuf::State* state = new state::protobuf::State(storage);
  Registrar* registrar = new Registrar(flags, state);
  Repairer* repairer = new Repairer();

  Files files;

  MasterContender* contender;
  MasterDetector* detector;

  // TODO(vinod): 'MasterContender::create()' should take
  // Option<string>.
  Try<MasterContender*> contender_ = MasterContender::create(zk.getOrElse(""));
  if (contender_.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master contender: " << contender_.error();
  }
  contender = contender_.get();

  // TODO(vinod): 'MasterDetector::create()' should take
  // Option<string>.
  Try<MasterDetector*> detector_ = MasterDetector::create(zk.getOrElse(""));
  if (detector_.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master detector: " << detector_.error();
  }
  detector = detector_.get();

  Option<Authorizer*> authorizer = None();

  auto authorizerNames = strings::split(flags.authorizers, ",");
  if (authorizerNames.empty()) {
    EXIT(EXIT_FAILURE) << "No authorizer specified";
  }
  if (authorizerNames.size() > 1) {
    EXIT(EXIT_FAILURE) << "Multiple authorizers not supported";
  }
  std::string authorizerName = authorizerNames[0];

  // NOTE: The flag --authorizers overrides the flag --acls, i.e. if
  // a non default authorizer is requested, it will be used and
  // the contents of --acls will be ignored.
  // TODO(arojas): Add support for multiple authorizers.
  if (authorizerName != master::DEFAULT_AUTHORIZER ||
      flags.acls.isSome()) {
    Try<Authorizer*> create = Authorizer::create(authorizerName);

    if (create.isError()) {
      EXIT(EXIT_FAILURE) << "Could not create '" << authorizerName
                         << "' authorizer: " << create.error();
    }

    authorizer = create.get();

    LOG(INFO) << "Using '" << authorizerName << "' authorizer";

    if (authorizerName == master::DEFAULT_AUTHORIZER) {
      Try<Nothing> initialize = authorizer.get()->initialize(flags.acls.get());

      if (initialize.isError()) {
        // Failing to initialize the authorizer leads to undefined
        // behavior, therefore we default to skip authorization
        // altogether.
        LOG(WARNING) << "Authorization disabled: Failed to initialize '"
                     << authorizerName << "' authorizer: "
                     << initialize.error();

        delete authorizer.get();
        authorizer = None();
      }
    } else if (flags.acls.isSome()) {
      LOG(WARNING) << "Ignoring contents of --acls flag, because '"
                   << authorizerName << "' authorizer will be used instead "
                   << " of the default.";
    }
  }

  Option<shared_ptr<RateLimiter>> slaveRemovalLimiter = None();
  if (flags.slave_removal_rate_limit.isSome()) {
    // Parse the flag value.
    // TODO(vinod): Move this parsing logic to flags once we have a
    // 'Rate' abstraction in stout.
    vector<string> tokens =
      strings::tokenize(flags.slave_removal_rate_limit.get(), "/");

    if (tokens.size() != 2) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>";
    }

    Try<int> permits = numify<int>(tokens[0]);
    if (permits.isError()) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>"
        << ": " << permits.error();
    }

    Try<Duration> duration = Duration::parse(tokens[1]);
    if (duration.isError()) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>"
        << ": " << duration.error();
    }

    slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get());
  }

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
Esempio n. 17
0
/*
 * Go through paces to compile firewall which may be a member of a
 * cluster.  Note that both firewall and cluster are defined by their
 * unique string IDs.  This is necessary because CompilerDriver
 * operates with a copy of the object database which is not exposed
 * outside, so the caller can not provide pointers to these obejcts.
 */
QString CompilerDriver_ipt::run(const std::string &cluster_id,
                                const std::string &firewall_id,
                                const std::string &single_rule_id)
{

    FWObjectDatabase::registerObjectType(combinedAddress::TYPENAME,
                                         &create_combinedAddress);

    // see #2212 Create temporary copy of the firewall and cluster
    // objects and pass them to the compilers.

    Cluster *cluster = NULL;
    Firewall *fw = NULL;

    getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw);

    string generated_script;

    try
    {
        clearReadOnly(fw);

        // Copy rules from the cluster object
        populateClusterElements(cluster, fw);

        commonChecks2(cluster, fw);

        string fw_version = fw->getStr("version");
        if (fw_version.empty()) fw_version = "(any version)";
        string platform = fw->getStr("platform");
        string host_os = fw->getStr("host_OS");

        FWOptions* options = fw->getOptionsObject();
        string s;

        // Note that fwobjectname may be different from the name of the
        // firewall fw This happens when we compile a member of a cluster
        current_firewall_name = fw->getName().c_str();

        if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" &&
            fw->getOptionsObject()->getBool("use_iptables_restore"))
        {
            abort("Prolog place \"after policy reset\" can not be used"
                  " when policy is activated with iptables-restore");
        }

        string firewall_dir = options->getStr("firewall_dir");
        if (firewall_dir=="") firewall_dir="/etc";

        bool debug=options->getBool("debug");
        QString shell_dbg = (debug)?"set -x":"" ;

        std::auto_ptr<OSConfigurator_linux24> oscnf;

        string platform_family = Resources::platform_res[platform]->
            getResourceStr("/FWBuilderResources/Target/family");
        string os_family = Resources::os_res[host_os]->
            getResourceStr("/FWBuilderResources/Target/family");

        bool supports_prolog_epilog = Resources::getTargetCapabilityBool(
            platform, "supports_prolog_epilog");

        if (!supports_prolog_epilog)
        {
            prolog_done = true;
            epilog_done = true;
        }

        string os_variant = DISTRO;

/* minimal sanity checking */
        if (os_family == "ipcop")
        {
            os_variant = "ipcop";

            // can't use iptables-restore with ipcop
            fw->getOptionsObject()->setBool("use_iptables_restore", false);
            // ipcop has its own iptables commands that accept packets
            // in states ESTABLISHED,RELATED
            fw->getOptionsObject()->setBool("accept_established", false);

            oscnf = std::auto_ptr<OSConfigurator_linux24>(
                new OSConfigurator_ipcop(objdb , fw, false));
        }

        if (os_family == "linux24" ||
            os_family == "openwrt" ||
            os_family == "dd-wrt-nvram" ||
            os_family == "dd-wrt-jffs" ||
            os_family == "sveasoft")
            oscnf = std::auto_ptr<OSConfigurator_linux24>(
                new OSConfigurator_linux24(objdb , fw, false));

        if (os_family == "secuwall")
            oscnf = std::auto_ptr<OSConfigurator_linux24>(
                new OSConfigurator_secuwall(objdb , fw, false));

        if (oscnf.get()==NULL)
        {
            abort("Unrecognized host OS " + fw->getStr("host_OS") +
                  "  (family " + os_family+")");
            return "";
        }

        if (inTestMode()) oscnf->setTestMode();
        if (inEmbeddedMode()) oscnf->setEmbeddedMode();

        oscnf->validateInterfaces();
        oscnf->prolog();

        list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
        list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);

        int routing_rules_count = 0;
        bool have_ipv4 = false;
        bool have_ipv6 = false;

        // track chains in each table separately. Can we have the same
        // chain in filter and mangle tables ? Would it be the same
        // chain, i.e. do we need to create it only once or do we create
        // it twice, in each table separately ? 
        // Using separate trackers we track and create chain in each
        // table separately.
        std::map<const std::string, bool> minus_n_commands_filter;
        std::map<const std::string, bool> minus_n_commands_mangle;
        std::map<const std::string, bool> minus_n_commands_nat;

        vector<int> ipv4_6_runs;

        findImportedRuleSets(fw, all_policies);
        findBranchesInMangleTable(fw, all_policies);
        findImportedRuleSets(fw, all_nat);

        try
        {
            AutomaticRules_ipt auto_rules(fw, persistent_objects);
            auto_rules.addConntrackRule();
            auto_rules.addFailoverRules();
        } catch (FWException &ex)
        {
            abort(ex.toString());
        }

        // assign unique rule ids that later will be used to generate
        // chain names.  This should be done after calls to
        // findImportedRuleSets()

        assignUniqueRuleIds(all_policies);
        assignUniqueRuleIds(all_nat);

        // command line options -4 and -6 control address family for which
        // script will be generated. If "-4" is used, only ipv4 part will 
        // be generated. If "-6" is used, only ipv6 part will be generated.
        // If neither is used, both parts will be done.

        if (options->getStr("ipv4_6_order").empty() ||
            options->getStr("ipv4_6_order") == "ipv4_first")
        {
            if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
            if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
        }

        if (options->getStr("ipv4_6_order") == "ipv6_first")
        {
            if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
            if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
        }

        for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i)
        {
            int policy_af = *i;
            bool ipv6_policy = (policy_af == AF_INET6);

            /*
              clear chain tracker map only between ipv4/ipv6 runs
              Don't clear it between compiler runs for different
              policy or nat objects for the same address family.
            */
            minus_n_commands_filter.clear();
            minus_n_commands_mangle.clear();
            minus_n_commands_nat.clear();

            /*
              We need to create and run preprocessor for this address
              family before nat and policy compilers, but if there are
              no nat / policy rules for this address family, we do not
              need preprocessor either.
            */

            // Count rules for each address family
            int nat_count = 0;
            int policy_count = 0;

            for (list<FWObject*>::iterator p=all_nat.begin();
                 p!=all_nat.end(); ++p)
            {
                NAT *nat = NAT::cast(*p);
                if (nat->matchingAddressFamily(policy_af)) nat_count++;
            }

            for (list<FWObject*>::iterator p=all_policies.begin();
                 p!=all_policies.end(); ++p)
            {
                Policy *policy = Policy::cast(*p);
                if (policy->matchingAddressFamily(policy_af)) policy_count++;
            }

            if (nat_count || policy_count)
            {
                Preprocessor_ipt* prep = new Preprocessor_ipt(
                    objdb , fw, ipv6_policy);
                prep->setSingleRuleCompileMode(single_rule_id);
                if (inTestMode()) prep->setTestMode();
                if (inEmbeddedMode()) prep->setEmbeddedMode();
                prep->compile();
                delete prep;
            }

            ostringstream automaitc_rules_stream;
            ostringstream automaitc_mangle_stream;
            ostringstream filter_rules_stream;
            ostringstream mangle_rules_stream;
            ostringstream nat_rules_stream;

            bool empty_output = true;

            // First, process branch NAT rulesets, then top NAT ruleset

            NAT *top_nat = NULL;
            for (list<FWObject*>::iterator p=all_nat.begin();
                 p!=all_nat.end(); ++p)
            {
                NAT *nat = NAT::cast(*p);
                if (!nat->matchingAddressFamily(policy_af)) continue;
                if (nat->isTop())
                {
                    top_nat = nat;
                    continue;
                }
                if (! processNatRuleSet(
                        fw,
                        nat,
                        single_rule_id,
                        nat_rules_stream,
                        oscnf.get(),
                        policy_af,
                        minus_n_commands_nat)) empty_output = false;
            }

            if (top_nat &&
                ! processNatRuleSet(
                    fw,
                    top_nat,
                    single_rule_id,
                    nat_rules_stream,
                    oscnf.get(),
                    policy_af,
                    minus_n_commands_nat)) empty_output = false;

            // first process all non-top rule sets, then all top rule sets
            for (int all_top = 0; all_top < 2; ++all_top)
            {
                for (list<FWObject*>::iterator p=all_policies.begin();
                     p!=all_policies.end(); ++p )
                {
                    Policy *policy = Policy::cast(*p);
                    if (!policy->matchingAddressFamily(policy_af)) continue;

                    if (policy->isTop() && all_top == 0) continue;
                    if (!policy->isTop() && all_top == 1) continue;

                    if (! processPolicyRuleSet(
                            fw,
                            policy,
                            single_rule_id,
                            filter_rules_stream,
                            mangle_rules_stream,
                            automaitc_rules_stream,
                            automaitc_mangle_stream,
                            oscnf.get(),
                            policy_af,
                            minus_n_commands_filter,
                            minus_n_commands_mangle)) empty_output = false;
                }
            }

            if (!empty_output && !single_rule_compile_on)
            {
                if (ipv6_policy)
                {
                    have_ipv6 = true;
                    generated_script += "\n\n";
                    generated_script += "# ================ IPv6\n";
                    generated_script += "\n\n";
                } else
                {
                    have_ipv4 = true;
                    generated_script += "\n\n";
                    generated_script += "# ================ IPv4\n";
                    generated_script += "\n\n";
                }
            }

            generated_script += dumpScript(fw,
                                           automaitc_rules_stream.str(),
                                           automaitc_mangle_stream.str(),
                                           nat_rules_stream.str(),
                                           mangle_rules_stream.str(),
                                           filter_rules_stream.str(),
                                           ipv6_policy);
            if (single_rule_compile_on)
                generated_script += "\n\n";
        }

        std::auto_ptr<RoutingCompiler_ipt> routing_compiler(
            new RoutingCompiler_ipt(objdb, fw, false, oscnf.get()));

        RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME));
        if (routing)
        {
            routing_compiler->setSourceRuleSet(routing);
            routing_compiler->setRuleSetName(routing->getName());
            routing_compiler->setPersistentObjects(persistent_objects);

            routing_compiler->setSingleRuleCompileMode(single_rule_id);
            routing_compiler->setDebugLevel( dl );
            if (rule_debug_on) routing_compiler->setDebugRule(drr);
            routing_compiler->setVerbose( verbose );
            if (inTestMode()) routing_compiler->setTestMode();
            if (inEmbeddedMode()) routing_compiler->setEmbeddedMode();

            if ( (routing_rules_count=routing_compiler->prolog()) > 0 )
            {
                routing_compiler->compile();
                routing_compiler->epilog();
            }

            if (routing_compiler->haveErrorsAndWarnings())
                all_errors.push_back(routing_compiler->getErrors("").c_str());
        }

        /*
         * compilers detach persistent objects when they finish, this
         * means at this point library persistent_objects is not part
         * of any object tree.
         */
        objdb->reparent(persistent_objects);

        if (haveErrorsAndWarnings())
        {
            all_errors.push_front(getErrors("").c_str());
        }

        if (single_rule_compile_on)
        {
            return formSingleRuleCompileOutput(
                QString::fromUtf8(
                    (getErrors("") + 
                     generated_script +
                     routing_compiler->getCompiledScript()).c_str()));
        }


/*
 * These store generated configuration internally, extract it later using
 * OSConfiguration::getGeneratedFiles();
 */
        oscnf->processFirewallOptions();

/*
 * now write generated scripts to files
 */

        char *timestr = NULL;
        time_t tm;
        struct tm *stm;

        tm = time(NULL);
        stm = localtime(&tm);
        timestr = strdup(ctime(&tm));
        timestr[strlen(timestr)-1] = '\0';

        /*
         * assemble the script and then perhaps post-process it if it
         * should run on Linksys device with sveasoft firmware
         */
        Configlet script_skeleton(fw, "linux24", "script_skeleton");
        script_skeleton.removeComments();

        QString script_buffer;
        QTextStream script(&script_buffer, QIODevice::WriteOnly);

        /*
         * text comes from the compiler in UTF-8 (because all comments
         * and object names are stored in UTF-8 in objects and
         * compilers do not decode). We have a choice: 1) apply
         * QString::fromUtf8() to all strings coming from the compiler
         * to convert to Unicode and rely on QTextStream to convert
         * back to UTF-8 in the generated file, or 2) leavle strings
         * coming from compilers as-is and tell the stream to not
         * covert.
         */

        script_buffer = "";

        script_skeleton.setVariable("shell_debug", shell_dbg);

        script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n";
        script << "export PATH" << "\n";

        script_skeleton.setVariable("path", script_buffer);
        script_buffer = "";

        Configlet script_constants(fw, "linux24", "constants");
        script_skeleton.setVariable("constants", script_constants.expand());

        /*
         * print definitions for variables IPTABLES, IP, LOGGER. Some
         * day we may add a choice of os_variant in the GUI. Right now
         * paths are either default for a given os_variant, or custom
         * strings entered by user in the GUI and stored in firewall
         * options.
         */
        script_skeleton.setVariable("tools",
                                    oscnf->printPathForAllTools(os_variant).c_str());
        script_skeleton.setVariable("shell_functions",
                                    oscnf->printShellFunctions(have_ipv6).c_str());
        script_skeleton.setVariable("run_time_address_tables",
                                    oscnf->printRunTimeAddressTablesCode().c_str());
        script_skeleton.setVariable("using_ipset", oscnf->usingIpSetModule());

        if (supports_prolog_epilog)
        {
            //script_skeleton.setVariable("prolog_epilog",
            //                         oscnf->printPrologEpilogFunctions().c_str());
            script_skeleton.setVariable(
                "prolog_script", 
                fw->getOptionsObject()->getStr("prolog_script").c_str());
            script_skeleton.setVariable(
                "epilog_script", 
                fw->getOptionsObject()->getStr("epilog_script").c_str());
        }

        ostringstream ostr;

        ostr << "# Configure interfaces" << endl;

        if ( options->getBool("configure_bonding_interfaces") ) 
            ostr << oscnf->printBondingInterfaceConfigurationCommands();

        if ( options->getBool("configure_vlan_interfaces")) 
            ostr << oscnf->printVlanInterfaceConfigurationCommands();

        if ( options->getBool("configure_bridge_interfaces") ) 
            ostr << oscnf->printBridgeInterfaceConfigurationCommands();


        if ( options->getBool("configure_interfaces") ||
             options->getBool("manage_virtual_addr"))
        {
            if ( options->getBool("configure_interfaces"))
                ostr << oscnf->printInterfaceConfigurationCommands();
            else
                ostr << oscnf->printVirtualAddressesForNatCommands();
        }

        ostr << oscnf->printCommandsToClearKnownInterfaces();

        ostr << oscnf->printDynamicAddressesConfigurationCommands();

        script_skeleton.setVariable(
            "configure_interfaces", indent(4, QString(ostr.str().c_str())));



        // verify_interfaces checks bridge interfaces so run it
        // after those have been created
        if (options->getBool("verify_interfaces")) 
        {
            list<FWObject*> l2=fw->getByType(Interface::TYPENAME);
            if (l2.empty() )
                script_skeleton.setVariable("verify_interfaces", QString());
            else
                script_skeleton.setVariable("verify_interfaces",
                                            oscnf->printVerifyInterfacesCommands().c_str());
        } else
            script_skeleton.setVariable("verify_interfaces", QString());
    
        string prolog_place = fw->getOptionsObject()->getStr("prolog_place");
        if (prolog_place == "") prolog_place="top";

        /* there is no way to stick prolog commands between iptables
         * reset and iptables rules if we use iptables-restore to
         * activate policy. Therefore, if prolog needs to be ran after
         * iptables flush and we use iptables-restore, we run prolog
         * on top of the script.
         */
        if (!prolog_done &&
            (prolog_place == "top" ||
             (prolog_place == "after_flush" && 
              fw->getOptionsObject()->getBool("use_iptables_restore"))))
        {
            script_skeleton.setVariable("prolog_top", 1);
            script_skeleton.setVariable("prolog_after_interfaces", 0);
            script_skeleton.setVariable("prolog_after_flush", 0);
            prolog_done = true;
        }

        if (!prolog_done && prolog_place == "after_interfaces")
        {
            script_skeleton.setVariable("prolog_top", 0);
            script_skeleton.setVariable("prolog_after_interfaces", 1);
            script_skeleton.setVariable("prolog_after_flush", 0);
            prolog_done = true;
        }

        if (!prolog_done && prolog_place == "after_flush")
        {
            script_skeleton.setVariable("prolog_top", 0);
            script_skeleton.setVariable("prolog_after_interfaces", 0);
            script_skeleton.setVariable("prolog_after_flush", 1);
            prolog_done = true;
        }

        script_skeleton.setVariable("load_modules",
                                    oscnf->generateCodeForProtocolHandlers().c_str());
        script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"nat":"");
        script_skeleton.setVariable("load_modules_with_ipv6", (have_ipv6)?"ipv6":"");

        script_skeleton.setVariable("ip_forward_commands",
                                    oscnf->printIPForwardingCommands().c_str());

        /*
         * script body begins here
         */
        script_buffer = "";

        if (oscnf->haveErrorsAndWarnings())
        {
            all_errors.push_back(oscnf->getErrors("").c_str());
        }

        // convert from UTF8 to make sure localized comments are shown correctly
        // script << oscnf->getCompiledScript().c_str();
        // script << generated_script.c_str();
        // script << routing_compiler->getCompiledScript().c_str();

        script << QString::fromUtf8(oscnf->getCompiledScript().c_str());
        script << QString::fromUtf8(generated_script.c_str());
        script << QString::fromUtf8(routing_compiler->getCompiledScript().c_str());

        script << endl;

        script_skeleton.setVariable("script_body", indent(4, script_buffer));

        script_skeleton.setVariable("timestamp", timestr);
        script_skeleton.setVariable("tz", tzname[stm->tm_isdst]);
        script_skeleton.setVariable("user", user_name);
        script_skeleton.setVariable("database", objdb->getFileName().c_str());

        /*
         * Call reset_all function to flush and reset iptables, but only
         * do this if we do not use iptables_restore. Reset is done as part
         * of iptables-restore script in the latter case and commands are
         * added in PolicyCompiler_ipt::flushAndSetDefaultPolicy()
         */
        script_skeleton.setVariable("not_using_iptables_restore",
                                    ! fw->getOptionsObject()->getBool("use_iptables_restore"));

        script_buffer = "";
        if (have_ipv4) script << "  reset_iptables_v4" << endl;
        if (have_ipv6) script << "  reset_iptables_v6" << endl;
        script_skeleton.setVariable("reset_all", script_buffer);

        script_buffer = "";

        Configlet block_action(fw, "linux24", "block_action");
        if (XMLTools::version_compare(fw_version, "1.4.20") >= 0)
            block_action.setVariable("opt_wait", "-w");
        else
            block_action.setVariable("opt_wait", "");

        block_action.collapseEmptyStrings(true);

        // the name of the option is historical (including the typo)
        if (fw->getOptionsObject()->getBool("add_mgmt_ssh_rule_when_stoped"))
        {
            std::auto_ptr<PolicyCompiler_ipt> policy_compiler =
                createPolicyCompiler(fw, false, NULL,  NULL);
            PolicyCompiler_ipt::PrintRule* print_rule =
                policy_compiler->createPrintRuleProcessor();
            print_rule->setContext(policy_compiler.get());
            print_rule->_printBackupSSHAccessRules(&block_action);
        } else
        {
            block_action.setVariable("mgmt_access", 0);
        }

        script_skeleton.setVariable("block_action", block_action.expand());


        Configlet stop_action(fw, "linux24", "stop_action");
        stop_action.collapseEmptyStrings(true);
        stop_action.setVariable("have_ipv4", have_ipv4);
        stop_action.setVariable("have_ipv6", have_ipv6);

        if (XMLTools::version_compare(fw_version, "1.4.20") >= 0)
            stop_action.setVariable("opt_wait", "-w");
        else
            stop_action.setVariable("opt_wait", "");

        script_skeleton.setVariable("stop_action", stop_action.expand());



        Configlet status_action(fw, "linux24", "status_action");
        status_action.collapseEmptyStrings(true);
        script_skeleton.setVariable("status_action", status_action.expand());

        Configlet top_comment(fw, "linux24", "top_comment");

        top_comment.setVariable("version", VERSION);
        top_comment.setVariable("timestamp", timestr);
        top_comment.setVariable("tz", tzname[stm->tm_isdst]);
        top_comment.setVariable("user", user_name);
        top_comment.setVariable("database", objdb->getFileName().c_str());

        determineOutputFileNames(cluster, fw, !cluster_id.empty(),
                                 QStringList(""), QStringList("fw"),
                                 QStringList("script_name_on_firewall"));

        script_buffer = "";
        script << MANIFEST_MARKER
               << "* "
               << this->escapeFileName(file_names[FW_FILE]);

        if (!remote_file_names[FW_FILE].isEmpty())
            script << " " << this->escapeFileName(remote_file_names[FW_FILE]);
        script << "\n";

        /* Add additional files to manifest if specified.  Currently there
         * are no GUI controls to let user provide alternative names for
         * these on the firewall. See description of manifest format in
         * comments in src/gui/FirewallInstaller.cpp
         */
        map<string, string> file_list = oscnf->getGeneratedFiles();
        if (!file_list.empty())
        {
            info(" Adding additional files to manifest");
            map<string, string>::const_iterator c_iter = file_list.begin();
            for (; c_iter != file_list.end(); ++c_iter)
            {
                string name = c_iter->first;
                string dest = c_iter->second;
                script << MANIFEST_MARKER << this->escapeFileName(name.c_str());
                if (!dest.empty()) script << " " << dest;
                script << "\n";
            }
        }

        top_comment.setVariable("manifest", script_buffer);
        top_comment.setVariable("platform", platform.c_str());
        top_comment.setVariable("fw_version", fw_version.c_str());
        top_comment.setVariable("comment", prepend("# ", fw->getComment().c_str()));

        script_skeleton.setVariable("top_comment", top_comment.expand());
        script_skeleton.setVariable("errors_and_warnings",
                                    prepend("# ", all_errors.join("\n")));

        info("Output file name: " + file_names[FW_FILE].toStdString());

        QFile fw_file(file_names[FW_FILE]);
        if (fw_file.open(QIODevice::WriteOnly))
        {
            QTextStream fw_str(&fw_file);
            fw_str << script_skeleton.expand();
            fw_file.close();
            fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
                                   QFile::ReadGroup | QFile::ReadOther |
                                   QFile::ExeOwner | 
                                   QFile::ExeGroup |
                                   QFile::ExeOther );

            info(" Compiled successfully");

        } else
        {
            QString err(" Failed to open file %1 for writing: %2; Current dir: %3");
            abort(err.arg(fw_file.fileName())
                  .arg(fw_file.error()).arg(QDir::current().path()).toStdString());
        }

        free(timestr);

        if (!all_errors.isEmpty())
            status = BaseCompiler::FWCOMPILER_WARNING;

    }
    catch (FWException &ex)
    {
        status = BaseCompiler::FWCOMPILER_ERROR;
        return QString::fromUtf8(ex.toString().c_str());
    }
    
    return "";
}
Esempio n. 18
0
int main(int argc, char** argv)
{
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  master::Flags flags;

  // The following flags are executable specific (e.g., since we only
  // have one instance of libprocess per execution, we only want to
  // advertise the IP and port option once, here).
  Option<string> ip;
  flags.add(&ip, "ip", "IP address to listen on");

  uint16_t port;
  flags.add(&port, "port", "Port to listen on", MasterInfo().port());

  Option<string> zk;
  flags.add(&zk,
            "zk",
            "ZooKeeper URL (used for leader election amongst masters)\n"
            "May be one of:\n"
            "  zk://host1:port1,host2:port2,.../path\n"
            "  zk://username:password@host1:port1,host2:port2,.../path\n"
            "  file:///path/to/file (where file contains one of the above)");

  Try<Nothing> load = flags.load("MESOS_", argc, argv);

  if (load.isError()) {
    cerr << flags.usage(load.error()) << endl;
    return EXIT_FAILURE;
  }

  if (flags.version) {
    version();
    return EXIT_SUCCESS;
  }

  if (flags.help) {
    cout << flags.usage() << endl;
    return EXIT_SUCCESS;
  }

  // Initialize modules. Note that since other subsystems may depend
  // upon modules, we should initialize modules before anything else.
  if (flags.modules.isSome()) {
    Try<Nothing> result = ModuleManager::load(flags.modules.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
    }
  }

  // Initialize hooks.
  if (flags.hooks.isSome()) {
    Try<Nothing> result = HookManager::initialize(flags.hooks.get());
    if (result.isError()) {
      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
    }
  }

  // Initialize libprocess.
  if (ip.isSome()) {
    os::setenv("LIBPROCESS_IP", ip.get());
  }

  os::setenv("LIBPROCESS_PORT", stringify(port));

  process::initialize("master");

  logging::initialize(argv[0], flags, true); // Catch signals.

  LOG(INFO) << "Build: " << build::DATE << " by " << build::USER;

  LOG(INFO) << "Version: " << MESOS_VERSION;

  if (build::GIT_TAG.isSome()) {
    LOG(INFO) << "Git tag: " << build::GIT_TAG.get();
  }

  if (build::GIT_SHA.isSome()) {
    LOG(INFO) << "Git SHA: " << build::GIT_SHA.get();
  }

  // Create an instance of allocator.
  const std::string allocatorName = flags.allocator;
  Try<Allocator*> allocator = Allocator::create(allocatorName);

  if (allocator.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create '" << allocatorName
      << "' allocator: " << allocator.error();
  }

  CHECK_NOTNULL(allocator.get());
  LOG(INFO) << "Using '" << allocatorName << "' allocator";

  state::Storage* storage = NULL;
  Log* log = NULL;

  if (flags.registry == "in_memory") {
    if (flags.registry_strict) {
      EXIT(EXIT_FAILURE)
        << "Cannot use '--registry_strict' when using in-memory storage"
        << " based registry";
    }
    storage = new state::InMemoryStorage();
  } else if (flags.registry == "replicated_log" ||
             flags.registry == "log_storage") {
    // TODO(bmahler): "log_storage" is present for backwards
    // compatibility, can be removed before 0.19.0.
    if (flags.work_dir.isNone()) {
      EXIT(EXIT_FAILURE)
        << "--work_dir needed for replicated log based registry";
    }

    Try<Nothing> mkdir = os::mkdir(flags.work_dir.get());
    if (mkdir.isError()) {
      EXIT(EXIT_FAILURE)
        << "Failed to create work directory '" << flags.work_dir.get()
        << "': " << mkdir.error();
    }

    if (zk.isSome()) {
      // Use replicated log with ZooKeeper.
      if (flags.quorum.isNone()) {
        EXIT(EXIT_FAILURE)
          << "Need to specify --quorum for replicated log based"
          << " registry when using ZooKeeper";
      }

      Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get());
      if (url.isError()) {
        EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error();
      }

      log = new Log(
          flags.quorum.get(),
          path::join(flags.work_dir.get(), "replicated_log"),
          url.get().servers,
          flags.zk_session_timeout,
          path::join(url.get().path, "log_replicas"),
          url.get().authentication,
          flags.log_auto_initialize);
    } else {
      // Use replicated log without ZooKeeper.
      log = new Log(
          1,
          path::join(flags.work_dir.get(), "replicated_log"),
          set<UPID>(),
          flags.log_auto_initialize);
    }
    storage = new state::LogStorage(log);
  } else {
    EXIT(EXIT_FAILURE)
      << "'" << flags.registry << "' is not a supported"
      << " option for registry persistence";
  }

  CHECK_NOTNULL(storage);

  state::protobuf::State* state = new state::protobuf::State(storage);
  Registrar* registrar = new Registrar(flags, state);
  Repairer* repairer = new Repairer();

  Files files;

  MasterContender* contender;
  MasterDetector* detector;

  // TODO(vinod): 'MasterContender::create()' should take
  // Option<string>.
  Try<MasterContender*> contender_ = MasterContender::create(zk.get(""));
  if (contender_.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master contender: " << contender_.error();
  }
  contender = contender_.get();

  // TODO(vinod): 'MasterDetector::create()' should take
  // Option<string>.
  Try<MasterDetector*> detector_ = MasterDetector::create(zk.get(""));
  if (detector_.isError()) {
    EXIT(EXIT_FAILURE)
      << "Failed to create a master detector: " << detector_.error();
  }
  detector = detector_.get();

  Option<Authorizer*> authorizer = None();
  if (flags.acls.isSome()) {
    Try<Owned<Authorizer>> create = Authorizer::create(flags.acls.get());

    if (create.isError()) {
      EXIT(EXIT_FAILURE)
        << "Failed to initialize the authorizer: "
        << create.error() << " (see --acls flag)";
    }

    // Now pull out the authorizer but need to make a copy since we
    // get a 'const &' from 'Try::get'.
    authorizer = Owned<Authorizer>(create.get()).release();
  }

  Option<shared_ptr<RateLimiter>> slaveRemovalLimiter = None();
  if (flags.slave_removal_rate_limit.isSome()) {
    // Parse the flag value.
    // TODO(vinod): Move this parsing logic to flags once we have a
    // 'Rate' abstraction in stout.
    vector<string> tokens =
      strings::tokenize(flags.slave_removal_rate_limit.get(), "/");

    if (tokens.size() != 2) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>";
    }

    Try<int> permits = numify<int>(tokens[0]);
    if (permits.isError()) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>"
        << ": " << permits.error();
    }

    Try<Duration> duration = Duration::parse(tokens[1]);
    if (duration.isError()) {
      EXIT(EXIT_FAILURE)
        << "Invalid slave_removal_rate_limit: "
        << flags.slave_removal_rate_limit.get()
        << ". Format is <Number of slaves>/<Duration>"
        << ": " << duration.error();
    }

    slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get());
  }

  if (flags.firewall_rules.isSome()) {
    vector<Owned<FirewallRule>> rules;

    const Firewall firewall = flags.firewall_rules.get();

    if (firewall.has_disabled_endpoints()) {
      hashset<string> paths;

      foreach (const string& path, firewall.disabled_endpoints().paths()) {
        paths.insert(path);
      }

      rules.emplace_back(new DisabledEndpointsFirewallRule(paths));
    }
Esempio n. 19
0
void instDialog::setFlags(QTreeWidgetItem* item)
{
    int obj_id = item->data(0, Qt::UserRole).toInt();
    Firewall *fw = Firewall::cast(project->db()->findInIndex(obj_id));
    QTreeWidgetItem* parent = item->parent();

    time_t lm = fw->getInt("lastModified");
    time_t lc = fw->getInt("lastCompiled");
    time_t li = fw->getInt("lastInstalled");
    QDateTime dt;

    if (fwbdebug)
    {
        qDebug() << "instDialog::setFlags"
                 << item->text(0)
                 << "parent=" << parent
                 << "fw=" << fw
                 << "Firewall::isA(fw)=" << Firewall::isA(fw)
                 << "lm=" << lm
                 << "lc=" << lc
                 << "li=" << li
                 << "compile_only=" << compile_only;
        qDebug() << "fw->needsCompile()" << fw->needsCompile()
                 << "checkIfNeedToCompile(fw)=" << checkIfNeedToCompile(fw);
    }

    // need to skip the secondary cluster members if platform only
    // allows installations on the primary (e.g. PIX).  Note that
    // platform attribute must be the same in the cluster and member
    // firewalls objects. See #998

    string platform = fw->getStr("platform");
    bool install_only_on_primary_member = Resources::getTargetCapabilityBool(
        platform, "install_only_on_primary");

    Cluster *cluster = NULL;
    FWObject *master_interface = NULL;

    if (parent)
    {
        int obj_id = parent->data(0, Qt::UserRole).toInt();
        cluster = Cluster::cast(project->db()->findInIndex(obj_id));
        if (cluster)
        {
            FWObject *state_sync_group =
                cluster->getFirstByType(StateSyncClusterGroup::TYPENAME);
            // use state sync group to find which member firewall is
            // master.  This is only needed for platforms that install
            // only on master (PIX at this time)
            if (state_sync_group)
            {
                string master_id = state_sync_group->getStr("master_iface");
                for (FWObjectTypedChildIterator grp_it =
                         state_sync_group->findByType(FWObjectReference::TYPENAME);
                     grp_it != grp_it.end(); ++grp_it)
                {
                    FWObject *iface = FWObjectReference::getObject(*grp_it);
                    if (FWObjectDatabase::getStringId(iface->getId()) == master_id)
                    {
                        master_interface = iface;
                        break;
                    }
                }
            }
        }
    }

    // Real firewalls get checkbox for install
    if (Firewall::isA(fw))
    {
        bool checked = false;

        if (!compile_only)
        {
            checked = checkIfNeedToInstall(fw);
            if (cluster)
            {
                // override if checkIfNeedToCompile() is true for the
                // parent cluster.
                if (checkIfNeedToCompile(cluster))
                {
                    checked = true;
                }
            }
            item->setCheckState(INSTALL_CHECKBOX_COLUMN,
                                checked?Qt::Checked:Qt::Unchecked);

            // If this platform requires installation only on
            // the master, disable and uncheck checkbox for the standby.
            if (install_only_on_primary_member && master_interface != NULL)
            {
                QString txt = item->text(0);
                if (master_interface->isChildOf(fw))
                {
                    // Master
                    item->setText(0, QString("%1 (master)").arg(txt));
                } else
                {
                    // Standby
                    item->setText(0, QString("%1 (standby)").arg(txt));
                    item->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked);
                    item->setFlags(0);
                }
            }
        }

        if (cluster==NULL)
        {
            // we are adding firewall that is not cluster member, it
            // needs "compile" checkbox
            checked = checkIfNeedToCompile(fw);
            item->setCheckState(COMPILE_CHECKBOX_COLUMN,
                                checked?Qt::Checked:Qt::Unchecked);
        }
    }

    int num_members = 0;
    // Clusters only get checkbox for compile, and only if they have members.
    if (Cluster::isA(fw))
    {
        list<Firewall*> members;
        Cluster::cast(fw)->getMembersList(members);
        num_members = members.size();
        if (num_members)
        {
            bool checked = checkIfNeedToCompile(fw);
            item->setCheckState(COMPILE_CHECKBOX_COLUMN,
                                checked?Qt::Checked:Qt::Unchecked);
        }
    }

    dt.setTime_t(lm);
    item->setText(LAST_MODIFIED_COLUMN, (lm)?dt.toString():QString("Never"));

    dt.setTime_t(lc);
    item->setText(LAST_COMPILED_COLUMN, (lc)?dt.toString():QString("Never"));

    dt.setTime_t(li);
    item->setText(LAST_INSTALLED_COLUMN, (li)?dt.toString():QString("Never"));
}