diff --git a/doc/ChangeLog b/doc/ChangeLog index 0d93ac071..911e296b7 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,10 @@ 2011-04-15 vadim + * fwbedit.cpp (main): see #2328 "Add ability to run firewall import + from the command line". This has been implemented as a new function + "import" in fwbedit. See man page fwbedit(1) and "fwbuilder -h" for + more details. + * iptables.g (multiport_tcp_udp_port_spec): see #2245 fixed bug in parser for iptables that prevented correct import of iptables rules using module "multiport" with port range matches. diff --git a/doc/fwbedit.1 b/doc/fwbedit.1 index 6e21e4f7e..3ab713510 100644 --- a/doc/fwbedit.1 +++ b/doc/fwbedit.1 @@ -31,37 +31,29 @@ below). Creates new object. -.PP - -f file.fwb: data file -.PP - -t objtype: create new object of this type -.PP --p parent: create new object as a child of this object. This parameter -is mandatory. If you are adding an address to an interface, -corresponding interface onkect must be specified as the -parent. Similarly if you need to add an interface to a host or a -firewall, corresponding host or firewall object is the parent. If you -are adding an object to one of the standard folders, the parent is the -library you want to add the object to or correct full path to the -folder in the tree. -.PP - -n name: the name of the new object -.PP - -c txt: specify comment for the new object -.PP - -a attribute1[,attribute2...] : specify attributes that - define parameters of the new object (see below) - + -f file.fwb: data file + -t objtype: create new object of this type + -p parent: create new object as a child of this object. + This parameter is mandatory. If you are adding an address + to an interface, corresponding interface onkect must be + specified as the parent. Similarly if you need to add an + interface to a host or a firewall, corresponding host or + firewall object is the parent. If you are adding an + object to one of the standard folders, the parent is the + library you want to add the object to or correct full + path to the folder in the tree. + -n name: the name of the new object + -c txt: specify comment for the new object + -a attribute1[,attribute2...] : specify attributes that + define parameters of the new object (see below) .B delete -f file.fwb -o object Deletes object specified by its full path in the tree or object ID. -.PP - -f file.fwb: data file -.PP - -o object: object to be deleted, full path or ID + -f file.fwb: data file + -o object: object to be deleted, full path or ID @@ -70,14 +62,10 @@ Deletes object specified by its full path in the tree or object ID. Modifies object specified by its full path in the tree or object ID. Object can not be renamed using this operation. -.PP - -f file.fwb: data file -.PP - -o object: object to be deleted, full path or ID -.PP - -c txt: specify comment for the new object -.PP - -a attribute1[,attribute2...] : specify attributes that + -f file.fwb: data file + -o object: object to be deleted, full path or ID + -c txt: specify comment for the new object + -a attribute1[,attribute2...] : specify attributes that define parameters of the new object (see below) @@ -86,28 +74,25 @@ Object can not be renamed using this operation. Prints name and ID of an object. -.PP - -f file.fwb: data file -.PP - -o object: object to print, full path or ID -.PP --r print specified object and all objects under it in the tree -.PP --c print only children objects of the given object but do not - print the object itself. -.PP --d print full dump of all object's attributes including internal debugging -information if available, this can be very verbose. -.PP --Fformat_string Program recognizes macros in the format string and -replaces them with values of corresponding object's attributes. Macro -is the name of the attribute surrounded with '%', such as '%name%' -or '%address%'. Here is the list of some attribute names: "id", -"name", "path", "comment", "type", "address", "netmask", -"dnsname". TCP and UDP service objects provide attributes -"src_range_start", "src_range_end", "dst_range_start", "dst_range_end" -for the source and destination port ranges. ICMP and ICMP6 service -objects have attributes "icmp_type" and "icmp_code". + -f file.fwb: data file + -o object: object to print, full path or ID + -r print specified object and all objects under it in the tree + -c print only children objects of the given object but do not + print the object itself. + -d print full dump of all object's attributes including internal + debugging information if available, this can be very + verbose. + -Fformat_string Program recognizes macros in the format string + and replaces them with values of corresponding object's + attributes. Macro is the name of the attribute surrounded + with '%', such as '%name%' or '%address%'. Here is the + list of some attribute names: "id", "name", "path", + "comment", "type", "address", "netmask", "dnsname". TCP + and UDP service objects provide attributes + "src_range_start", "src_range_end", "dst_range_start", + "dst_range_end" for the source and destination port + ranges. ICMP and ICMP6 service objects have attributes + "icmp_type" and "icmp_code". @@ -116,13 +101,10 @@ objects have attributes "icmp_type" and "icmp_code". Adds object specified by path or ID to a group, also specified by its path or ID. -.PP - -f file.fwb: data file -.PP - -g group: group the object should be added to, + -f file.fwb: data file + -g group: group the object should be added to, full path or ID -.PP - -o object: object to be deleted, full path or ID + -o object: object to be deleted, full path or ID @@ -130,14 +112,10 @@ path or ID. Removes object from a group. -.PP - -f file.fwb: data file -.PP - -g group: group the object should be removed from, - full path or ID -.PP - -o object: object to be deleted, full path or ID - + -f file.fwb: data file + -g group: group the object should be removed from, + full path or ID + -o object: object to be deleted, full path or ID .B upgrade -f file.fwb @@ -164,6 +142,25 @@ combined object tree saved in file1.fwb -i file.fwb: data file #2 +.B import -f file1.fwb -i firewall_config.txt -o path_to_firewall_object + +Firewall configuration from file firewall_config.txt is parsed and +imported into data file file1.fwb. The program creates new firewall +object located in the library and with the name defined by its path +path_to_firewall_object. This has to be full path, beginning with the +library name, such as "/User/Firewalls/my_new_firewall" + + -f file.fwb: data file #1 + -i config.txt: firewall configuration file + -o object_path + +currently (as of v4.2.0) fwbuilder supports import of iptables +configuration saved with iptables-save command, as well as import of +Cisco router IOS configuration, Cisco PIX, ASA and FWSM firewalls +saved with "show run" command. + + + .SH ATTRIBUTES FOR THE NEW OBJECTS, BY TYPE .PP diff --git a/src/fwbedit/fwbedit.cpp b/src/fwbedit/fwbedit.cpp index 9b38d3a35..67ef45363 100644 --- a/src/fwbedit/fwbedit.cpp +++ b/src/fwbedit/fwbedit.cpp @@ -101,9 +101,24 @@ extern int errno; #include "fwbedit.h" #include "upgradePredicate.h" +#include "FWWindow.h" +#include "FWBSettings.h" +#include "FWBApplication.h" +#include "UserWorkflow.h" + +#include + + using namespace libfwbuilder; using namespace std; + +FWWindow *mw = NULL; +FWBSettings *st = NULL; +FWBApplication *app = NULL; +UserWorkflow *wfl; +int sig = FWB_SIG; + string cmd_str = ""; command cmd = NONE; @@ -118,123 +133,9 @@ FWObjectDatabase *objdb = NULL; int fwbdebug = 0; -void usage() + +void list_attributes() { - cout << "Firewall Builder: general purpose object tree editing tool" - << endl; - cout << "Version " << VERSION << endl; - cout << endl; - cout << "Usage: fwbedit command [options]" << endl; - cout << endl; - - cout << "Command is one of:" << endl; - cout << " new create new object" << endl; - cout << " delete delete object" << endl; - cout << " modify modify object" << endl; - cout << " list print object" << endl; - cout << " add add object to a group" << endl; - cout << " remove remove object from a group" << endl; - cout << " upgrade upgrade data file" << endl; - cout << " checktree check object tree and repair if necessary" << endl; - cout << " merge merge one data file into another" << endl; - cout << endl; - - cout << "Options:" << endl; - cout << endl; - cout << - " new -f file.fwb -t objtype -n name -c comment " - "-p parent [-a attrs]\n" - "\n" - " -f file.fwb: data file\n" - " -t objtype: create a new object of this type\n" - " -n name: the name of the new object\n" - " -c txt: specify comment for the new object\n" - " -a attribute1[,attribute2...] : specify attributes that\n" - " define parameters of the new object (see below)\n"; - cout << endl; - - cout << - " delete -f file.fwb -o object\n" - "\n" - " -f file.fwb: data file\n" - " -o object: object to be deleted, full path or ID\n"; - cout << endl; - - cout << - " modify -f file.fwb -o object -c comment [-a attrs]\n" - "\n" - " -f file.fwb: data file\n" - " -o object: object to be modified, full path or ID\n" - " -c txt: specify comment for the new object\n" - " -a attribute1[,attribute2...] : specify attributes that\n" - " define parameters of the new object (see below)\n"; - cout << endl; - - cout << - " list -f file.fwb -o object [-r|-c] [-d|-Fformat]\n" - "\n" - " -f file.fwb: data file\n" - " -o object: object to print, full path or ID\n" - " -r print given object and all object below it in the tree\n" - " -c print all children of given object but not the object\n" - " itself\n" - " -d print full dump of all object's attributes including\n" - " internal debugging information if available\n" - " -F format_string print according to the format; see\n" - " man fwbedit(1) for the list of macros and examples\n"; - cout << endl; - - cout << - " add -f file.fwb -g group -o object\n" - "\n" - " -f file.fwb: data file\n" - " -g group: group the object should be added to, \n" - " full path or ID\n" - " -o object: object to be added, full path or ID\n"; - cout << endl; - - cout << - " remove -f file.fwb -g group -o object\n" - "\n" - " -f file.fwb: data file\n" - " -g group: group the object should be removed from,\n" - " full path or ID\n" - " -o object: object to be removed, full path or ID\n"; - cout << endl; - - cout << - " upgrade -f file.fwb\n" - "\n" - " -f file.fwb: data file\n"; - cout << endl; - - cout << - " checktree -f file.fwb\n" - "\n" - " -f file.fwb: data file\n"; - cout << endl; - - cout << - " merge -f file1.fwb -i file2.fwb -c[1|2]\n" - "\n" - " -f file1.fwb: data file #1\n" - " -i file2.fwb: data file #2\n" - " -cN in case of conflict (the same object is found in both files),\n" - " keep the object from the file N (can be '1' or '2').\n" - " Default is '1'.\n" - " Objects from the file2.fwb are merged with objects in file1\n" - " and combined object tree saved in file1.fwb\n"; - - cout << - " import -f file1.fwb -i firewall_config.txt -l library_name -n firewall_name\n" - "\n" - " -f file1.fwb: data file #1\n" - " -i firewall_config.txt: firewall configuration file that should be imported #2\n" - " -l library: the name of the object library where firewall object should be created\n" - " -n firewall_name: the name of the new firewall object\n"; - - cout << endl; - cout << "Attributes for the new objects, by type:" << endl; cout << endl; cout << " " @@ -293,6 +194,164 @@ void usage() } +void usage() +{ + cout << "Firewall Builder: general purpose object tree editing tool" + << endl; + cout << "Version " << VERSION << endl; + cout << endl; + cout << "Usage: fwbedit command [options]" << endl; + cout << endl; + + cout << "Command is one of:" << endl; + cout << " new create new object" << endl; + cout << " delete delete object" << endl; + cout << " modify modify object" << endl; + cout << " list print object" << endl; + cout << " add add object to a group" << endl; + cout << " remove remove object from a group" << endl; + cout << " upgrade upgrade data file" << endl; + cout << " checktree check object tree and repair if necessary" << endl; + cout << " merge merge one data file into another" << endl; + cout << " import import firewall configuration (iptables, CIsco IOS," << endl; + cout << " Cisco PIX, ASA and FWSM)" << endl; + cout << endl; + cout << "Type 'fwbedit command' to get summary of options for the command" + << endl; + cout << endl; +} + +void usage_new() +{ + cout << "Options:" << endl; + cout << endl; + cout << + " new -f file.fwb -t objtype -n name -c comment " + "-p parent [-a attrs]\n" + "\n" + " -f file.fwb: data file\n" + " -t objtype: create a new object of this type\n" + " -n name: the name of the new object\n" + " -c txt: specify comment for the new object\n" + " -a attribute1[,attribute2...] : specify attributes that\n" + " define parameters of the new object (see below)\n"; + cout << endl; + + list_attributes(); +} + +void usage_delete() +{ + cout << + " delete -f file.fwb -o object\n" + "\n" + " -f file.fwb: data file\n" + " -o object: object to be deleted, full path or ID\n"; + cout << endl; +} + +void usage_modify() +{ + cout << + " modify -f file.fwb -o object -c comment [-a attrs]\n" + "\n" + " -f file.fwb: data file\n" + " -o object: object to be modified, full path or ID\n" + " -c txt: specify comment for the new object\n" + " -a attribute1[,attribute2...] : specify attributes that\n" + " define parameters of the new object (see below)\n"; + cout << endl; +} + +void usage_list() +{ + cout << + " list -f file.fwb -o object [-r|-c] [-d|-Fformat]\n" + "\n" + " -f file.fwb: data file\n" + " -o object: object to print, full path or ID\n" + " -r print given object and all object below it in the tree\n" + " -c print all children of given object but not the object\n" + " itself\n" + " -d print full dump of all object's attributes including\n" + " internal debugging information if available\n" + " -F format_string print according to the format; see\n" + " man fwbedit(1) for the list of macros and examples\n"; + cout << endl; +} + +void usage_add() +{ + cout << + " add -f file.fwb -g group -o object\n" + "\n" + " -f file.fwb: data file\n" + " -g group: group the object should be added to, \n" + " full path or ID\n" + " -o object: object to be added, full path or ID\n"; + cout << endl; +} + +void usage_remove() +{ + cout << + " remove -f file.fwb -g group -o object\n" + "\n" + " -f file.fwb: data file\n" + " -g group: group the object should be removed from,\n" + " full path or ID\n" + " -o object: object to be removed, full path or ID\n"; + cout << endl; +} + +void usage_upgrade() +{ + cout << + " upgrade -f file.fwb\n" + "\n" + " -f file.fwb: data file\n"; + cout << endl; +} + +void usage_checktree() +{ + cout << + " checktree -f file.fwb\n" + "\n" + " -f file.fwb: data file\n"; + cout << endl; +} + +void usage_merge() +{ + cout << + " merge -f file1.fwb -i file2.fwb -c[1|2]\n" + "\n" + " -f file1.fwb: data file #1\n" + " -i file2.fwb: data file #2\n" + " -cN in case of conflict (the same object is found in both files),\n" + " keep the object from the file N (can be '1' or '2').\n" + " Default is '1'.\n" + " Objects from the file2.fwb are merged with objects in file1\n" + " and combined object tree saved in file1.fwb\n"; + cout << endl; +} + +void usage_import() +{ + cout << + " import -f file1.fwb -i firewall_config.txt -o firewall_object_path\n" + "\n" + " -f file1.fwb: data file #1\n" + " -i firewall_config.txt: firewall configuration file that\n" + " should be imported #2\n" + " -o firewall_object_path: a full path to the firewall object\n" + " to be created, e.g. '/User/Firewalls/my_new_firewall'\n" + " Note that path must start with the library name\n"; + cout << endl; +} + + void _findObjects(const string &obj_path, FWObject *obj, list &res) { string path = fixPath(obj_path); @@ -392,8 +451,9 @@ int main(int argc, char * const *argv) bool recursive = false; string list_format = "%path%"; bool full_dump = false; + string import_config; - if (argc<=2) + if (argc<=1) { usage(); exit(1); @@ -417,6 +477,7 @@ int main(int argc, char * const *argv) if (cmd_str=="upgrade") cmd = UPGRADE; if (cmd_str=="checktree") cmd = STRUCT; if (cmd_str=="merge") cmd = MERGE; + if (cmd_str=="import") cmd = IMPORT; char * const *args = argv; args++; @@ -448,6 +509,13 @@ int main(int argc, char * const *argv) break; } } + + if (filename=="") + { + usage_new(); + exit(1); + } + break; } @@ -462,6 +530,13 @@ int main(int argc, char * const *argv) case 'o': object = optarg; break; } } + + if (filename.empty() || object.empty()) + { + usage_delete(); + exit(1); + } + break; case MODOBJECT: @@ -484,6 +559,13 @@ int main(int argc, char * const *argv) break; } } + + if (filename.empty() || object.empty()) + { + usage_modify(); + exit(1); + } + break; } @@ -501,6 +583,14 @@ int main(int argc, char * const *argv) case 'o': object = optarg; break; } } + + if (filename.empty() || group.empty() || object.empty()) + { + if (cmd == ADDGRP) usage_add(); + if (cmd == REMGRP) usage_remove(); + exit(1); + } + break; case LIST: @@ -518,6 +608,13 @@ int main(int argc, char * const *argv) case 'd': full_dump = true; break; } } + + if (filename.empty() || object.empty()) + { + usage_list(); + exit(1); + } + break; case UPGRADE: @@ -530,6 +627,13 @@ int main(int argc, char * const *argv) case 'f': filename = optarg; break; } } + + if (filename.empty()) + { + usage_upgrade(); + exit(1); + } + break; case STRUCT: @@ -541,6 +645,13 @@ int main(int argc, char * const *argv) case 'f': filename = optarg; break; } } + + if (filename.empty()) + { + usage_checktree(); + exit(1); + } + break; case MERGE: @@ -554,6 +665,33 @@ int main(int argc, char * const *argv) case 'c': conflict_res = atoi(optarg); break; } } + + if (filename.empty() || filemerge.empty()) + { + usage_merge(); + exit(1); + } + + break; + + case IMPORT: + // -f file.fwb -i config.txt -o /User/Firewalls/new_firewall + while( (opt=getopt(argc, args, "f:i:o:")) != EOF ) + { + switch(opt) + { + case 'f': filename = optarg; break; + case 'i': import_config = optarg; break; + case 'o': object = optarg; break; + } + } + + if (filename.empty() || import_config.empty() || object.empty()) + { + usage_import(); + exit(1); + } + break; case NONE: @@ -584,11 +722,60 @@ int main(int argc, char * const *argv) { if (filemerge.empty()) { - usage(); + cerr << "The name of the file that should be merged is missing" + << endl; + usage_merge(); exit(1); } mergeTree(objdb, filemerge, conflict_res); } + else if (cmd == IMPORT) + { + if (import_config.empty() || object.empty()) + { + cerr << "Configuration file name and path to the new firewall " + "object are mandatory options for import" << endl; + usage_import(); + exit(1); + } + + QStringList components = QString::fromUtf8(object.c_str()) + .split("/", QString::SkipEmptyParts); + string fw_name = components.last().toUtf8().constData(); + + Library *library = NULL; + while (library == NULL) + { + components.pop_back(); + string library_path = components.join("/").toUtf8().constData(); + + list objects; + findObjects(library_path, objdb, objects); + + if (objects.size() == 0) + { + cerr << "Library or folder '" + << library_path << "' not found" << endl; + usage_import(); + exit(1); + } + + library = Library::cast(objects.front()); + } + + cout << "Import firewall configuration from file " + << import_config + << endl; + + cout << "New firewall object '" + << fw_name + << "' will be created in library '" + << library->getName() + << "'" + << endl; + + importConfig(objdb, import_config, library, fw_name); + } else if (cmd == STRUCT) { checkAndRepairTree(objdb); diff --git a/src/fwbedit/fwbedit.h b/src/fwbedit/fwbedit.h index b03c833e4..416f689c4 100644 --- a/src/fwbedit/fwbedit.h +++ b/src/fwbedit/fwbedit.h @@ -37,7 +37,7 @@ // can't use 'DELETE' in this enum because it is degined somewhere on windows typedef enum { NONE, ADDGRP, REMGRP, DELOBJECT, NEWOBJECT, MODOBJECT, - LIST, STRUCT, UPGRADE, MERGE} command; + LIST, STRUCT, UPGRADE, MERGE, IMPORT} command; class OperandsError : public std::exception {}; @@ -72,6 +72,11 @@ extern void checkAndRepairTree(libfwbuilder::FWObjectDatabase *objdb); extern void mergeTree(libfwbuilder::FWObjectDatabase *objdb, const std::string &mergefile, int conflict_res); +extern void importConfig(libfwbuilder::FWObjectDatabase *objdb, + const std::string &import_config, + libfwbuilder::FWObject *library, + const std::string &fw_name); + extern int splitStr(char ch,std::string s, operands * ops); extern std::string getNextOpt(operands &ops); extern std::string fixPath(const std::string &obj_path); diff --git a/src/fwbedit/fwbedit.pro b/src/fwbedit/fwbedit.pro index cfabd1201..dcaf8aa9e 100644 --- a/src/fwbedit/fwbedit.pro +++ b/src/fwbedit/fwbedit.pro @@ -5,11 +5,15 @@ include(../../qmake.inc) # TEMPLATE = app +QT += network -SOURCES = fwbedit.cpp new_object.cpp repair_tree.cpp list_object.cpp merge.cpp +SOURCES = fwbedit.cpp new_object.cpp repair_tree.cpp list_object.cpp merge.cpp import.cpp HEADERS = ../../config.h fwbedit.h upgradePredicate.h -INCLUDEPATH += ../libfwbuilder/src +INCLUDEPATH += ../libfwbuilder/src ../import ../compiler_lib/ ../libgui + +win32:INCLUDEPATH += ../libgui/ui +!win32:INCLUDEPATH += ../libgui/.ui TARGET = fwbedit @@ -20,7 +24,12 @@ DEPENDPATH = ../common \ ../libfwbuilder/src/fwcompiler !win32:LIBS = ../common/libcommon.a \ + ../import/libimport.a \ + ../parsers/libfwbparser.a \ + ../compiler_lib/libcompilerdriver.a \ ../libfwbuilder/src/fwbuilder/libfwbuilder.a \ + ../libgui/libgui.a \ + $$ANTLR_LIBS \ $$LIBS !win32:PRE_TARGETDEPS = ../common/libcommon.a \ @@ -29,7 +38,13 @@ DEPENDPATH = ../common \ win32:CONFIG += console win32:LIBS += ../common/release/common.lib \ - ../libfwbuilder/src/fwbuilder/release/fwbuilder.lib + ../import/release/import.lib \ + ../parsers/release/fwbparser.lib \ + ../compiler_lib/release/compilerdriver.lib \ + ../libfwbuilder/src/fwbuilder/release/fwbuilder.lib \ + ../libgui/release/gui.lib \ + $$ANTLR_LIBS \ + $$LIBS win32:PRE_TARGETDEPS = ../common/release/common.lib \ ../libfwbuilder/src/fwbuilder/release/fwbuilder.lib diff --git a/src/fwbedit/import.cpp b/src/fwbedit/import.cpp new file mode 100644 index 000000000..f050adc35 --- /dev/null +++ b/src/fwbedit/import.cpp @@ -0,0 +1,99 @@ +/* + + Firewall Builder + + Copyright (C) 2011 NetCitadel, LLC + + Author: Vadim Kurland vadim@fwbuilder.org + + This program is free software which we release under the GNU General Public + License. You may redistribute and/or modify this program under the terms + of that license as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + To get a copy of the GNU General Public License, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "../../config.h" +#include "fwbuilder/libfwbuilder-config.h" +#include "fwbuilder/Library.h" + +#include "fwbedit.h" + +#include "PreImport.h" +#include "IOSImporter.h" +#include "IPTImporter.h" +#include "PIXImporter.h" + +#include + +#include +#include + + +using namespace libfwbuilder; +using namespace std; + + +void importConfig(FWObjectDatabase *objdb, + const string &import_config, + FWObject *library, + const string &fw_name) +{ + QFile f(QString::fromUtf8(import_config.c_str())); + f.open(QFile::ReadOnly); + string buffer = QString(f.readAll()).toStdString(); + f.close(); + + std::istringstream instream(buffer); + QueueLogger *logger = new QueueLogger(); + logger->copyToStderr(); + Importer* imp = NULL; + + QStringList sl_buf = QString::fromUtf8(buffer.c_str()).split("\n"); + PreImport pi(&sl_buf); + pi.scan(); + + switch (pi.getPlatform()) + { + case PreImport::PIX: + case PreImport::FWSM: + imp = new PIXImporter(library, instream, logger, fw_name); + break; + + case PreImport::IOSACL: + imp = new IOSImporter(library, instream, logger, fw_name); + break; + + case PreImport::IPTABLES: + imp = new IPTImporter(library, instream, logger, fw_name); + break; + + case PreImport::IPTABLES_WITH_COUNTERS: + cerr << "This appears to be iptables configuration saved using " + "command \"iptables-save -c\"" + "and it includes packet counters. Please save configuration " + "using command \"iptables-save\" without option \"-c\" and " + "try to import it again." + << endl; + exit(1); + + default: + cerr << "Can not import configuration file: unrecognized firewall platform" + << endl; + exit(1); + } + + imp->run(); + imp->finalize(); + + +} +