def _buildGui(self): frame = QFrame() layout = QVBoxLayout(frame) layout.addWidget(QLabel(tr("<H1>Mobile VPN</H1>"))) self.activation_box = QGroupBox(tr("Feature Activation")) self.activation = QGridLayout(self.activation_box) # enabled checkbox: self.enabledCheckBox = QCheckBox() self.mainwindow.writeAccessNeeded(self.enabledCheckBox) self.connect(self.enabledCheckBox, SIGNAL('toggled(bool)'), self.setEnabled) self.enabledLabel = QLabel(tr('Enable Mobile VPN')) self.activation.addWidget(self.enabledLabel, 0, 0) self.activation.addWidget(self.enabledCheckBox, 0, 1) layout.addWidget(self.activation_box) options_box = QGroupBox(tr("Network Configuration")) options = QFormLayout(options_box) self.serverIpEdit = IpOrHostnameOrFqdnEdit() self.connect(self.serverIpEdit, SIGNAL('editingFinished()'), self.setServer) self.protocolComboBox = QComboBox() self.protocolComboBox.addItem('tcp') self.protocolComboBox.addItem('udp') self.connect(self.protocolComboBox, SIGNAL('currentIndexChanged(QString)'), self.setProtocol) self.portEdit = PortEdit() self.connect(self.portEdit, SIGNAL('editingFinished()'), self.setPort) self.clientNetNetworkEdit = NetworkEdit() self.connect(self.clientNetNetworkEdit, SIGNAL('editingFinished()'), self.setClientNetwork) self.redirectCheckBox = QCheckBox() self.connect(self.redirectCheckBox, SIGNAL('toggled(bool)'), self.setRedirect) options.addRow(tr("Server public address (for client configuration)"), self.serverIpEdit) options.addRow(tr("Protocol"), self.protocolComboBox) options.addRow(tr("Port"), self.portEdit) options.addRow(tr("Virtual network address of VPN clients"), self.clientNetNetworkEdit) options.addRow(tr("Redirect default gateway through the VPN"), self.redirectCheckBox) self.pushed_routes = self._mkPushedRoutes(5) options.addRow(QLabel(tr("This VPN's routed networks"))) options.addRow(self.pushed_routes) self.connect(self.pushed_routes, SIGNAL('textChanged()'), self.setModified) self.connect(self.pushed_routes, SIGNAL('textChanged()'), self.setPushedRoutes) layout.addWidget(options_box) self.pki_embed = PkiEmbedWidget(self.client, self, "openvpn", PkiEmbedWidget.SHOW_ALL | PkiEmbedWidget.CRL_OPTIONAL, self.setModified) layout.addWidget(self.pki_embed) self.mainwindow.writeAccessNeeded( self.serverIpEdit, self.protocolComboBox, self.portEdit, self.clientNetNetworkEdit, self.redirectCheckBox, self.pushed_routes, self.pki_embed) getClientConfigButton = QPushButton(tr('Get client configuration')) self.connect(getClientConfigButton, SIGNAL('clicked()'), self.getClientConfig) layout.addWidget(getClientConfigButton) layout.addStretch() self.setWidget(frame) self.setWidgetResizable(True)
def __init__(self, client, parent): self.__loading = True ScrollArea.__init__(self) self.mainwindow = parent self.client = client self.modified = False self.qauthcertobject = QAuthCertObject.getInstance() frame = QFrame(self) layout = QVBoxLayout(frame) layout.addWidget(QLabel('<H1>%s</H1>' % tr('Authentication server') )) head_box = QGroupBox(tr("How the authentication server handles certificates")) head = QFormLayout(head_box) self.strictCheckBox = QCheckBox() head.addRow(QLabel(tr("Strict mode (check the client's certificate against the installed CA)")), self.strictCheckBox) self.connect(self.strictCheckBox, SIGNAL('toggled(bool)'), self.setStrict) self.cl_auth_box = QGroupBox(tr("Client authentication with a certificate is")) cl_auth = QVBoxLayout(self.cl_auth_box) self.auth_by_cert = QButtonGroup() self.auth_by_cert.setExclusive(True) self.mainwindow.writeAccessNeeded(self.strictCheckBox) labels = [tr('forbidden'), tr('allowed'), tr('mandatory')] for index, label_button in enumerate(labels): button = QRadioButton(label_button) self.auth_by_cert.addButton(button, index) cl_auth.addWidget(button) self.mainwindow.writeAccessNeeded(button) self.auth_by_cert.button(0).setChecked(Qt.Checked) self.connect(self.auth_by_cert, SIGNAL('buttonClicked(int)'), self.auth_by_cert_modified) # Captive portal # -------------- self.portal_groupbox = QGroupBox(tr("Captive portal")) self.portal_groupbox.setLayout(QVBoxLayout()) # Enabled checkbox: self.portal_checkbox = QCheckBox(tr("Enable captive portal")) self.connect(self.portal_checkbox, SIGNAL('toggled(bool)'), self.setPortalEnabled) # List of networks redirected to the captive portal: self.portal_nets_groupbox = QGroupBox( tr("Networks handled by the captive portal")) self.portal_nets_groupbox.setLayout(QVBoxLayout()) self.portal_nets_edit = NetworkListEdit() self.connect(self.portal_nets_edit, SIGNAL('textChanged()'), self.setPortalNets) self.portal_nets_groupbox.layout().addWidget(self.portal_nets_edit) # Pack the widgets: for widget in (self.portal_checkbox, self.portal_nets_groupbox): self.portal_groupbox.layout().addWidget(widget) self.mainwindow.writeAccessNeeded(self.portal_checkbox) self.mainwindow.writeAccessNeeded(self.portal_nets_edit) if not EDENWALL: self.portal_groupbox.setVisible(False) # authentication server self.pki_widget = PkiEmbedWidget(self.client, self, 'auth_cert', PkiEmbedWidget.SHOW_ALL|PkiEmbedWidget.CRL_OPTIONAL, self.setModified) self.mainwindow.writeAccessNeeded(self.pki_widget) layout.addWidget(head_box) layout.addWidget(self.cl_auth_box) layout.addWidget(self.portal_groupbox) layout.addWidget(self.pki_widget) layout.addStretch() self.setWidget(frame) self.setWidgetResizable(True) self.resetConf() self.__loading = False
class RoadWarriorFrontend(ScrollArea): COMPONENT = 'openvpn' LABEL = tr('Mobile VPN') REQUIREMENTS = ('openvpn',) ICON = ':/icons/vpn.png' def __init__(self, client, parent): ScrollArea.__init__(self) if not EDENWALL: raise NuConfModuleDisabled("Roadwarrior") self.loaded_done = False self.mainwindow = parent self.client = client self.modified = False self.error_message = '' self._buildGui() self.qopenvpnobject = QOpenVpnObject.getInstance() self.qopenvpnobject.openvpn = self.client.call('openvpn', 'getOpenVpnConfig') # FIXME: Remove isValid() or call it more even? self.isValid() self.resetConf() def _buildGui(self): frame = QFrame() layout = QVBoxLayout(frame) layout.addWidget(QLabel(tr("<H1>Mobile VPN</H1>"))) self.activation_box = QGroupBox(tr("Feature Activation")) self.activation = QGridLayout(self.activation_box) # enabled checkbox: self.enabledCheckBox = QCheckBox() self.mainwindow.writeAccessNeeded(self.enabledCheckBox) self.connect(self.enabledCheckBox, SIGNAL('toggled(bool)'), self.setEnabled) self.enabledLabel = QLabel(tr('Enable Mobile VPN')) self.activation.addWidget(self.enabledLabel, 0, 0) self.activation.addWidget(self.enabledCheckBox, 0, 1) layout.addWidget(self.activation_box) options_box = QGroupBox(tr("Network Configuration")) options = QFormLayout(options_box) self.serverIpEdit = IpOrHostnameOrFqdnEdit() self.connect(self.serverIpEdit, SIGNAL('editingFinished()'), self.setServer) self.protocolComboBox = QComboBox() self.protocolComboBox.addItem('tcp') self.protocolComboBox.addItem('udp') self.connect(self.protocolComboBox, SIGNAL('currentIndexChanged(QString)'), self.setProtocol) self.portEdit = PortEdit() self.connect(self.portEdit, SIGNAL('editingFinished()'), self.setPort) self.clientNetNetworkEdit = NetworkEdit() self.connect(self.clientNetNetworkEdit, SIGNAL('editingFinished()'), self.setClientNetwork) self.redirectCheckBox = QCheckBox() self.connect(self.redirectCheckBox, SIGNAL('toggled(bool)'), self.setRedirect) options.addRow(tr("Server public address (for client configuration)"), self.serverIpEdit) options.addRow(tr("Protocol"), self.protocolComboBox) options.addRow(tr("Port"), self.portEdit) options.addRow(tr("Virtual network address of VPN clients"), self.clientNetNetworkEdit) options.addRow(tr("Redirect default gateway through the VPN"), self.redirectCheckBox) self.pushed_routes = self._mkPushedRoutes(5) options.addRow(QLabel(tr("This VPN's routed networks"))) options.addRow(self.pushed_routes) self.connect(self.pushed_routes, SIGNAL('textChanged()'), self.setModified) self.connect(self.pushed_routes, SIGNAL('textChanged()'), self.setPushedRoutes) layout.addWidget(options_box) self.pki_embed = PkiEmbedWidget(self.client, self, "openvpn", PkiEmbedWidget.SHOW_ALL | PkiEmbedWidget.CRL_OPTIONAL, self.setModified) layout.addWidget(self.pki_embed) self.mainwindow.writeAccessNeeded( self.serverIpEdit, self.protocolComboBox, self.portEdit, self.clientNetNetworkEdit, self.redirectCheckBox, self.pushed_routes, self.pki_embed) getClientConfigButton = QPushButton(tr('Get client configuration')) self.connect(getClientConfigButton, SIGNAL('clicked()'), self.getClientConfig) layout.addWidget(getClientConfigButton) layout.addStretch() self.setWidget(frame) self.setWidgetResizable(True) def _mkPushedRoutes(self, lines): pushed_routes = NetworkListEdit() pushed_routes.setMaximumHeight( pushed_routes.fontMetrics().height() * lines ) return pushed_routes def loaded(self): self.loaded_done = True def isLoaded(self): return self.loaded_done def isModified(self): return self.modified def isValid(self): valid, msg = self.qopenvpnobject.openvpn.isValidWithMsg() if msg is not None: self.error_message = msg cert_validity = self.pki_embed.validate() if cert_validity is not None: if msg is None: self.error_message = '' self.error_message += '<br/>' + cert_validity + '<br/>' self.mainwindow.addToInfoArea(cert_validity, category=COLOR_ERROR) valid = False return valid def resetConf(self): self.qopenvpnobject.openvpn = self.client.call('openvpn', 'getOpenVpnConfig') self.serverIpEdit.setText(unicode(self.qopenvpnobject.openvpn.server)) self.portEdit.setText(unicode(self.qopenvpnobject.openvpn.port)) index = self.protocolComboBox.findText( unicode(self.qopenvpnobject.openvpn.protocol)) if index != -1: self.protocolComboBox.setCurrentIndex(index) self.clientNetNetworkEdit.setText( self.qopenvpnobject.openvpn.client_network) for input_widget in (self.serverIpEdit, self.portEdit): input_widget.validColor() if self.qopenvpnobject.openvpn.enabled: self.enabledCheckBox.setChecked(self.qopenvpnobject.openvpn.enabled) self.redirectCheckBox.setChecked(self.qopenvpnobject.openvpn.redirect) # Certificates configuration ssl_conf = self.qopenvpnobject.openvpn.getSSLDict() self.pki_embed.setConfig(ssl_conf) pushed_routes = self.qopenvpnobject.openvpn.manual_pushed_routes self.pushed_routes.clear() for net in pushed_routes: self.pushed_routes.append("%s\n" % net) self.setModified(False) def saveConf(self, message): conf = self.pki_embed.getConfig() self.qopenvpnobject.openvpn.setSSLDict(conf) serialized = self.qopenvpnobject.openvpn.serialize(downgrade=True) self.client.call("openvpn", 'setOpenVpnConfig', serialized, message) def setModified(self, isModified=True, message=u""): if isModified: self.modified = True self.mainwindow.setModified(self, True) if message: self.mainwindow.addToInfoArea(unicode(message)) if self.isLoaded(): self.qopenvpnobject.post_modify() else: self.modified = False def error(self, message): self.mainwindow.addToInfoArea(message, category=COLOR_ERROR) def getClientConfig(self): filename = QFileDialog.getSaveFileName(self, tr('Select a destination'), QString(u'client.ovpn')) if not filename: return async = self.client.async() self.desc = tr('Client configuration') async.call( "openvpn", 'getClientConfig', callback = self.successDiag, errback = self.errorDiag, callbackArgs=(filename, self.desc) ) def successDiag(self, file_, filename, desc): with open(filename, 'wb') as fd: fd.write(decodeFileContent(file_)) self.mainwindow.addToInfoArea(tr("%s saved in '%s'.") % (desc, filename)) def errorDiag(self, error): self.mainwindow.addToInfoArea(tr("Fetching %s failed.") % self.desc) warning = QMessageBox(self) warning.setWindowTitle(tr('Fetching diagnostic failed')) warning.setText(tr('An error has occurred while fetching %s.') % self.desc) warning.setDetailedText(exceptionAsUnicode(error)) warning.setIcon(QMessageBox.Warning) warning.exec_() def setEnabled(self, value): if value != self.qopenvpnobject.openvpn.enabled: self.qopenvpnobject.openvpn.setEnabled(value) self.setModified() def setServer(self): value = self.serverIpEdit.text() if value != self.qopenvpnobject.openvpn.server: self.qopenvpnobject.openvpn.setServer(value) self.setModified() def setPort(self): value = self.portEdit.text() if value != self.qopenvpnobject.openvpn.port: self.qopenvpnobject.openvpn.setPort(value) self.setModified() def setProtocol(self, value): if value != self.qopenvpnobject.openvpn.protocol: self.qopenvpnobject.openvpn.setProtocol(value) self.setModified() def setClientNetwork(self): value = self.clientNetNetworkEdit.text() if value != self.qopenvpnobject.openvpn.client_network: self.qopenvpnobject.openvpn.setClientNetwork(value) self.setModified() def setRedirect(self, value): if value != self.qopenvpnobject.openvpn.redirect: self.qopenvpnobject.openvpn.setRedirect(value) self.setModified() #disable pushed_routes when redirecting default gw enable = (not value) and (not self.mainwindow.isReadOnly()) self.pushed_routes.setEnabled(enable) def setPushedRoutes(self): if self.pushed_routes.isValid(): pushed_routes = tuple(self.pushed_routes.value()) self.qopenvpnobject.openvpn.manual_pushed_routes = pushed_routes def onApplyFinished(self): self.pki_embed.feed()
class AuthenticationFrontend(ScrollArea): COMPONENT = 'auth_cert' LABEL = tr('Authentication server') REQUIREMENTS = ('auth_cert',) ICON = ':/icons/auth_protocol.png' def __init__(self, client, parent): self.__loading = True ScrollArea.__init__(self) self.mainwindow = parent self.client = client self.modified = False self.qauthcertobject = QAuthCertObject.getInstance() frame = QFrame(self) layout = QVBoxLayout(frame) layout.addWidget(QLabel('<H1>%s</H1>' % tr('Authentication server') )) head_box = QGroupBox(tr("How the authentication server handles certificates")) head = QFormLayout(head_box) self.strictCheckBox = QCheckBox() head.addRow(QLabel(tr("Strict mode (check the client's certificate against the installed CA)")), self.strictCheckBox) self.connect(self.strictCheckBox, SIGNAL('toggled(bool)'), self.setStrict) self.cl_auth_box = QGroupBox(tr("Client authentication with a certificate is")) cl_auth = QVBoxLayout(self.cl_auth_box) self.auth_by_cert = QButtonGroup() self.auth_by_cert.setExclusive(True) self.mainwindow.writeAccessNeeded(self.strictCheckBox) labels = [tr('forbidden'), tr('allowed'), tr('mandatory')] for index, label_button in enumerate(labels): button = QRadioButton(label_button) self.auth_by_cert.addButton(button, index) cl_auth.addWidget(button) self.mainwindow.writeAccessNeeded(button) self.auth_by_cert.button(0).setChecked(Qt.Checked) self.connect(self.auth_by_cert, SIGNAL('buttonClicked(int)'), self.auth_by_cert_modified) # Captive portal # -------------- self.portal_groupbox = QGroupBox(tr("Captive portal")) self.portal_groupbox.setLayout(QVBoxLayout()) # Enabled checkbox: self.portal_checkbox = QCheckBox(tr("Enable captive portal")) self.connect(self.portal_checkbox, SIGNAL('toggled(bool)'), self.setPortalEnabled) # List of networks redirected to the captive portal: self.portal_nets_groupbox = QGroupBox( tr("Networks handled by the captive portal")) self.portal_nets_groupbox.setLayout(QVBoxLayout()) self.portal_nets_edit = NetworkListEdit() self.connect(self.portal_nets_edit, SIGNAL('textChanged()'), self.setPortalNets) self.portal_nets_groupbox.layout().addWidget(self.portal_nets_edit) # Pack the widgets: for widget in (self.portal_checkbox, self.portal_nets_groupbox): self.portal_groupbox.layout().addWidget(widget) self.mainwindow.writeAccessNeeded(self.portal_checkbox) self.mainwindow.writeAccessNeeded(self.portal_nets_edit) if not EDENWALL: self.portal_groupbox.setVisible(False) # authentication server self.pki_widget = PkiEmbedWidget(self.client, self, 'auth_cert', PkiEmbedWidget.SHOW_ALL|PkiEmbedWidget.CRL_OPTIONAL, self.setModified) self.mainwindow.writeAccessNeeded(self.pki_widget) layout.addWidget(head_box) layout.addWidget(self.cl_auth_box) layout.addWidget(self.portal_groupbox) layout.addWidget(self.pki_widget) layout.addStretch() self.setWidget(frame) self.setWidgetResizable(True) self.resetConf() self.__loading = False def setModified(self, isModified=True, message=""): if self.__loading: return if isModified: self.modified = True self.mainwindow.setModified(self, True) if message: self.mainwindow.addToInfoArea(message) else: self.modified = False def setModifiedCallback(self, *unused): self.setModified() def isModified(self): return self.modified def saveConf(self, message): self.qauthcertobject.auth_cert.auth_by_cert = self.auth_by_cert.checkedId() conf = self.pki_widget.getConfig() self.qauthcertobject.auth_cert.setSSLDict(conf) serialized = self.qauthcertobject.auth_cert.serialize(downgrade=True) self.client.call('auth_cert', 'setAuthCertConfig', serialized, message) def resetConf(self): auth_cert_loaded = self._reset_helper( 'auth_cert', 'getAuthCertConfig', self.qauthcertobject, tr("Authentication interface enabled"), tr("Authentication disabled: backend not loaded") ) self.setModified(False) remote = self.qauthcertobject.auth_cert.getReceivedSerialVersion() if remote < 3: self.mainwindow.addWarningMessage(tr('Captive portal configuration disabled: this frontend and your appliance software versions are not compatible.')) enable_portal = ( auth_cert_loaded and EDENWALL and remote >= 3 ) self.portal_groupbox.setVisible(enable_portal) if not auth_cert_loaded: return self.strictCheckBox.setChecked(self.qauthcertobject.auth_cert.strict) if not self.qauthcertobject.auth_cert.auth_by_cert: self.qauthcertobject.auth_cert.auth_by_cert = 0 self.auth_by_cert.button( self.qauthcertobject.auth_cert.auth_by_cert).setChecked(True) # Captive portal: self.portal_checkbox.setChecked( self.qauthcertobject.auth_cert.portal_enabled) self.portal_nets_edit.setIpAddrs( self.qauthcertobject.auth_cert.portal_nets) # Certificate (PKI): pki_conf = self.qauthcertobject.auth_cert.getSSLDict() self.pki_widget.setConfig(pki_conf) def error(self, message): self.mainwindow.addToInfoArea(message, category=COLOR_ERROR) def auth_by_cert_modified(self, idbox): button_name = self.auth_by_cert.button(idbox).text() info = tr("Certificates - Authentication with client certificate : '%s'") % button_name self.setModified(message=info) def setPortalEnabled(self, value): if value != self.qauthcertobject.auth_cert.portal_enabled: self.qauthcertobject.auth_cert.setPortalEnabled(value) self.setModified() def setPortalNets(self): if self.portal_nets_edit.isValid(): self.qauthcertobject.auth_cert.setPortalNets( self.portal_nets_edit.value()) self.setModified() def setStrict(self, value): if value != self.qauthcertobject.auth_cert.strict: self.qauthcertobject.auth_cert.setStrict(value) self.setModified() self.cl_auth_box.setEnabled(value) def isValid(self): cert_validity = self.pki_widget.validate() if cert_validity is not None: self.error_message = '<br/>' + cert_validity + '<br/>' self.mainwindow.addToInfoArea(cert_validity, category=COLOR_ERROR) return False return True def onApplyFinished(self): self.pki_widget.feed()