1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2011 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 #include "addressObjectMaker.h"
25 
26 #include "fwbuilder/Address.h"
27 #include "fwbuilder/AddressRange.h"
28 #include "fwbuilder/AddressTable.h"
29 #include "fwbuilder/DNSName.h"
30 #include "fwbuilder/FWObject.h"
31 #include "fwbuilder/FWObjectDatabase.h"
32 #include "fwbuilder/Network.h"
33 #include "fwbuilder/IPv4.h"
34 #include "fwbuilder/IPv6.h"
35 
36 #include "QStringListOperators.h"
37 
38 #include <string>
39 
40 #include <QtDebug>
41 
42 
43 extern int fwbdebug;
44 
45 using namespace libfwbuilder;
46 using namespace std;
47 
48 
~AddressObjectMaker()49 AddressObjectMaker::~AddressObjectMaker() {}
50 
createObject(ObjectSignature & sig)51 FWObject* AddressObjectMaker::createObject(ObjectSignature &sig)
52 {
53     FWObject *obj = NULL;
54 
55     if (sig.type_name == AddressRange::TYPENAME)
56         obj = createAddressRange(sig);
57 
58     if (sig.type_name == AddressTable::TYPENAME)
59         obj = createAddressTable(sig);
60 
61     if (sig.type_name == DNSName::TYPENAME)
62         obj = createDNSName(sig);
63 
64     if (obj == NULL)
65         obj = createAddress(sig);
66 
67     // Now I should build new signature because actual object type has
68     // only been determined in createAddress()
69 
70     ObjectSignature new_sig(error_tracker);
71 
72     if ( ! sig.object_name.isEmpty())
73     {
74         obj->setName(sig.object_name.toUtf8().constData());
75         obj->dispatch(&new_sig, (void*)(NULL));
76         registerNamedObject(new_sig, obj);
77     } else
78     {
79         obj->dispatch(&new_sig, (void*)(NULL));
80         registerAnonymousObject(new_sig, obj);
81     }
82 
83     return obj;
84 }
85 
createAddress(ObjectSignature & sig)86 FWObject* AddressObjectMaker::createAddress(ObjectSignature &sig)
87 {
88     ObjectSignature signature = sig;
89 
90     InetAddr netmask(signature.netmask.toStdString());
91 
92     if ( netmask == InetAddr::getAllOnes() )
93     {
94         QString name;
95         try
96         {
97             signature.type_name = IPv4::TYPENAME;
98 
99             FWObject *obj = findMatchingObject(signature);
100             if (obj) return obj;
101 
102             InetAddr obj_addr(sig.address.toStdString()); // testing if string converts to an address
103             name = QString("h-") + sig.address;
104             Address *a = Address::cast(
105                 ObjectMaker::createObject(IPv4::TYPENAME, name.toStdString()));
106             a->setAddress(obj_addr);
107             a->setNetmask(InetAddr(InetAddr::getAllOnes()));
108             return a;
109 
110         } catch(FWException &ex)
111         {
112             // address text line can not be converted to ipv4 address.
113             // Since parsers do not understand ipv6 yet, assume this
114             // is a host address and create DNSName object
115 
116             signature.type_name = DNSName::TYPENAME;
117             FWObject *obj = findMatchingObject(signature);
118             if (obj) return obj;
119 
120             name = sig.address;
121             DNSName *da = DNSName::cast(
122                 ObjectMaker::createObject(DNSName::TYPENAME, name.toStdString()));
123             da->setSourceName(sig.address.toStdString());
124             da->setRunTime(true);
125             return da;
126         }
127 
128     } else
129     {
130         signature.type_name = Network::TYPENAME;
131 
132         FWObject *obj = findMatchingObject(signature);
133         if (obj) return obj;
134 
135         QString name = QString("net-%1/%2")
136             .arg(signature.address).arg(signature.netmask);
137         Network *net = Network::cast(
138             ObjectMaker::createObject(Network::TYPENAME, name.toStdString()));
139         try
140         {
141             net->setAddress( InetAddr(sig.address.toStdString()) );
142         } catch (FWException &ex)
143         {
144             error_tracker->registerError(
145                 QString("Error converting address '%1'").arg(sig.address));
146         }
147 
148         // we have already verified netmask above
149         net->setNetmask(netmask);
150 
151         return net;
152     }
153     return NULL;
154 }
155 
createAddressRange(ObjectSignature & sig)156 FWObject* AddressObjectMaker::createAddressRange(ObjectSignature &sig)
157 {
158     FWObject *obj = findMatchingObject(sig);
159     if (obj) return obj;
160 
161     QString addr1 = sig.address_range_start;
162     QString addr2 = sig.address_range_end;
163     QString name = QString("range-%1-%2").arg(addr1).arg(addr2);
164 
165     AddressRange *ar = AddressRange::cast(
166         ObjectMaker::createObject(AddressRange::TYPENAME, name.toStdString()));
167 
168     try
169     {
170         ar->setRangeStart( InetAddr(addr1.toStdString()) );
171     } catch (FWException &ex)
172     {
173         error_tracker->registerError(
174             QString("Error converting address '%1'").arg(addr1));
175     }
176 
177     try
178     {
179         ar->setRangeEnd( InetAddr(addr2.toStdString()) );
180     } catch (FWException &ex)
181     {
182         error_tracker->registerError(
183             QString("Error converting address '%1'").arg(addr2));
184     }
185 
186     return ar;
187 }
188 
189 
createAddressTable(ObjectSignature & sig)190 FWObject* AddressObjectMaker::createAddressTable(ObjectSignature &sig)
191 {
192     FWObject *obj = findMatchingObject(sig);
193     if (obj) return obj;
194 
195     AddressTable *at =  AddressTable::cast(
196         ObjectMaker::createObject(AddressTable::TYPENAME,
197                                   sig.object_name.toUtf8().constData()));
198     assert(at!=NULL);
199     at->setRunTime(true);
200     at->setSourceName(sig.address_table_name.toStdString());
201     return at;
202 }
203 
createDNSName(ObjectSignature & sig)204 FWObject* AddressObjectMaker::createDNSName(ObjectSignature &sig)
205 {
206     FWObject *obj = findMatchingObject(sig);
207     if (obj) return obj;
208 
209     DNSName *dns_obj =  DNSName::cast(
210         ObjectMaker::createObject(DNSName::TYPENAME,
211                                   sig.object_name.toUtf8().constData()));
212     assert(dns_obj!=NULL);
213     dns_obj->setRunTime(true);
214     dns_obj->setSourceName(sig.dns_name.toStdString());
215     return dns_obj;
216 }
217