mirror of
https://github.com/fwbuilder/fwbuilder
synced 2025-11-19 08:12:32 +01:00
915 lines
26 KiB
C++
915 lines
26 KiB
C++
/*
|
|
|
|
Firewall Builder
|
|
|
|
Copyright (C) 2003 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 "version.h"
|
|
#include "fwbuilder/Constants.h"
|
|
|
|
#include <qsettings.h>
|
|
#include <qdatetime.h>
|
|
|
|
#ifdef HAVE_LOCALE_H
|
|
#include <locale.h>
|
|
#endif
|
|
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
|
|
|
|
#ifndef _WIN32
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
|
|
#include <errno.h>
|
|
#ifndef errno
|
|
extern int errno;
|
|
#endif
|
|
|
|
#include <QCommandLineParser>
|
|
|
|
#include "fwbuilder/Resources.h"
|
|
|
|
#include "fwbuilder/XMLTools.h"
|
|
#include "fwbuilder/FWException.h"
|
|
#include "fwbuilder/Group.h"
|
|
|
|
#include "fwbuilder/Library.h"
|
|
#include "fwbuilder/Firewall.h"
|
|
#include "fwbuilder/Cluster.h"
|
|
#include "fwbuilder/Host.h"
|
|
#include "fwbuilder/Network.h"
|
|
#include "fwbuilder/NetworkIPv6.h"
|
|
#include "fwbuilder/IPv4.h"
|
|
#include "fwbuilder/IPv6.h"
|
|
#include "fwbuilder/DNSName.h"
|
|
#include "fwbuilder/AddressTable.h"
|
|
#include "fwbuilder/AddressRange.h"
|
|
#include "fwbuilder/Interface.h"
|
|
|
|
#include "fwbuilder/ServiceGroup.h"
|
|
#include "fwbuilder/CustomService.h"
|
|
#include "fwbuilder/IPService.h"
|
|
#include "fwbuilder/ICMPService.h"
|
|
#include "fwbuilder/TCPService.h"
|
|
#include "fwbuilder/UDPService.h"
|
|
#include "fwbuilder/Interval.h"
|
|
#include "fwbuilder/TagService.h"
|
|
#include "fwbuilder/UserService.h"
|
|
|
|
#include "fwbuilder/Constants.h"
|
|
|
|
#include "../common/init.cpp"
|
|
|
|
#include "fwbedit.h"
|
|
#include "upgradePredicate.h"
|
|
|
|
#include "FWWindow.h"
|
|
#include "FWBSettings.h"
|
|
#include "FWBApplication.h"
|
|
|
|
#include <QStringList>
|
|
#include <QFile>
|
|
|
|
|
|
using namespace libfwbuilder;
|
|
using namespace std;
|
|
|
|
|
|
FWWindow *mw = nullptr;
|
|
FWBSettings *st = nullptr;
|
|
FWBApplication *app = nullptr;
|
|
|
|
string cmd_str = "";
|
|
command cmd = NONE;
|
|
|
|
bool autoupgrade_flag = false;
|
|
string filename = "";
|
|
string filemerge = "";
|
|
int conflict_res = 1;
|
|
|
|
vector<string> platforms;
|
|
|
|
FWObjectDatabase *objdb = nullptr;
|
|
|
|
int fwbdebug = 0;
|
|
|
|
|
|
void list_attributes()
|
|
{
|
|
cout << "Attributes for the new objects, by type:" << endl;
|
|
cout << endl;
|
|
cout << " "
|
|
<< " -t " <<Firewall::TYPENAME
|
|
<< " -a platform, host OS" << endl;
|
|
cout << " "
|
|
<< " -t " <<Cluster::TYPENAME
|
|
<< " -a platform, host OS" << endl;
|
|
cout << " "
|
|
<< " -t " <<IPv4::TYPENAME
|
|
<< " -a IP address [,netmask]" << endl;
|
|
cout << " "
|
|
<< " -t " <<IPv6::TYPENAME
|
|
<< " -a IPv6 address [,masklen]" << endl;
|
|
cout << " "
|
|
<< " -t " <<DNSName::TYPENAME
|
|
<< " -a DNS record,run time" << endl;
|
|
cout << " "
|
|
<< " -t " <<AddressRange::TYPENAME
|
|
<< " -a start address, end address" << endl;
|
|
cout << " "
|
|
<< " -t " <<ObjectGroup::TYPENAME
|
|
<< endl;
|
|
cout << " "
|
|
<< " -t " <<Network::TYPENAME
|
|
<< " -a address,netmask" << endl;
|
|
cout << " "
|
|
<< " -t " <<NetworkIPv6::TYPENAME
|
|
<< " -a ipv6_address,netmask_length" << endl;
|
|
cout << " "
|
|
<< " -t " <<Interval::TYPENAME
|
|
<< " -a start time,start date,start day,end time, end date, end day" << endl;
|
|
cout << " "
|
|
<< " -t " <<Interface::TYPENAME
|
|
<< " -a security level,address type "
|
|
"(dynamic or unnumbered),management" << endl;
|
|
cout << " "
|
|
<< " -t " <<Host::TYPENAME
|
|
<< endl;
|
|
cout << " "
|
|
<< " -t " <<ServiceGroup::TYPENAME
|
|
<< endl;
|
|
cout << " "
|
|
<< " -t " <<TCPService::TYPENAME
|
|
<< " -a source port range start,end,destination port range start,end,UAPRSF,UAPRSF" << endl;
|
|
cout << " "
|
|
<< " -t " <<UDPService::TYPENAME
|
|
<< " -a source port range start,end,Destination port range start,end" << endl;
|
|
cout << " "
|
|
<< " -t " <<ICMPService::TYPENAME
|
|
<< " -a ICMP type,ICMP code" << endl;
|
|
cout << " "
|
|
<< " -t " <<IPService::TYPENAME
|
|
<< " -a protocol "
|
|
"number,lsrr/ssrr/rr/ts/fragm/short_fragm" << endl;
|
|
}
|
|
|
|
|
|
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 [-d]\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"
|
|
" -d reuse address and service objects created in the process\n"
|
|
" of import\n";
|
|
cout << endl;
|
|
}
|
|
|
|
|
|
void _findObjects(const string &obj_path, FWObject *obj, list<FWObject*> &res)
|
|
{
|
|
string path = fixPath(obj_path);
|
|
if (obj->getPath()==path) res.push_back(obj);
|
|
for (FWObject::iterator it=obj->begin(); it!=obj->end(); ++it)
|
|
{
|
|
if (FWReference::cast(*it)) continue;
|
|
_findObjects(path, *it, res);
|
|
}
|
|
}
|
|
|
|
string fixPath(const string &obj_path)
|
|
{
|
|
string res = obj_path;
|
|
// add leading "/" if it is not there
|
|
if (res[0]!='/') res = string("/") + res;
|
|
|
|
// strip trailing "/"
|
|
if (res[res.length()-1] == '/')
|
|
res = res.substr(0, res.length()-1);
|
|
|
|
if (res.find("/FWObjectDatabase")!=0)
|
|
res = string("/FWObjectDatabase") + res;
|
|
|
|
return res;
|
|
}
|
|
|
|
void findObjects(const string &obj_path, FWObject *obj, list<FWObject*> &res)
|
|
{
|
|
if (obj_path.find('/')==string::npos)
|
|
{
|
|
int id = FWObjectDatabase::getIntId(obj_path);
|
|
if (id>=0)
|
|
{
|
|
FWObject *o = obj->getRoot()->findInIndex(id);
|
|
if (o)
|
|
{
|
|
res.push_back(o);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
string path = fixPath(obj_path);
|
|
_findObjects(path, obj, res);
|
|
}
|
|
|
|
int splitStr(char ch,string s, operands * ops)
|
|
{
|
|
int res=0;
|
|
string::size_type pos;
|
|
ops->clear();
|
|
if (s.length()>0)
|
|
{
|
|
while((pos=s.find_first_of(ch))!=string::npos)
|
|
{
|
|
ops->push_back(s.substr(0,pos));
|
|
s=s.substr(pos+1);
|
|
res++;
|
|
}
|
|
ops->push_back(s);
|
|
res++;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
string getNextOpt(operands &ops)
|
|
{
|
|
operands::iterator it = ops.begin();
|
|
if (it == ops.end())
|
|
throw OperandsError();
|
|
|
|
string s = *it;
|
|
ops.pop_front();
|
|
return s;
|
|
}
|
|
|
|
bool getBool(string s)
|
|
{
|
|
return (s.find("y")!=string::npos) || (s.find("Y")!=string::npos) || (s.find("1")!=string::npos);
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char * const *argv)
|
|
{
|
|
operands ops;
|
|
|
|
string objtype;
|
|
string name;
|
|
string object;
|
|
string group;
|
|
string parent;
|
|
string comment_txt;
|
|
bool list_children = false;
|
|
bool recursive = false;
|
|
string list_format = "%path%";
|
|
bool full_dump = false;
|
|
string import_config;
|
|
bool deduplicate = false;
|
|
|
|
if (argc<=1)
|
|
{
|
|
usage();
|
|
exit(1);
|
|
}
|
|
|
|
QStringList arguments;
|
|
for (int i = 0; i < argc; ++i) {
|
|
arguments.append(QString(argv[i]));
|
|
}
|
|
|
|
/*
|
|
* Command line format:
|
|
* fwbedit command [options]
|
|
*
|
|
* argv[1] is always command
|
|
*/
|
|
|
|
cmd_str = arguments.at(1).toStdString();
|
|
|
|
cmd = NONE;
|
|
if (cmd_str=="new") cmd = NEWOBJECT;
|
|
if (cmd_str=="delete") cmd = DELOBJECT;
|
|
if (cmd_str=="modify") cmd = MODOBJECT;
|
|
if (cmd_str=="add") cmd = ADDGRP;
|
|
if (cmd_str=="remove") cmd = REMGRP;
|
|
if (cmd_str=="list") cmd = LIST;
|
|
if (cmd_str=="upgrade") cmd = UPGRADE;
|
|
if (cmd_str=="checktree") cmd = STRUCT;
|
|
if (cmd_str=="merge") cmd = MERGE;
|
|
if (cmd_str=="import") cmd = IMPORT;
|
|
|
|
QCommandLineParser parser;
|
|
|
|
QCommandLineOption fileNameOption("f", "filename", "filename");
|
|
QCommandLineOption objectTypeOption("t", "objtype", "objtype");
|
|
QCommandLineOption nameOption("n", "name", "name");
|
|
QCommandLineOption commentOption("c", "comment", "comment");
|
|
QCommandLineOption parentOption("p", "parent", "parent");
|
|
QCommandLineOption attributesOption("a", "attributes", "attributes");
|
|
QCommandLineOption objectOption("o", "object", "object");
|
|
QCommandLineOption formatOption("F", "format", "format");
|
|
QCommandLineOption groupOption("g", "group", "group");
|
|
|
|
switch (cmd)
|
|
{
|
|
case NEWOBJECT:
|
|
{
|
|
// -f file.fwb -t objtype -n name -c comment -p parent [-a attrs]
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(objectTypeOption);
|
|
parser.addOption(nameOption);
|
|
parser.addOption(commentOption);
|
|
parser.addOption(parentOption);
|
|
parser.addOption(attributesOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
if (filename.empty()) {
|
|
usage_new();
|
|
exit(1);
|
|
}
|
|
|
|
objtype = parser.value(objectTypeOption).toStdString();
|
|
name = parser.value(nameOption).toStdString();
|
|
comment_txt = parser.value(commentOption).toStdString();
|
|
parent = parser.value(parentOption).toStdString();
|
|
auto attributes = parser.value(attributesOption).split(',');
|
|
for (const QString& attribute : attributes) {
|
|
ops.push_back(attribute.toStdString());
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case DELOBJECT:
|
|
{
|
|
// -f file.fwb -o object_def
|
|
// object_def can be either full path or object ID
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(objectOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
object = parser.value(objectOption).toStdString();
|
|
|
|
if (filename.empty() || object.empty()) {
|
|
usage_delete();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case MODOBJECT:
|
|
{
|
|
// -f file.fwb -o object -c comment [-a attrs]
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(objectOption);
|
|
parser.addOption(commentOption);
|
|
parser.addOption(attributesOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
object = parser.value(objectOption).toStdString();
|
|
comment_txt = parser.value(commentOption).toStdString();
|
|
auto attributes = parser.value(attributesOption).split(',');
|
|
for (const QString& attribute : attributes) {
|
|
ops.push_back(attribute.toStdString());
|
|
}
|
|
|
|
if (filename.empty() || object.empty()) {
|
|
usage_modify();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case ADDGRP:
|
|
case REMGRP:
|
|
{
|
|
// -f file.fwb -p group -o object
|
|
// Add/remove object to group
|
|
// both group and object can be either path or ID
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(groupOption);
|
|
parser.addOption(objectOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
object = parser.value(objectOption).toStdString();
|
|
group = parser.value(groupOption).toStdString();
|
|
|
|
if (filename.empty() || group.empty() || object.empty())
|
|
{
|
|
if (cmd == ADDGRP) usage_add();
|
|
if (cmd == REMGRP) usage_remove();
|
|
exit(1);
|
|
}
|
|
break;
|
|
}
|
|
case LIST:
|
|
{
|
|
// -f file.fwb -o object [-r] [-Fformat_string] [-d]
|
|
// object can be either path or ID
|
|
|
|
QCommandLineOption recursiveOption("r", "recursive");
|
|
QCommandLineOption listChildrenOption("c", "list_children");
|
|
QCommandLineOption fullDumpOption("d", "full_dump");
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(objectOption);
|
|
parser.addOption(formatOption);
|
|
parser.addOption(recursiveOption);
|
|
parser.addOption(listChildrenOption);
|
|
parser.addOption(fullDumpOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
object = parser.value(objectOption).toStdString();
|
|
list_format = parser.value(formatOption).toStdString();
|
|
recursive = parser.isSet(recursiveOption);
|
|
list_children = parser.isSet(listChildrenOption);
|
|
full_dump = parser.isSet(fullDumpOption);
|
|
|
|
if (filename.empty() || object.empty())
|
|
{
|
|
usage_list();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case UPGRADE:
|
|
{
|
|
// -f file.fwb
|
|
autoupgrade_flag = true;
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.parse(arguments);
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
|
|
if (filename.empty())
|
|
{
|
|
usage_upgrade();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case STRUCT:
|
|
{
|
|
// -f file.fwb
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.parse(arguments);
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
|
|
if (filename.empty())
|
|
{
|
|
usage_checktree();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case MERGE:
|
|
{
|
|
// -f file1.fwb -i file2.fwb
|
|
|
|
QCommandLineOption mergeFileNameOption("f", "mergeFile", "mergeFile");
|
|
QCommandLineOption conflictResolveOption("c", "conflictResolve", "conflictResolve");
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(mergeFileNameOption);
|
|
parser.addOption(conflictResolveOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
filemerge = parser.value(mergeFileNameOption).toStdString();
|
|
if (parser.isSet(conflictResolveOption)) {
|
|
bool ok = false;
|
|
conflict_res = parser.value(conflictResolveOption).toInt(&ok);
|
|
if (!ok) {
|
|
conflict_res = 1;
|
|
}
|
|
}
|
|
|
|
if (filename.empty() || filemerge.empty())
|
|
{
|
|
usage_merge();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case IMPORT:
|
|
{
|
|
// -f file.fwb -i config.txt -o /User/Firewalls/new_firewall
|
|
|
|
QCommandLineOption importConfigFileNameOption("i", "importConfigFilename", "importConfigFilename");
|
|
QCommandLineOption deduplicateOption("d", "deduplicate");
|
|
|
|
parser.addOption(fileNameOption);
|
|
parser.addOption(importConfigFileNameOption);
|
|
parser.addOption(objectOption);
|
|
parser.addOption(deduplicateOption);
|
|
parser.parse(arguments);
|
|
|
|
filename = parser.value(fileNameOption).toStdString();
|
|
import_config = parser.value(importConfigFileNameOption).toStdString();
|
|
object = parser.value(objectOption).toStdString();
|
|
deduplicate = parser.isSet(deduplicateOption);
|
|
|
|
if (filename.empty() || import_config.empty() || object.empty())
|
|
{
|
|
usage_import();
|
|
exit(1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case NONE:
|
|
break;
|
|
}
|
|
|
|
if (cmd==NONE || filename=="")
|
|
{
|
|
usage();
|
|
exit(1);
|
|
}
|
|
|
|
init(argv);
|
|
|
|
try
|
|
{
|
|
new Resources(Constants::getResourcesFilePath());
|
|
|
|
/* create database */
|
|
objdb = new FWObjectDatabase();
|
|
|
|
/* load the data file */
|
|
UpgradePredicate upgrade_predicate(autoupgrade_flag);
|
|
|
|
objdb->load(filename, &upgrade_predicate, Constants::getDTDDirectory());
|
|
|
|
if (cmd == MERGE)
|
|
{
|
|
if (filemerge.empty())
|
|
{
|
|
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);
|
|
}
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
|
QStringList components = QString::fromUtf8(object.c_str()).split("/", Qt::SkipEmptyParts);
|
|
#else
|
|
QStringList components = QString::fromUtf8(object.c_str()).split("/", QString::SkipEmptyParts);
|
|
#endif
|
|
string fw_name = components.last().toUtf8().constData();
|
|
|
|
Library *library = nullptr;
|
|
while (library == nullptr)
|
|
{
|
|
components.pop_back();
|
|
string library_path = components.join("/").toUtf8().constData();
|
|
|
|
list<FWObject*> 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(import_config, library, fw_name, deduplicate);
|
|
}
|
|
|
|
else if (cmd == STRUCT)
|
|
{
|
|
checkAndRepairTree(objdb);
|
|
}
|
|
|
|
else if (cmd == LIST)
|
|
{
|
|
listObject(objdb, object, list_children, recursive,
|
|
list_format, full_dump);
|
|
return(0);
|
|
}
|
|
|
|
else if (cmd == UPGRADE)
|
|
{
|
|
cout << "File upgraded; current data format version: "
|
|
<< libfwbuilder::Constants::getDataFormatVersion() << endl;
|
|
}
|
|
|
|
else if (cmd == NEWOBJECT)
|
|
{
|
|
newObject(objdb, objtype, name, comment_txt, parent, ops);
|
|
}
|
|
|
|
else if (cmd == DELOBJECT)
|
|
{
|
|
delObject(objdb, object);
|
|
}
|
|
|
|
else if (cmd == MODOBJECT)
|
|
{
|
|
modObject(objdb, object, comment_txt, ops);
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
list<FWObject*> objects;
|
|
findObjects(object, objdb, objects);
|
|
if (objects.size()==0)
|
|
{
|
|
cout << "Object " << object << " not found" << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
for (list<FWObject*>::iterator it=objects.begin();
|
|
it!=objects.end(); ++it)
|
|
{
|
|
FWObject *obj = *it;
|
|
|
|
if (cmd==ADDGRP)
|
|
{
|
|
list<FWObject*> groups;
|
|
findObjects(group, objdb, groups);
|
|
if (groups.size()==0)
|
|
{
|
|
cout << "Group " << group << " not found" << endl;
|
|
exit(-1);
|
|
}
|
|
FWObject *grp = groups.front();
|
|
cout << "Adding object '" << obj->getName()
|
|
<< "' to the group '" << grp->getName()
|
|
<< "'" << endl;
|
|
grp->addRef(obj);
|
|
}
|
|
if (cmd==REMGRP)
|
|
{
|
|
list<FWObject*> groups;
|
|
findObjects(group, objdb, groups);
|
|
if (groups.size()==0)
|
|
{
|
|
cout << "Group " << group << " not found" << endl;
|
|
exit(-1);
|
|
}
|
|
FWObject *grp = groups.front();
|
|
cout << "Removing object '" << obj->getName()
|
|
<< "' from the group '" << grp->getName()
|
|
<< "'" << endl;
|
|
grp->removeRef(obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
QString filename_qstr = QString::fromUtf8(filename.c_str());
|
|
QString bakfile = filename_qstr + ".bak";
|
|
|
|
QFile bakf(bakfile);
|
|
if (bakf.exists()) bakf.remove();
|
|
|
|
QFile dataf(filename_qstr);
|
|
if (dataf.rename(bakfile))
|
|
{
|
|
objdb->saveFile(filename);
|
|
} else
|
|
{
|
|
cout << "Could not rename data file, abroting operation" << endl;
|
|
cout << dataf.errorString().toStdString() << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
} catch(FWException &ex) {
|
|
cerr << ex.toString() << endl;
|
|
exit(1);
|
|
} catch (std::string s) {
|
|
cerr << s;
|
|
exit(1);
|
|
} catch (std::exception &ex) {
|
|
cerr << ex.what();
|
|
exit(1);
|
|
} catch (...) {
|
|
cerr << "Unsupported exception";
|
|
exit(1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|