source: src-qt4/warden-gui/dialogEditIP.cpp @ ed41975

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since ed41975 was ed41975, checked in by Kris Moore <kris@…>, 10 months ago

Add support to enable / disable VNET and related options via warden GUI

  • Property mode set to 100644
File size: 18.4 KB
Line 
1/****************************************************************************
2** ui.h extension file, included from the uic-generated form implementation.
3**
4** If you want to add, delete, or rename functions or slots, use
5** Qt Designer to update this file, preserving your code.
6**
7** You should not define a constructor or destructor in this file.
8** Instead, write your code in functions called init() and destroy().
9** These will automatically be called by the form's constructor and
10** destructor.
11*****************************************************************************/
12// QT Includes
13#include <QInputDialog>
14#include <QProcess>
15#include <QString>
16#include <QFile>
17#include <QFileDialog>
18#include <QMessageBox>
19#include <QDebug>
20#include <QListWidgetItem>
21#include "pcbsd-utils.h"
22
23// Local Includes
24#include "dialogEditIP.h"
25
26
27void dialogEditIP::programInit(QString name)
28{
29  JailDir = pcbsd::Utils::getValFromPCConf("/usr/local/etc/warden.conf", "JDIR");
30  jailName = name;
31  QFile file;
32  QString tmp;
33
34  // Is VNET enabled?
35  file.setFileName( JailDir + "/." + jailName + ".meta/vnet" );
36  if ( file.exists() )
37    checkVNET->setChecked(true);
38
39  // Lets start loading IP addresses
40  file.setFileName( JailDir + "/." + jailName + ".meta/ipv4" );
41  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
42     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
43     lineIP->setText(tmp);
44     if ( ! tmp.isEmpty() )
45        checkIPv4->setChecked(true);
46     file.close();
47  }
48
49  file.setFileName( JailDir + "/." + jailName + ".meta/bridge-ipv4" );
50  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
51     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
52     lineIPBridge->setText(tmp);
53     if ( ! tmp.isEmpty() )
54        checkIPv4Bridge->setChecked(true);
55     file.close();
56  }
57
58  file.setFileName( JailDir + "/." + jailName + ".meta/defaultrouter-ipv4" );
59  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
60     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
61     lineIPRouter->setText(tmp);
62     if ( ! tmp.isEmpty() )
63        checkIPv4Router->setChecked(true);
64     file.close();
65  }
66
67  file.setFileName( JailDir + "/." + jailName + ".meta/ipv6" );
68  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
69     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
70     lineIP6->setText(tmp);
71     if ( ! tmp.isEmpty() )
72        checkIPv6->setChecked(true);
73     file.close();
74  }
75
76  file.setFileName( JailDir + "/." + jailName + ".meta/bridge-ipv6" );
77  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
78     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
79     lineIP6Bridge->setText(tmp);
80     if ( ! tmp.isEmpty() )
81        checkIPv6Bridge->setChecked(true);
82     file.close();
83  }
84
85  file.setFileName( JailDir + "/." + jailName + ".meta/defaultrouter-ipv6" );
86  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
87     QTextStream stream( &file ); tmp=""; tmp = stream.readLine();
88     lineIP6Router->setText(tmp);
89     if ( ! tmp.isEmpty() )
90        checkIPv6Router->setChecked(true);
91     file.close();
92  }
93
94  file.setFileName( JailDir + "/." + jailName + ".meta/alias-ipv4" );
95  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
96     QTextStream stream( &file ); 
97     while ( ! file.atEnd() )
98       IPv4Alias << stream.readLine();
99     file.close();
100  }
101
102  file.setFileName( JailDir + "/." + jailName + ".meta/alias-bridge-ipv4" );
103  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
104     QTextStream stream( &file ); 
105     while ( ! file.atEnd() )
106       IPv4AliasBridge << stream.readLine();
107     file.close();
108  }
109
110  file.setFileName( JailDir + "/." + jailName + ".meta/alias-ipv6" );
111  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
112     QTextStream stream( &file ); 
113     while ( ! file.atEnd() )
114       IPv6Alias << stream.readLine();
115     file.close();
116  }
117
118  file.setFileName( JailDir + "/." + jailName + ".meta/alias-bridge-ipv6" );
119  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
120     QTextStream stream( &file ); 
121     while ( ! file.atEnd() )
122       IPv6AliasBridge << stream.readLine();
123     file.close();
124  }
125
126  // Our buttons / slots
127  connect( checkVNET, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
128  connect( checkIPv4, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
129  connect( checkIPv4Bridge, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
130  connect( checkIPv4Router, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
131  connect( checkIPv6, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
132  connect( checkIPv6Bridge, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
133  connect( checkIPv6Router, SIGNAL( clicked() ), this, SLOT( slotCheckChecks() ) );
134
135  connect( comboIPType, SIGNAL( currentIndexChanged(int) ), this, SLOT( slotComboIPChanged() ) );
136
137  connect( pushSave, SIGNAL( clicked() ), this, SLOT( slotSaveClicked() ) );
138  connect( pushCancel, SIGNAL( clicked() ), this, SLOT( slotCancelClicked() ) );
139  connect( pushAdd, SIGNAL( clicked() ), this, SLOT( slotAddClicked() ) );
140  connect( pushRemove, SIGNAL( clicked() ), this, SLOT( slotRemClicked() ) );
141
142  slotCheckChecks();
143  slotComboIPChanged();
144  loadPerms();
145}
146
147void dialogEditIP::loadPerms()
148{
149
150  // Add the allow flags to show in the GUI
151  // <flag> | <default value> | <descrip>
152  jailFlags \
153        << "allow.set_hostname|true|" + tr("A process within the jail has access to System V IPC primitives.") \
154        << "allow.sysvipc|false|" + tr("A process within the jail has access to System V IPC primitives.") \
155        << "allow.raw_sockets|false|" + tr("The prison root is allowed to create raw sockets. Enables ping / traceroute.") \
156        << "allow.chflags|false|" + tr("When this parameter is set, such users are treated as privileged, and may manipulate system file flags subject to the usual constraints on kern.securelevel.") \
157        << "allow.mount|false|" + tr("Privileged users inside the jail will be able to mount and unmount file system types marked as jail-friendly.") \
158        << "allow.mount.devfs|false|" + tr("Privileged users inside the jail will be able to mount and unmount the devfs file system.") \
159        << "allow.mount.nullfs|false|" + tr("Privileged users inside the jail will be able to mount and unmount the nullfs file system.") \
160        << "allow.mount.procfs|false|" + tr("Privileged users inside the jail will be able to mount and unmount the procfs file system.") \
161        << "allow.mount.zfs|false|" + tr("Privileged users inside the jail will be able to mount and unmount the zfs file system.") \
162        << "allow.quotas|false|" + tr("The prison root may administer quotas on the jail's filesystem(s).") \
163        << "allow.socket_af|false|" + tr("This allows access to other protocol stacks that have not had jail functionality added to them.") \
164        ;
165
166  QString jDefault;
167  QString toggled;
168  QString curFlags;
169  QFile file( JailDir + "/." + jailName + ".meta/jail-flags" );
170  if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
171     QTextStream stream( &file );
172     curFlags = stream.readLine();
173     file.close();
174  }
175
176
177  for (int i = 0; i < jailFlags.size(); ++i) {
178      QListWidgetItem *myItem = new QListWidgetItem;
179      myItem->setText( jailFlags.at(i).section("|", 0, 0) );
180      jDefault = jailFlags.at(i).section("|", 1, 1);
181      myItem->setToolTip( jailFlags.at(i).section("|", 2, 2) );
182      if ( jDefault == "false" ) {
183        if ( curFlags.indexOf(jailFlags.at(i).section("|", 0,0) + "=true") != -1 )
184          myItem->setCheckState(Qt::Checked);
185        else
186          myItem->setCheckState(Qt::Unchecked);
187      } else {
188        if ( curFlags.indexOf(jailFlags.at(i).section("|", 0,0) + "=false") != -1 )
189          myItem->setCheckState(Qt::Unchecked);
190        else
191          myItem->setCheckState(Qt::Checked);
192      }
193      listPerms->addItem(myItem);
194  }
195}
196
197void dialogEditIP::savePerms()
198{
199  QStringList savePerms;
200  QString jFlag, jDefault;
201  QString lFlag, lChecked;
202
203  for ( int i=0; i < listPerms->count() ; i++) {
204    lFlag =  listPerms->item(i)->text();
205    if ( listPerms->item(i)->checkState() == Qt::Checked )
206       lChecked="true";
207    else
208       lChecked="false";
209   
210    for ( int j=0; j < jailFlags.count() ; j++) {
211       jFlag = jailFlags.at(j).section("|", 0, 0);
212       if ( jFlag != lFlag ) 
213         continue;
214
215       jDefault = jailFlags.at(j).section("|", 1, 1);
216       if ( jDefault == "true" && lChecked == "false" )
217          savePerms << jFlag + "=false";
218       if ( jDefault == "false" && lChecked == "true" )
219          savePerms << jFlag + "=true";
220    }
221  }
222
223  QFile file( JailDir + "/." + jailName + ".meta/jail-flags" );
224  if ( ! savePerms.isEmpty() ) {
225    if ( file.open( QIODevice::WriteOnly ) ) {
226       QTextStream stream( &file );
227       stream << savePerms.join(" ");
228       file.close();
229    }
230  } else {
231    file.remove();
232  }
233
234
235}
236
237void dialogEditIP::slotComboIPChanged()
238{
239   QStringList curList;
240
241   // IPv4 Aliases
242   if ( comboIPType->currentIndex() == 0 )
243      curList = IPv4Alias;
244
245   // IPv4 Bridge Aliases
246   if ( comboIPType->currentIndex() == 1 )
247      curList = IPv4AliasBridge;
248
249   // IPv6 Aliases
250   if ( comboIPType->currentIndex() == 2 )
251      curList = IPv6Alias;
252
253   // IPv6 Bridge Aliases
254   if ( comboIPType->currentIndex() == 3 )
255      curList = IPv6AliasBridge;
256
257   listIP->clear();
258   for (int i = 0; i < curList.size(); ++i)
259          listIP->addItem(curList.at(i));
260
261}
262
263void dialogEditIP::slotCheckChecks()
264{
265  lineIP->setEnabled(checkIPv4->isChecked());
266  lineIPBridge->setEnabled(checkIPv4Bridge->isChecked());
267  lineIPRouter->setEnabled(checkIPv4Router->isChecked());
268  lineIP6->setEnabled(checkIPv6->isChecked());
269  lineIP6Bridge->setEnabled(checkIPv6Bridge->isChecked());
270  lineIP6Router->setEnabled(checkIPv6Router->isChecked());
271
272  // Enable / disable VNET only options
273  if ( checkVNET->isChecked() )
274  {
275    lineIPBridge->setEnabled(checkIPv4Bridge->isChecked());
276    lineIPRouter->setEnabled(checkIPv4Router->isChecked());
277    lineIP6Bridge->setEnabled(checkIPv6Bridge->isChecked());
278    lineIP6Router->setEnabled(checkIPv6Router->isChecked());
279    checkIPv4Bridge->setEnabled(true);
280    checkIPv4Router->setEnabled(true);
281    checkIPv6Bridge->setEnabled(true);
282    checkIPv6Router->setEnabled(true);
283  } else {
284    lineIPBridge->setEnabled(false);
285    lineIPRouter->setEnabled(false);
286    lineIP6Bridge->setEnabled(false);
287    lineIP6Router->setEnabled(false);
288    checkIPv4Bridge->setEnabled(false);
289    checkIPv4Router->setEnabled(false);
290    checkIPv6Bridge->setEnabled(false);
291    checkIPv6Router->setEnabled(false);
292  }
293
294}
295
296void dialogEditIP::slotCancelClicked()
297{
298   close();
299}
300
301bool dialogEditIP::sanityCheckSettings()
302{
303  if ( checkIPv4->isChecked() && ! checkValidBlock(lineIP->text(), QString("IPv4")) ) {
304        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv4 address!"), QMessageBox::Ok, QMessageBox::Ok);
305        return false;
306  }
307  if ( checkIPv4Bridge->isChecked() && ! checkValidBlock(lineIPBridge->text(), QString("IPv4")) ) {
308        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv4 bridge address!"), QMessageBox::Ok, QMessageBox::Ok);
309        return false;
310  }
311  if ( checkIPv4Router->isChecked() && ! checkValidBlock(lineIPRouter->text(), QString("IPv4")) ) {
312        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv4 router address!"), QMessageBox::Ok, QMessageBox::Ok);
313        return false;
314  }
315  if ( checkIPv6->isChecked() && ! checkValidBlock(lineIP6->text(), QString("IPv6")) ) {
316        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv6 address!"), QMessageBox::Ok, QMessageBox::Ok);
317        return false;
318  }
319  if ( checkIPv6Bridge->isChecked() && ! checkValidBlock(lineIP6Bridge->text(), QString("IPv6")) ) {
320        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv6 bridge address!"), QMessageBox::Ok, QMessageBox::Ok);
321        return false;
322  }
323  if ( checkIPv6Router->isChecked() && ! checkValidBlock(lineIP6Router->text(), QString("IPv6")) ) {
324        QMessageBox::critical(this, tr("Warden"), tr("Invalid IPv6 router address!"), QMessageBox::Ok, QMessageBox::Ok);
325        return false;
326  }
327
328  return true;
329}
330
331void dialogEditIP::slotSaveClicked()
332{
333   if ( sanityCheckSettings() )
334   {
335     saveSettings();
336     savePerms();
337     emit saved();
338     close();
339   }
340}
341
342void dialogEditIP::saveSettings()
343{
344  QString tmp;
345  QFile file;
346
347  // Start saving settings
348  file.setFileName( JailDir + "/." + jailName + ".meta/vnet" );
349  if ( checkVNET->isChecked() ) {
350    if ( file.open( QIODevice::WriteOnly ) ) {
351       QTextStream stream( &file );
352         stream << "";
353       file.close();
354    }
355  } else {
356    file.remove();
357  }
358
359  file.setFileName( JailDir + "/." + jailName + ".meta/alias-ipv4" );
360  if ( ! IPv4Alias.isEmpty() ) {
361    if ( file.open( QIODevice::WriteOnly ) ) {
362       QTextStream stream( &file );
363       for (int i = 0; i < IPv4Alias.size(); ++i)
364         stream << IPv4Alias.at(i);
365       file.close();
366    }
367  } else {
368    file.remove();
369  }
370
371  file.setFileName( JailDir + "/." + jailName + ".meta/alias-bridge-ipv4" );
372  if ( ! IPv4AliasBridge.isEmpty() ) {
373    if ( file.open( QIODevice::WriteOnly ) ) {
374       QTextStream stream( &file );
375       for (int i = 0; i < IPv4AliasBridge.size(); ++i)
376         stream << IPv4AliasBridge.at(i);
377       file.close();
378    }
379  } else {
380    file.remove();
381  }
382
383  file.setFileName( JailDir + "/." + jailName + ".meta/alias-ipv6" );
384  if ( ! IPv6Alias.isEmpty() ) {
385    if ( file.open( QIODevice::WriteOnly ) ) {
386       QTextStream stream( &file );
387       for (int i = 0; i < IPv6Alias.size(); ++i)
388         stream << IPv6Alias.at(i);
389       file.close();
390    }
391  } else {
392    file.remove();
393  }
394
395  file.setFileName( JailDir + "/." + jailName + ".meta/alias-bridge-ipv6" );
396  if ( ! IPv6AliasBridge.isEmpty() ) {
397    if ( file.open( QIODevice::WriteOnly ) ) {
398       QTextStream stream( &file );
399       for (int i = 0; i < IPv6AliasBridge.size(); ++i)
400         stream << IPv6AliasBridge.at(i);
401       file.close();
402    }
403  } else {
404    file.remove();
405  }
406
407  file.setFileName( JailDir + "/." + jailName + ".meta/ipv4" );
408  if ( checkIPv4->isChecked() ) {
409    if ( file.open( QIODevice::WriteOnly ) ) {
410       QTextStream stream( &file ); tmp = lineIP->text();
411       if (tmp.indexOf("/") == -1)
412         tmp = tmp + "/24"; 
413       stream << tmp;
414       file.close();
415    }
416  } else {
417    file.remove();
418  }
419
420  file.setFileName( JailDir + "/." + jailName + ".meta/bridge-ipv4" );
421  if ( checkIPv4Bridge->isChecked() ) {
422    if ( file.open( QIODevice::WriteOnly ) ) {
423       QTextStream stream( &file ); tmp = lineIPBridge->text();
424       if (tmp.indexOf("/") == -1)
425         tmp = tmp + "/24"; 
426       stream << tmp;
427       file.close();
428    }
429  } else {
430    file.remove();
431  }
432
433  file.setFileName( JailDir + "/." + jailName + ".meta/defaultrouter-ipv4" );
434  if ( checkIPv4Router->isChecked() ) {
435    if ( file.open( QIODevice::WriteOnly ) ) {
436       QTextStream stream( &file ); tmp = lineIPRouter->text();
437       if (tmp.indexOf("/") == -1)
438         tmp = tmp + "/24"; 
439       stream << tmp;
440       file.close();
441    }
442  } else {
443    file.remove();
444  }
445
446  file.setFileName( JailDir + "/." + jailName + ".meta/ipv6" );
447  if ( checkIPv6->isChecked() ) {
448    if ( file.open( QIODevice::WriteOnly ) ) {
449       QTextStream stream( &file ); tmp = lineIP6->text();
450       if (tmp.indexOf("/") == -1)
451         tmp = tmp + "/64"; 
452       stream << tmp;
453       file.close();
454    }
455  } else {
456    file.remove();
457  }
458
459  file.setFileName( JailDir + "/." + jailName + ".meta/bridge-ipv6" );
460  if ( checkIPv6Bridge->isChecked() ) {
461    if ( file.open( QIODevice::WriteOnly ) ) {
462       QTextStream stream( &file ); tmp = lineIP6Bridge->text();
463       if (tmp.indexOf("/") == -1)
464         tmp = tmp + "/64"; 
465       stream << tmp;
466       file.close();
467    }
468  } else {
469    file.remove();
470  }
471
472  file.setFileName( JailDir + "/." + jailName + ".meta/defaultrouter-ipv6" );
473  if ( checkIPv6Router->isChecked() ) {
474    if ( file.open( QIODevice::WriteOnly ) ) {
475       QTextStream stream( &file ); tmp = lineIP6Router->text();
476       if (tmp.indexOf("/") == -1)
477         tmp = tmp + "/64"; 
478       stream << tmp;
479       file.close();
480    }
481  } else {
482    file.remove();
483  }
484
485        /*
486        QStringList IPs;
487        for ( int i=0; i<listIP->count() ; i++)
488                IPs << listIP->item(i)->text();
489
490        qDebug() << "Updating IPs...";
491        QProcess ipcmd;
492        if ( IPs.count() == 0 )
493          ipcmd.start(QString("warden"), QStringList() << "set" << "ip" << wardenIP << "" );
494        else
495          ipcmd.start(QString("warden"), QStringList() << "set" << "ip" << wardenIP << IPs.join(",") );
496
497        setEnabled(false);
498        ipcmd.waitForFinished(1000);
499        while ( ipcmd.state() != QProcess::NotRunning ) {
500                ipcmd.waitForFinished(100);
501                QCoreApplication::processEvents();
502        }
503        */
504       
505}
506
507void dialogEditIP::slotAddClicked()
508{
509   bool ok;
510   QString address = QInputDialog::getText(this, tr("Add IP"),
511                        tr("IP Address:"), QLineEdit::Normal,
512                        QString(), &ok);
513   if ( ! ok )
514      return;
515
516   if ( ! checkValidBlock(address, "IPv4") || checkValidBlock(address, "IPv6") )
517      QMessageBox::critical(this, tr("Warden"), \
518                                tr("Please enter a valid IPV4 or IPV6 address!"), \
519                                QMessageBox::Ok, \
520                                QMessageBox::Ok);
521
522   // IPv4 Aliases
523   if ( comboIPType->currentIndex() == 0 ) {
524      if ( address.indexOf("/") == -1 ) 
525         address = address + "/24";
526      IPv4Alias << address;
527      listIP->addItem(address);
528   }
529
530   // IPv4 Bridge Aliases
531   if ( comboIPType->currentIndex() == 1 ) {
532      if ( address.indexOf("/") == -1 ) 
533         address = address + "/24";
534      IPv4AliasBridge << address;
535      listIP->addItem(address);
536   }
537
538   // IPv6 Aliases
539   if ( comboIPType->currentIndex() == 2 ) {
540      if ( address.indexOf("/") == -1 ) 
541         address = address + "/64";
542      IPv6Alias << address;
543      listIP->addItem(address);
544   }
545
546   // IPv6 Bridge Aliases
547   if ( comboIPType->currentIndex() == 3 ) {
548      if ( address.indexOf("/") == -1 ) 
549         address = address + "/64";
550      IPv6AliasBridge << address;
551      listIP->addItem(address);
552   }
553
554}
555
556bool dialogEditIP::checkValidBlock(QString block, QString type)
557{
558   QString url = block;
559
560   // Strip off the /24 part
561   if ( url.indexOf("/") != -1 )
562      url.truncate(url.indexOf("/"));
563
564   if ( type == "IPv4" ) {
565      if ( ! pcbsd::Utils::validateIPV4(url) )
566        return false;
567
568   } else {
569      if ( ! pcbsd::Utils::validateIPV6(url) )
570        return false;
571
572   }
573
574   return true;
575}
576
577void dialogEditIP::slotRemClicked()
578{
579        if ( ! listIP->currentItem() )
580                return;
581
582        delete listIP->currentItem();
583}
Note: See TracBrowser for help on using the repository browser.