1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2003 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@fwbuilder.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 
27 #include "config.h"
28 #include "global.h"
29 #include "utils.h"
30 #include "platforms.h"
31 #include "ProjectPanel.h"
32 
33 #include "FWBTree.h"
34 #include "CustomServiceDialog.h"
35 #include "FWBSettings.h"
36 #include "FWCmdChange.h"
37 
38 #include "fwbuilder/Library.h"
39 #include "fwbuilder/CustomService.h"
40 #include "fwbuilder/Resources.h"
41 
42 #include <memory>
43 
44 #include <qlineedit.h>
45 #include <qtextedit.h>
46 #include <qcombobox.h>
47 #include <qpushbutton.h>
48 #include <QUndoStack>
49 
50 #include <iostream>
51 
52 #include "FWWindow.h"
53 
54 using namespace libfwbuilder;
55 using namespace std;
56 
CustomServiceDialog(QWidget * parent)57 CustomServiceDialog::CustomServiceDialog(QWidget *parent) : BaseObjectDialog(parent)
58 {
59     m_dialog = new Ui::CustomServiceDialog_q;
60     m_dialog->setupUi(this);
61     obj=NULL;
62 
63     connectSignalsOfAllWidgetsToSlotChange();
64 }
65 
~CustomServiceDialog()66 CustomServiceDialog::~CustomServiceDialog()
67 {
68     delete m_dialog;
69 }
70 
loadFWObject(FWObject * o)71 void CustomServiceDialog::loadFWObject(FWObject *o)
72 {
73     obj=o;
74     CustomService *s = dynamic_cast<CustomService*>(obj);
75     assert(s!=NULL);
76 
77     init=true;
78 
79     m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) );
80     m_dialog->commentKeywords->loadFWObject(o);
81 
82 /* fill in m_dialog->platform */
83     m_dialog->platform->clear();
84 
85     int cp=0;
86     QString default_platform =
87         st->value(SETTINGS_PATH_PREFIX"/CustomService/Platform").toString();
88 
89     QMap<QString,QString> platforms = getAllPlatforms();
90     QMap<QString,QString>::iterator i;
91     for (i=platforms.begin(); i!=platforms.end(); i++,cp++)
92     {
93 //        cerr << "m_dialog->platform: key=" << i.key()
94 //             << "  data=" << i.data() << endl;
95 
96 /*
97  * here i.key is m_dialog->platform m_dialog->code ( "ipf", "ipfw",
98  * "iptables", "pf") while i.data is human readable name ("ipfilter",
99  * "PF" )
100  */
101         platformReverseMap[i.value()] = i.key();
102 
103         m_dialog->platform->addItem(i.value());
104         if (default_platform=="") default_platform = i.key();
105         if (default_platform==i.key()) m_dialog->platform->setCurrentIndex(cp);
106 
107         string platform_code = i.key().toStdString();
108 
109         allCodes[i.key()] = QString(s->getCodeForPlatform(platform_code).c_str());
110     }
111 
112     fillDialogInputFields();
113 
114     QString protocol = s->getProtocol().c_str();
115     if (protocol == "") protocol = "any";
116 
117     m_dialog->protocol->clear();
118     m_dialog->protocol->addItem("any");
119     m_dialog->protocol->addItem("tcp");
120     m_dialog->protocol->addItem("udp");
121     m_dialog->protocol->addItem("icmp");
122     m_dialog->protocol->addItem("ipv6-icmp");
123 
124     bool standard_protocol = false;
125     int proto_index = 0;
126     for (; proto_index < m_dialog->protocol->count(); ++proto_index)
127     {
128         if (protocol == m_dialog->protocol->itemText(proto_index))
129         {
130             m_dialog->protocol->setCurrentIndex(proto_index);
131             standard_protocol = true;
132             break;
133         }
134     }
135     if (!standard_protocol)
136     {
137         m_dialog->protocol->addItem(protocol);
138         m_dialog->protocol->setCurrentIndex(proto_index);
139     }
140 
141     int af = s->getAddressFamily();
142     if (af == AF_INET6)
143         m_dialog->ipv6->setChecked(true);
144     else
145         m_dialog->ipv4->setChecked(true);
146 
147     //apply->setEnabled( false );
148 
149     m_dialog->obj_name->setEnabled(!o->isReadOnly());
150     setDisabledPalette(m_dialog->obj_name);
151 
152     m_dialog->code->setEnabled(!o->isReadOnly());
153     setDisabledPalette(m_dialog->code);
154 
155     // do not make "platform" widget disabled when object is read-only
156     // to let the user flip between platforms to see the configuration. See #2669
157 
158     m_dialog->protocol->setEnabled(!o->isReadOnly());
159     setDisabledPalette(m_dialog->protocol);
160 
161     m_dialog->ipv4->setEnabled(!o->isReadOnly());
162     setDisabledPalette(m_dialog->ipv4);
163 
164     m_dialog->ipv6->setEnabled(!o->isReadOnly());
165     setDisabledPalette(m_dialog->ipv6);
166 
167     init=false;
168 }
169 
changed()170 void CustomServiceDialog::changed()
171 {
172     if (!init)
173     {
174         QString pl = platformReverseMap[m_dialog->platform->currentText()];
175         allCodes[pl] = m_dialog->code->text().toUtf8().constData();
176     }
177     BaseObjectDialog::changed();
178 }
179 
validate(bool * res)180 void CustomServiceDialog::validate(bool *res)
181 {
182     *res=true;
183     if (!validateName(this,obj,m_dialog->obj_name->text()))
184     {
185         *res=false;
186         return;
187     }
188 }
189 
190 
191 
platformChanged()192 void CustomServiceDialog::platformChanged()
193 {
194     init=true;
195     fillDialogInputFields();
196     init=false;
197 //    changed();
198 }
199 
applyChanges()200 void CustomServiceDialog::applyChanges()
201 {
202     std::auto_ptr<FWCmdChange> cmd( new FWCmdChange(m_project, obj));
203     FWObject* new_state = cmd->getNewState();
204 
205     CustomService *s = dynamic_cast<CustomService*>(new_state);
206     assert(s!=NULL);
207 
208     string oldname = obj->getName();
209     new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) );
210     m_dialog->commentKeywords->applyChanges(new_state);
211 
212     QMap<QString,QString> platforms = getAllPlatforms();
213     QMap<QString,QString>::iterator i;
214     for (i=platforms.begin(); i!=platforms.end(); i++)
215     {
216         QString platform = i.key();
217         QString code = allCodes[platform];
218         s->setCodeForPlatform( platform.toUtf8().constData(),
219                                string(code.toUtf8().constData()));
220     }
221     QString protocol = m_dialog->protocol->lineEdit()->text();
222     s->setProtocol(string(protocol.toUtf8().constData()));
223     int af = (m_dialog->ipv6->isChecked()) ? AF_INET6 : AF_INET;
224     s->setAddressFamily(af);
225 
226     if (!cmd->getOldState()->cmp(new_state, true))
227     {
228         if (obj->isReadOnly()) return;
229         m_project->undoStack->push(cmd.release());
230     }
231 
232 }
233 
fillDialogInputFields()234 void CustomServiceDialog::fillDialogInputFields()
235 {
236     QString npl = platformReverseMap[m_dialog->platform->currentText()];
237     showPlatform = npl;
238     st->setValue(SETTINGS_PATH_PREFIX"/CustomService/Platform", showPlatform);
239     m_dialog->code->setText(allCodes[showPlatform]);
240 }
241 
242