1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2008 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 #include "config.h"
27 #include "global.h"
28 #include "utils.h"
29 
30 #include "FWBTree.h"
31 #include "NetworkDialogIPv6.h"
32 #include "ProjectPanel.h"
33 #include "FWBSettings.h"
34 #include "FWCmdChange.h"
35 
36 #include "fwbuilder/Library.h"
37 #include "fwbuilder/Network.h"
38 #include "fwbuilder/NetworkIPv6.h"
39 #include "fwbuilder/Interface.h"
40 #include "fwbuilder/FWException.h"
41 #include "fwbuilder/Inet6AddrMask.h"
42 
43 #include <memory>
44 
45 #include <qlineedit.h>
46 #include <qspinbox.h>
47 #include <qcheckbox.h>
48 #include <qtextedit.h>
49 #include <qcombobox.h>
50 #include <qmessagebox.h>
51 #include <qpushbutton.h>
52 #include <QUndoStack>
53 #include <QApplication>
54 
55 
56 using namespace std;
57 using namespace libfwbuilder;
58 
NetworkDialogIPv6(QWidget * parent)59 NetworkDialogIPv6::NetworkDialogIPv6(QWidget *parent) : BaseObjectDialog(parent)
60 {
61     m_dialog = new Ui::NetworkDialogIPv6_q;
62     m_dialog->setupUi(this);
63     obj=NULL;
64 
65     connectSignalsOfAllWidgetsToSlotChange();
66 }
67 
~NetworkDialogIPv6()68 NetworkDialogIPv6::~NetworkDialogIPv6() { delete m_dialog; }
69 
loadFWObject(FWObject * o)70 void NetworkDialogIPv6::loadFWObject(FWObject *o)
71 {
72     obj=o;
73     NetworkIPv6 *s = dynamic_cast<NetworkIPv6*>(obj);
74     assert(s!=NULL);
75 
76     init=true;
77 
78     m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) );
79     m_dialog->address->setText( s->getAddressPtr()->toString().c_str() );
80     m_dialog->netmask->setText( QString("%1").arg(
81                                     s->getNetmaskPtr()->getLength()) );
82     m_dialog->commentKeywords->loadFWObject(o);
83 
84     //apply->setEnabled( false );
85 
86     m_dialog->obj_name->setEnabled(!o->isReadOnly());
87     setDisabledPalette(m_dialog->obj_name);
88 
89     m_dialog->address->setEnabled(!o->isReadOnly());
90     setDisabledPalette(m_dialog->address);
91 
92     m_dialog->netmask->setEnabled(!o->isReadOnly());
93     setDisabledPalette(m_dialog->netmask);
94 
95     init=false;
96 }
97 
changed()98 void NetworkDialogIPv6::changed()
99 {
100     //apply->setEnabled( true );
101     emit changed_sign();
102 }
103 
validate(bool * res)104 void NetworkDialogIPv6::validate(bool *res)
105 {
106     *res = true;
107 
108     if (!validateName(this,obj,m_dialog->obj_name->text()))
109     {
110         *res = false;
111         return;
112     }
113 
114     NetworkIPv6 *s = dynamic_cast<NetworkIPv6*>(obj);
115     assert(s != NULL);
116     try
117     {
118         InetAddr(AF_INET6, m_dialog->address->text().toStdString() );
119     } catch (FWException &ex)
120     {
121         *res = false;
122         if (QApplication::focusWidget() != NULL)
123         {
124             blockSignals(true);
125             QMessageBox::critical(this, "Firewall Builder",
126                                   tr("Illegal IPv6 address '%1'").arg(
127                                       m_dialog->address->text()),
128                                   tr("&Continue"), 0, 0,
129                                   0 );
130             blockSignals(false);
131         }
132     }
133 
134     bool ok = false;
135     int range = m_dialog->netmask->text().toInt(&ok);
136     // Do not allow netmask of 0 bits. See #251
137     if (ok && range > 0 && range < 128)
138     {
139         return;
140     }
141     else
142     {
143         *res = false;
144         if (QApplication::focusWidget() != NULL)
145         {
146             blockSignals(true);
147             QMessageBox::critical(this, "Firewall Builder",
148                                   tr("Illegal netmask '%1'").arg(
149                                       m_dialog->netmask->text() ),
150                                   tr("&Continue"), 0, 0,
151                                   0 );
152             blockSignals(false);
153         }
154     }
155 }
156 
157 
158 
applyChanges()159 void NetworkDialogIPv6::applyChanges()
160 {
161     std::auto_ptr<FWCmdChange> cmd( new FWCmdChange(m_project, obj));
162     FWObject* new_state = cmd->getNewState();
163 
164     NetworkIPv6 *s = dynamic_cast<NetworkIPv6*>(new_state);
165     assert(s!=NULL);
166 
167     string oldname=obj->getName();
168     new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) );
169     m_dialog->commentKeywords->applyChanges(new_state);
170 
171     try
172     {
173         s->setAddress(
174             InetAddr(AF_INET6,
175                      m_dialog->address->text().toStdString()) );
176         bool ok = false;
177         s->setNetmask(
178             InetAddr(AF_INET6, m_dialog->netmask->text().toInt(&ok)) );
179         if (!ok) throw FWException("");
180     } catch (FWException &ex)
181     {
182 /* exception thrown if user types illegal m_dialog->address or
183  * m_dialog->netmask
184  */
185 
186     }
187 
188     if (!cmd->getOldState()->cmp(new_state, true))
189     {
190         if (obj->isReadOnly()) return;
191         m_project->undoStack->push(cmd.release());
192     }
193 
194 
195 }
196 
addressEntered()197 void NetworkDialogIPv6::addressEntered()
198 {
199     try
200     {
201         QString addr = m_dialog->address->text();
202         Inet6AddrMask address_and_mask(string(addr.toStdString()));
203         if (addr.contains('/'))
204         {
205             m_dialog->address->setText(
206                 address_and_mask.getAddressPtr()->toString().c_str());
207             m_dialog->netmask->setText(
208                 QString().setNum(
209                     address_and_mask.getNetmaskPtr()->getLength()));
210         }
211     } catch (FWException &ex)
212     {
213 // exception thrown if user types illegal m_dialog->address
214 
215     }
216 
217 }
218 
219