def buildGui(self): layout = QFormLayout(self) self.is_default = False self.setTitle(tr("Route specification")) self.setSubTitle(tr("Specify a route")) self.network = NetworkCombo(parent=self, modelname=MODEL_NETWORKS_EXCL_HA) layout.addRow(tr("Network :"), self.network) dst_group = QGroupBox() layout.addRow(dst_group) dst_group.setTitle(tr("Route parameters")) form = QGridLayout(dst_group) self.destination = NetworkEdit() self.gateway = IpEdit() self.registerField("destination", self.destination) form.addWidget(QLabel(tr("Destination")), 0, 0) form.addWidget(self.destination, 0, 1) self.connect(self.gateway, SIGNAL('textChanged(QString)'), self.ifCompleteChanged) self.connect(self.destination, SIGNAL('textChanged(QString)'), self.ifCompleteChanged) build_default = QPushButton(tr("Build a default route")) form.addWidget(build_default, 0, 2) self.connect(build_default, SIGNAL('clicked()'), self.setDefaultRoute) self.registerField("gateway", self.gateway) form.addWidget(QLabel(tr("Gateway")), 2, 0) form.addWidget(self.gateway, 2, 1) self.message = Help() form.addWidget(self.message, 3, 0, 1, 3)
def __init__(self, interface, net=None, parent=None): QFrame.__init__(self, parent) self.interface = None self.interface_label = QLabel() self.interface_label.setTextFormat(Qt.RichText) self.setInterface(interface) #synonym for "inside a wizard" self.new = net is None if self.new: net = Net("", IP("0.0.0.0")) self.net = net self.setWindowTitle(tr("Editing network %s") % self.net.label) self.net_ip = NetworkEdit(self, accept_empty=False) net_ip_text = "" if self.new else unicode(self.net.net) self.net_ip.setText(net_ip_text) self.ip_addrs = NetIpListEdit(self.net) self.inputs = (self.net_ip, self.ip_addrs) self.net_label = OptionnalLine(value=self.net.label, hint=tr('network label')) self.net_label.setWhatsThis("<h3>%s</h3>" % tr('Enter a label for this network')) self.message_area = MessageArea() self.message_area.setWordWrap() form = QFormLayout(self) form.addRow(tr("Supporting interface"), self.interface_label) form.addRow(tr("Network address"), self.net_ip) form.addRow(tr("IP addresses on this network"), self.ip_addrs) form.addRow(tr("Network label"), self.net_label) form.addRow(self.message_area) for item in self.inputs + (self.net_label,): self.connect(item, SIGNAL('editing done'), self.isValid) self.connect(self.net_label, SIGNAL("textChanged(QString)"), self.changeTitle)
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)
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 NetFrame(QFrame): def __init__(self, interface, net=None, parent=None): QFrame.__init__(self, parent) self.interface = None self.interface_label = QLabel() self.interface_label.setTextFormat(Qt.RichText) self.setInterface(interface) #synonym for "inside a wizard" self.new = net is None if self.new: net = Net("", IP("0.0.0.0")) self.net = net self.setWindowTitle(tr("Editing network %s") % self.net.label) self.net_ip = NetworkEdit(self, accept_empty=False) net_ip_text = "" if self.new else unicode(self.net.net) self.net_ip.setText(net_ip_text) self.ip_addrs = NetIpListEdit(self.net) self.inputs = (self.net_ip, self.ip_addrs) self.net_label = OptionnalLine(value=self.net.label, hint=tr('network label')) self.net_label.setWhatsThis("<h3>%s</h3>" % tr('Enter a label for this network')) self.message_area = MessageArea() self.message_area.setWordWrap() form = QFormLayout(self) form.addRow(tr("Supporting interface"), self.interface_label) form.addRow(tr("Network address"), self.net_ip) form.addRow(tr("IP addresses on this network"), self.ip_addrs) form.addRow(tr("Network label"), self.net_label) form.addRow(self.message_area) for item in self.inputs + (self.net_label,): self.connect(item, SIGNAL('editing done'), self.isValid) self.connect(self.net_label, SIGNAL("textChanged(QString)"), self.changeTitle) def setInterface(self, interface): self.interface = interface if interface is None: name = tr("unset") else: name = interface.fullName() self.interface_label.setText("<i>%s</i>" % name) def changeTitle(self, *args): """ just discarding args after 'self' """ self.emit(SIGNAL('change title'), unicode(self.net_label.value()).strip()) @validator def _validNetIp(self): ok, msg = self.net_ip.isValidWithMsg() if not ok: err = "Network address field is incorrectly specified:<br/>%s" return False, tr(err) % msg return True, None @validator def _validIpAddrs(self): ok, msg = self.ip_addrs.isValidWithMsg(accept_empty=True) if not ok: #investigate try: self.ip_addrs.values() except InputException, err: return False, err.args[0] error_message = tr("IP addresses are incorrectly specified:") error_message += "<br/>%s" % msg return False, error_message return True, None
class FormPage(QWizardPage): def __init__(self, data, ip_version=4, parent=None): QWizardPage.__init__(self, parent) self.__editing_default_state = _strdefault(unicode(data[DESTINATION])) self.qnetobject = QNetObject.getInstance() self.buildGui() self.fillView(data) def _isEditingDefaultV4Route(self): return self.__editing_default_state == 4 def _isEditingDefaultV6Route(self): return self.__editing_default_state == 6 def buildGui(self): layout = QFormLayout(self) self.is_default = False self.setTitle(tr("Route specification")) self.setSubTitle(tr("Specify a route")) self.network = NetworkCombo(parent=self, modelname=MODEL_NETWORKS_EXCL_HA) layout.addRow(tr("Network :"), self.network) dst_group = QGroupBox() layout.addRow(dst_group) dst_group.setTitle(tr("Route parameters")) form = QGridLayout(dst_group) self.destination = NetworkEdit() self.gateway = IpEdit() self.registerField("destination", self.destination) form.addWidget(QLabel(tr("Destination")), 0, 0) form.addWidget(self.destination, 0, 1) self.connect(self.gateway, SIGNAL('textChanged(QString)'), self.ifCompleteChanged) self.connect(self.destination, SIGNAL('textChanged(QString)'), self.ifCompleteChanged) build_default = QPushButton(tr("Build a default route")) form.addWidget(build_default, 0, 2) self.connect(build_default, SIGNAL('clicked()'), self.setDefaultRoute) self.registerField("gateway", self.gateway) form.addWidget(QLabel(tr("Gateway")), 2, 0) form.addWidget(self.gateway, 2, 1) self.message = Help() form.addWidget(self.message, 3, 0, 1, 3) def fillView(self, data): if data[DESTINATION]: self.destination.setText(data[DESTINATION]) if data[GATEWAY]: self.gateway.setText(data[GATEWAY]) gateway = IP(unicode(data[GATEWAY])) net = self.qnetobject.netcfg.getNetForIp(gateway) if net is not None: self.network.selectNet(net) def ifCompleteChanged(self, orig_value=False): new_value = self.isComplete() if new_value != orig_value: self.emit(SIGNAL('completeChanged()')) def setDefaultRoute(self): selected_net = self.network.getNet() if selected_net is None: self.message.setMessage("<i>%s</i>" % tr("There is no network configuration, you cannot configure routes")) version = 4 else: version = selected_net.net.version() if 4 == version: default = Route.IPV4_DEFAULT else: default = Route.IPV6_DEFAULT self.destination.setText(default) def isComplete(self): gw_text = unicode(self.field('gateway').toString()) dst_text = unicode(self.field('destination').toString()) if not gw_text: self.message.setMessage("<i>%s</i>" % tr("Please fill the gateway field")) return False if (not self.gateway.isValid()): self.message.setMessage("<i>%s</i>" % tr("Invalid gateway")) return False if not dst_text: self.message.setMessage("<i>%s</i>" % tr("Please fill the destination field")) return False if not self.destination.isValid(): self.message.setMessage("<i>%s</i>" % tr("Invalid destination")) return False destination_version, gateway_version = \ (item.version() for item in (self.destination.value(), self.gateway.value())) if destination_version != gateway_version: error = "%s (%s) %s (%s)." % ( tr("The gateway IP version"), gateway_version, tr("does not match the destination IP version"), destination_version ) self.message.setMessage(error) return False str_gateway = unicode(self.field('gateway').toString()) gateway_ip = IP(str_gateway) selected_net = self.network.getNet() if selected_net is None: self.message.setMessage("<i>%s</i>" % tr("There is no network configuration, you cannot configure routes")) return False ok, msg = _valid_gateway_on_network(gateway_ip, str_gateway, selected_net) if not ok: self.message.setMessage(msg) return False ok, msg = _valid_not_too_much_default_gw( self.qnetobject.netcfg, self.destination.value(), destination_version, self._isEditingDefaultV4Route(), self._isEditingDefaultV6Route() ) if not ok: self.message.setMessage(msg) return False ok, msg = self.qnetobject.netcfg.isValidWithMsg() if not ok: self.message.setMessage(msg) return False self.message.setNoMessage() return True def validatePage(self): route = self.integrate_route() if not route.isDefault(): return True try: default_router, interface = self.qnetobject.netcfg.getDefaultGateway( route.dst.version() ) except NoMatch: return True default_route = None for other_route in interface.routes: if other_route.isDefault(): default_route = other_route if default_route is not None: interface.routes.discard(default_route) ok, msg = self.qnetobject.netcfg.isValidWithMsg() if not ok: self.message.setMessage(msg) return False return True def integrate_route(self): route = RouteRW( self.destination.value(), self.gateway.value(), ) return route