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

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