1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2007 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@fwbuilder.org
8 
9   This program is free software which we release under the GNU General Public
10   License. You may redistribute and/or modify this program under the terms
11   of that license as published by the Free Software Foundation; either
12   version 2 of the License, or (at your option) any later version.
13 
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18 
19   To get a copy of the GNU General Public License, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22 */
23 
24 
25 #ifndef _FWB_POLICY_IMPORTER_H_
26 #define _FWB_POLICY_IMPORTER_H_
27 
28 #include "fwbuilder/Firewall.h"
29 #include "fwbuilder/Interface.h"
30 #include "fwbuilder/Rule.h"
31 #include "fwbuilder/RuleSet.h"
32 #include "fwbuilder/Logger.h"
33 
34 #include "objectMaker.h"
35 #include "addressObjectMaker.h"
36 #include "serviceObjectMaker.h"
37 
38 #include <map>
39 #include <list>
40 #include <string>
41 #include <functional>
42 #include <sstream>
43 
44 #include <QString>
45 
46 typedef std::pair<std::string,std::string> str_tuple;
47 typedef std::vector<std::string> str_vector;
48 
49 
50 class Importer;
51 
52 /*
53  * Used for platforms where interface and direction are set for the
54  * whole ruleset (like in router access lists), as opposed to
55  * platforms where interface and direction are set on a per-rule basis
56  * (iptables)
57  */
58 
59 
60 class UnidirectionalRuleSet
61 {
62 
63 public:
64     libfwbuilder::RuleSet* ruleset;
65     std::string name;
66     // interface names and directions
67     std::map<std::string,std::string> intf_dir;
68     libfwbuilder::PolicyRule::Action default_action;
69     int created_from_line_number;
70     int default_action_line_number;
71     bool to_be_deleted;
72 
UnidirectionalRuleSet()73     UnidirectionalRuleSet()
74     {
75         created_from_line_number = -1;
76         default_action_line_number = -1;
77         default_action = libfwbuilder::PolicyRule::Deny;
78         to_be_deleted = false;
79     }
80 };
81 
82 class ImporterException : public std::exception
83 {
84     QString err;
85 public:
ImporterException(const std::string & e)86     ImporterException(const std::string &e) { err = e.c_str(); }
ImporterException(const QString & e)87     ImporterException(const QString &e) { err = e; }
~ImporterException()88     virtual ~ImporterException() throw() {}
toString()89     QString toString() { return err; }
what()90     virtual const char* what() const throw() { return err.toStdString().c_str(); }
91 };
92 
93 class Importer
94 {
95 
96     // firewall object
97     // one instance of Importer creates only one firewall object.
98     //
99     // Do not access this member directly, always use getFirewallObject()
100     // This ensures the object is created only when it is needed
101     // so that if we get ane xception in parser early, we do not
102     // create unnecessary object
103 
104     libfwbuilder::Firewall *fw;
105     std::string fwname;
106 
107 protected:
108 
109     AddressObjectMaker *address_maker;
110     ServiceObjectMaker *service_maker;
111 
112     int error_counter;
113 
114     // line number in the original stream being imported
115     int current_line_number;
116 
117     libfwbuilder::FWObject *library;
118 
119     std::string input_file_name;
120     std::istringstream &input;
121 
122     std::string platform;
123 
124     std::string discovered_platform;
125     std::string discovered_version;
126 
127     std::string user_choice_host_os;
128     std::string user_choice_version;
129 
130     libfwbuilder::Interface* current_interface;
131 
132     // map :  ruleset name : ruleset
133     // in case of IOS ACls or PIX policy ruleset name == acl name
134     // all other platforms have single ruleset for policy
135     // and another for NAT
136     std::map<const std::string,UnidirectionalRuleSet*>  all_rulesets;
137 
138     // map :  interface name : interface
139     std::map<const std::string,libfwbuilder::Interface*>  all_interfaces;
140 
141     // map :  object signature : object
142     // use this to quickly find objects to avoid creating duplicates
143     std::map<const std::string,libfwbuilder::FWObject*>   all_objects;
144 
145     // registry of broken objects. Sometimes we create an AddressTable
146     // or a group object during import that may have some kind of a problem
147     // that we leave for the user to fix manually. In order to be able to mark
148     // all rules that use this object as "broken", we should register these
149     // broken objects somewhere.
150     std::map<libfwbuilder::FWObject*, QString> broken_objects;
151 
152     UnidirectionalRuleSet* current_ruleset;
153 
154     libfwbuilder::Rule* current_rule;
155 
156     void addAddressObjectToInterface(libfwbuilder::Interface*intf,
157                                      const std::string &addr,
158                                      const std::string &netm);
159     std::string getBadRuleColor();
160 
161     // this method returns fw. It is created if fw==NULL
162     // Using getFirewallObject() instead of accessing fw directly
163     // provides a way to create firewall object only when
164     // it is really needed.
165     libfwbuilder::Firewall* getFirewallObject();
166 
167 
168     // need to be able to tell if firewall object has really
169     // been created during import. If the file is empty or in case of
170     // a parser error firewall object may not have been created.
171     // However in other cases there could have been an error after
172     // the object was created. This method allows us to tell one
173     // situation from another.
haveFirewallObject()174     bool haveFirewallObject() { return (fw!=NULL); }
175 
176     // checks if ruleset "rsname" exists. Returns pointer if yes,
177     // otherwise returns NULL
178     virtual UnidirectionalRuleSet* checkUnidirRuleSet(const std::string &rsname);
179 
180     // finds and rturns pointer to ruleset "rsname". If it does not
181     // exists, it is created
182     virtual UnidirectionalRuleSet* getUnidirRuleSet(
183         const std::string &ruleset_name, const std::string &ruleset_type_name);
184 
185     virtual libfwbuilder::FWObject* createTCPService(const QString &name="");
186     virtual libfwbuilder::FWObject* createUDPService(const QString &name="");
187 
188     // create libfwbuilder::ObjectGroup and place all interfaces in it
189     // argument represents a list of interface names
190     virtual libfwbuilder::FWObject* createGroupOfInterfaces(
191         const std::string &ruleset_name, std::list<std::string> &interfaces);
192 
193     virtual libfwbuilder::FWObject* makeAddressObj(const std::string addr,
194                                                    const std::string netm);
195 
196     virtual libfwbuilder::FWObject* makeSrcObj();
197     virtual libfwbuilder::FWObject* makeDstObj();
198     virtual libfwbuilder::FWObject* makeSrvObj();
199 
200     // importer may need to create multiple objects for
201     // either rule element for some platforms. It is more convenient to
202     // make these special virtual methods rather than use createAddress
203     // and createService every time.
204     virtual void addSrc();
205     virtual void addDst();
206     virtual void addSrv();
207 
208     virtual void addOSrc();
209     virtual void addODst();
210     virtual void addOSrv();
211 
212     virtual void addLogging();
213 
214     void registerBrokenObject(libfwbuilder::FWObject *o, const QString &err);
215     bool isObjectBroken(libfwbuilder::FWObject*);
216     QString getBrokenObjectError(libfwbuilder::FWObject*);
217 
218 public:
219 
220     ObjectMakerErrorTracker *error_tracker;
221 
222     // making logger public so I can access it from the code in the grammar
223     libfwbuilder::Logger *logger;
224 
225     QStringList last_comment;
226     bool add_standard_comments;
227 
228     // temporary variables used by parser to store values
229     // Importer converts these into a proper rule using method
230     // pushRule()
231     // Method clear() resets all these variables to their defaults.
232     //
233     // TODO:  need to add more variables to cover everything needed
234     // for NAT rules
235 
236     std::string action;
237     std::string protocol;
238     std::string rule_comment;
239 
240     std::string src_a;
241     std::string src_nm;
242     std::string src_port_op;
243     std::string src_port_spec;
244 
245     std::string dst_a;
246     std::string dst_nm;
247     std::string dst_port_op;
248     std::string dst_port_spec;
249 
250     std::string tmp_a;
251     std::string tmp_nm;
252     std::string tmp_port_op;
253     std::string tmp_port_spec;
254     std::string tmp_port_spec_2;
255 
256     std::string tmp_range_1;
257     std::string tmp_range_2;
258 
259     int  tmp_tcp_flag_code;
260     QList<int> tmp_tcp_flags_list;
261     QList<int> tcp_flags_mask;
262     QList<int> tcp_flags_comp;
263 
264     bool  logging;
265     std::string log_level;
266     std::string log_interval;
267 
268     bool  established;
269     bool  fragments;
270 
271     std::string icmp_spec;
272     std::string icmp_code;
273     std::string icmp_type;
274 
275     std::string time_range_name;
276 
277     void SaveTmpAddrToSrc();
278     void SaveTmpAddrToDst();
279 
280     void SaveTmpPortToSrc();
281     void SaveTmpPortToDst();
282 
283     void setSrcSelf();
284     void setDstSelf();
285 
286     virtual void clear();
287 
288     Importer(libfwbuilder::FWObject *lib,
289              const std::string      &platform,
290              std::istringstream     &input,
291              libfwbuilder::Logger   *log,
292              const std::string &fwname);
293     virtual ~Importer();
294 
295     virtual void run();
296 
setFileName(const std::string & fn)297     void setFileName(const std::string &fn) { input_file_name = fn; }
setPlatform(const std::string & pl)298     void setPlatform(const std::string &pl) { platform = pl; }
299     void prepareForDeduplication();
300 
301     // add standard line to rule comment, this adds something like
302     // "created during import from <file>, line <line>"
303     virtual void addStandardImportComment(libfwbuilder::FWObject *obj,
304                                           const QString &additional_comment);
305 
306     virtual libfwbuilder::FWObject* commitObject(libfwbuilder::FWObject *obj);
307 
errorCounter()308     int errorCounter() { return error_counter; }
309 
310     virtual void setDiscoveredPlatform(const std::string &v);
311     virtual void setDiscoveredVersion(const std::string &v);
312 
setUserChoiceHostOS(const std::string & s)313     void setUserChoiceHostOS(const std::string &s) { user_choice_host_os = s; }
setUserChoiceVersion(const std::string & s)314     void setUserChoiceVersion(const std::string &s) { user_choice_version = s; }
setAddStandardCommentsFlag(bool f)315     void setAddStandardCommentsFlag(bool f) { add_standard_comments = f; }
316 
317     virtual void setHostName(const std::string &hn);
318     virtual libfwbuilder::Interface* newInterface(const std::string &interface_name);
clearCurrentInterface()319     virtual void clearCurrentInterface() { current_interface = NULL; }
320     virtual void ignoreCurrentInterface();
321     virtual void addInterfaceAddress(const std::string &a,
322                                      const std::string &nm);
323     virtual void addInterfaceAddress(const std::string &label,
324                                      const std::string &a,
325                                      const std::string &nm);
326     virtual void setInterfaceComment(const std::string &descr);
327     virtual void setInterfaceLabel(const std::string &descr);
328     virtual void setInterfaceSecurityLevel(const std::string &seclevel);
329     virtual void setInterfaceParametes(const std::string &phys_intf,
330                                        const std::string &label,
331                                        const std::string &sec_level);
332     virtual void setInterfaceVlanId(const std::string &vlan_id);
333 
334     virtual void addRuleComment(const std::string &comm);
335 
336     /**
337      * create new unidirectional ruleset. Unidirectional ruleset
338      * has interface association and direction that apply to all rules
339      * in the set.
340      */
341     virtual void newUnidirRuleSet(const std::string &name,
342                                   const std::string &ruleset_type);
343 
344     /**
345      * Sets default action for the current rule set.
346      */
347     virtual void setDefaultAction(const std::string &iptables_action_name);
348 
349     /**
350      * add interface and direction setting to a ruleset. Note that the
351      * same ruleset may be associated with multiple interfaces and
352      * each association may have its own direction.
353      */
354     virtual void setInterfaceAndDirectionForRuleSet(
355         const std::string &ruleset_name,
356         const std::string &interface_name,
357         const std::string &dir);
358 
359     virtual void setInterfaceAndDirectionForRuleSet(
360         libfwbuilder::Interface *intf,
361         const std::string &ruleset_name,
362         const std::string &dir);
363 
364     virtual void newPolicyRule();
365     virtual void newNATRule();
366     virtual void pushRule();
367 
setCurrentLineNumber(int n)368     void setCurrentLineNumber(int n) { current_line_number = n; }
getCurrentLineNumber()369     int getCurrentLineNumber() { return current_line_number;}
370 
371     void markCurrentRuleBad();
372     void reportError(const std::string &comment);
373     void reportError(const QString &comment);
374 
375     // this method actually adds interfaces to the firewall object
376     // and does final clean up.
377     virtual libfwbuilder::Firewall* finalize();
378 
379     int countRules();
380     int countInterfaces();
381 
382     QString noFirewallErrorMessage();
383     QString noRulesErrorMessage();
384     QString noInterfacesErrorMessage();
385     QString commonFailureErrorMessage();
386 
387     // statistics
388     int getNumberOfRuleSets();
389     int getTotalNumberOfRules();
390     int getNumberOfInterfaces();
391 
392     void addMessageToLog(const std::string &msg);
393     void addMessageToLog(const QString &msg);
394 
395 
396     void rearrangeVlanInterfaces();
397 
398 };
399 
400 #endif
401