1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2009 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@vk.crocodile.org
8 
9   $Id$
10 
11   This program is free software which we release under the GNU General Public
12   License. You may redistribute and/or modify this program under the terms
13   of that license as published by the Free Software Foundation; either
14   version 2 of the License, or (at your option) any later version.
15 
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20 
21   To get a copy of the GNU General Public License, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 
24 */
25 
26 #ifndef __COMPILER_DRIVER_HH__
27 #define __COMPILER_DRIVER_HH__
28 
29 #include "fwcompiler/BaseCompiler.h"
30 
31 #include "Configlet.h"
32 
33 #include <string>
34 #include <sstream>
35 #include <memory>
36 
37 #include <QDir>
38 #include <QTextStream>
39 #include <QString>
40 #include <QStringList>
41 #include <QMap>
42 
43 
44 namespace libfwbuilder {
45     class FWObject;
46     class FWObjectDatabase;
47     class Cluster;
48     class ClusterGroup;
49     class FailoverClusterGroup;
50     class Firewall;
51     class RuleSet;
52     class Interface;
53     class Address;
54     class InetAddr;
55 };
56 
57 #define FW_FILE 0
58 #define CONF1_FILE 1
59 #define CONF2_FILE 2
60 
61 
62 namespace fwcompiler
63 {
64 
65     class OSConfigurator;
66 
67     class CompilerDriver : public BaseCompiler
68     {
69 
70         QString getOutputFileNameInternal(libfwbuilder::Firewall *current_fw,
71                                           const QString &from_cli,
72                                           const QString &option_name,
73                                           const QString &fw_name,
74                                           const QString &ext);
75 
76 protected:
77 
78         QStringList all_errors;
79 
80         QStringList args;
81         int fwbdebug;
82         std::string filename;
83         std::string wdir;
84         QDir start_current_dir;
85         QString fwobjectname;
86         QString current_firewall_name;
87 
88         // list of file names we should generate. Items in the list are
89         // as follows: [0] - the name of the initialization script (normally
90         // the .fw file); [1] - the name of the confguration file (for
91         // pf, ipfilter this is the main .conf file); [2] - the name of the
92         // next conf file, if any; and so on.
93         //
94         // function determineOutputFileNames() fills this list
95 
96         QStringList file_names;
97 
98         // file names on the firewall with full path. Items should correspond
99         // to items in the list file_name
100         //
101         // function determineOutputFileNames() fills this list
102 
103         QStringList remote_file_names;
104 
105         // I store file name provided via -o command line option here
106         QString file_name_setting_from_command_line;
107 
108         // member_file_names is the mapping between member firewall
109         // object ID and corresponding output file name. Can be
110         // enfirced via -O command line option or determined
111         // automatically using member firewall name. Used only when
112         // compiling Cluster
113         QMap<QString,QString> member_file_names;
114 
115         int dl;
116         int drp;
117         int drn;
118         int drr;
119         bool rule_debug_on;
120         bool single_rule_compile_on;
121         bool prepend_cluster_name_to_output_file;
122         std::string single_rule_id;
123         int verbose;
124         bool have_dynamic_interfaces;
125         bool ipv4_run;
126         bool ipv6_run;
127         bool fw_by_id;
128         bool prolog_done;
129         bool epilog_done;
130         bool have_filter;
131         bool have_nat;
132 
133         std::map<std::string,libfwbuilder::RuleSet*> branches;
134 
135         libfwbuilder::FWObjectDatabase *objdb;
136         libfwbuilder::Library *persistent_objects;
137         libfwbuilder::Library *workspace;
138 
139         void determineOutputFileNames(libfwbuilder::Cluster *cluster,
140                                       libfwbuilder::Firewall *current_fw,
141                                       bool cluster_member,
142                                       const QStringList &suffixes,
143                                       const QStringList &extensions,
144                                       const QStringList &remote_file_name_fw_options);
145 
146         bool isSupported(std::list<std::string> *protocols,
147                          const std::string &cluster_group_type);
148 
149         virtual int checkCluster(libfwbuilder::Cluster* cluster);
150 
151         void mergeRuleSets(libfwbuilder::Cluster *cluster,
152                            libfwbuilder::Firewall *fw, const std::string &type);
153 
154         static bool isReachable(const libfwbuilder::Address* const subnet,
155                                 const libfwbuilder::InetAddr* const addr);
156 
157         void clearReadOnly(libfwbuilder::Firewall *fw);
158 
159         /* Virtual methods used to compose generated script */
160         virtual QString printPathForAllTools(libfwbuilder::Firewall* fw,
161                                              const std::string &os);
162 
163         virtual QString printActivationCommands(libfwbuilder::Firewall *fw);
164 
165         virtual QString assembleManifest(libfwbuilder::Cluster *cluster,
166                                          libfwbuilder::Firewall* fw,
167                                          bool cluster_member);
168 
169         virtual void assembleFwScriptInternal(libfwbuilder::Cluster *cluster,
170                                               libfwbuilder::Firewall* fw,
171                                               bool cluster_member,
172                                               OSConfigurator *ocsnf,
173                                               Configlet *script_skeleton,
174                                               Configlet *top_comment,
175                                               const QString &comment_char,
176                                               bool indent);
177 
178         void _findImportedRuleSetsRecursively(libfwbuilder::Firewall *fw,
179                                               libfwbuilder::RuleSet *ruleset,
180                                               std::map<libfwbuilder::FWObject*, int> &branch_rulesets);
181 
182 
183         QString getAbsOutputFileName(const QString &output_file_name);
184 
185 public:
186 
187         CompilerDriver(libfwbuilder::FWObjectDatabase *db);
188         virtual ~CompilerDriver();
189 
190         // create a copy of itself, including objdb
191         virtual CompilerDriver* clone();
192 
193         /**
194          * Process command line arguments
195          */
196         virtual bool configure(const QStringList &args);
197 
198         /**
199          * Assign target object by its id
200          */
201         void setTargetId(const std::string &id);
202 
203         /**
204          * create right compiler objects and compile policy, nat and
205          * routing rules for given firewall which can be a member of a
206          * cluster. If firewall is standalone, @cluster_id is an empty
207          * string. Cluster and firewall are defined by their string IDs.
208          * In single compile mode rule ID is provided in @single_rule_id
209          * and generated script is returned. For compilers that create
210          * several files it is up to the actual cmopiler class to decide
211          * what should be returned in the single rule compile mode. In
212          * normal (not single rule) compile mode returned string is
213          * undefined and should not be used.
214          */
215         virtual QString run(const std::string &cluster_id,
216                             const std::string &firewall_id,
217                             const std::string &single_rule_id);
218 
219         virtual void commonChecks(libfwbuilder::Firewall *fw);
220         virtual void commonChecks2(libfwbuilder::Cluster *cluster,
221                                    libfwbuilder::Firewall *fw);
222 
223         void copyFailoverInterface(libfwbuilder::Cluster *cluster,
224                                    libfwbuilder::Firewall *fw,
225                                    libfwbuilder::FailoverClusterGroup *cluster_group,
226                                    libfwbuilder::Interface *iface);
227 
228         virtual void populateClusterElements(libfwbuilder::Cluster *cluster,
229                                              libfwbuilder::Firewall *fw);
230 
231         virtual void processStateSyncGroups(libfwbuilder::Cluster*,
232                                             libfwbuilder::Firewall*);
233 
234         std::string indent(int n_spaces, const std::string &txt);
235         QString indent(int n_spaces, const QString &txt);
236         QString prepend(const QString &prep, const QString &txt);
237 
238         /*
239          * Verifies that state sync and failover group types configured in
240          * the GUI are supported for the given host OS. List of supported
241          * protocols is taken from the os resource file. If unsupported
242          * protocol is found, calls compiler->abort to abort immediately.
243          */
244         virtual void validateClusterGroups(libfwbuilder::Cluster *cluster);
245 
246         /*
247          * Use chdir to change working directory. In case of failure, exit(1)
248          */
249         void chDir();
250 
251         /*
252          * Find firewall or cluster object we should process.
253          */
254         virtual libfwbuilder::Firewall* locateObject();
255 
256         void getFirewallAndClusterObjects(const std::string &cluster_id,
257                                           const std::string &fw_id,
258                                           libfwbuilder::Cluster **cl,
259                                           libfwbuilder::Firewall **fw);
260 
261         void findImportedRuleSets(libfwbuilder::Firewall *fw,
262                                   std::list<libfwbuilder::FWObject*> &all_policies);
263 
264         void assignUniqueRuleIds(std::list<libfwbuilder::FWObject*> &all_policies);
265 
266         virtual bool prepare(const QStringList &args);
267         virtual void compile();
268         virtual QMap<QString,QString> compileSingleRule(const std::string &rule_id);
269 
270         /*
271          * if compilers produced empty string for the generated code,
272          * this method checks if there were any errors and returns
273          * them. If compilers generated output, errors should be
274          * included in it because warning and error messages are
275          * usually attached to rules. Errors are taken from the
276          * all_errors member variable.
277          */
278         QString formSingleRuleCompileOutput(const QString &generated_code);
279 
280         static QString escapeFileName(QString fileName);
281         static QString unescapeFileName(QString fileName);
282 
283         static QString getConfFileNameFromFwFileName(const QString &file_name,
284                                                      const QString &ext);
285 
setDebugRule(int dr)286 	void setDebugRule(int dr)  { drp = drn = dr; rule_debug_on = true; }
287 
288     };
289 
290 };
291 
292 QTextStream& operator<< (QTextStream &text_stream, const std::string &str);
293 
294 
295 #endif
296