summaryrefslogtreecommitdiffstats
path: root/tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp')
-rw-r--r--tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp603
1 files changed, 603 insertions, 0 deletions
diff --git a/tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp b/tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp
new file mode 100644
index 0000000..7cee87a
--- /dev/null
+++ b/tdenetworkmanager/vpn-plugins/openvpn/src/tdenetman-openvpn.cpp
@@ -0,0 +1,603 @@
+/***************************************************************************
+ *
+ * knetworkmanager-openvpn.cpp - A NetworkManager frontend for TDE
+ *
+ * Copyright (C) 2006 Novell, Inc.
+ *
+ * Author: Helmut Schaa <hschaa@suse.de>, <helmut.schaa@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#include <klocale.h>
+#include <tqmessagebox.h>
+#include <tqbutton.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <tqobjectlist.h>
+#include <tqobject.h>
+#include <tqcheckbox.h>
+#include <kpassdlg.h>
+#include <kgenericfactory.h>
+#include <tqwidgetstack.h>
+#include <tqfileinfo.h>
+#include <tqhostaddress.h>
+
+#include "tdenetman-openvpn.h"
+
+typedef KGenericFactory<OpenVPNPlugin> OpenVPNPluginFactory;
+K_EXPORT_COMPONENT_FACTORY( tdenetman_openvpn, OpenVPNPluginFactory("tdenetman_openvpn"));
+
+/************************************
+* OpenVPNPlugin
+************************************/
+OpenVPNPlugin::OpenVPNPlugin(TQObject* parent, const char* name, const TQStringList& args)
+ : VPNPlugin(parent, name, args)
+{
+
+}
+
+OpenVPNPlugin::~OpenVPNPlugin()
+{
+
+}
+
+VPNConfigWidget* OpenVPNPlugin::CreateConfigWidget(TQWidget* parent)
+{
+ return new OpenVPNConfig(parent);
+}
+
+VPNAuthenticationWidget* OpenVPNPlugin::CreateAuthenticationWidget(TQWidget* parent)
+{
+ return new OpenVPNAuthentication(parent);
+}
+
+/************************************
+* OpenVPNConnectionType
+************************************/
+OpenVPNConnectionType::CONNECTIONTYPE OpenVPNConnectionType::mapString2ConnectionType(int prop)
+{
+ if (prop == 0)
+ return X509;
+ else if (prop == 1)
+ return SHARED_KEY;
+ else if (prop == 2)
+ return PASSWORD;
+ else if (prop == 3)
+ return X509USERPASS;
+ return UNKNOWN;
+}
+
+int OpenVPNConnectionType::mapConnectionType2String(CONNECTIONTYPE connType)
+{
+ switch(connType)
+ {
+ case X509:
+ return 0;
+ case SHARED_KEY:
+ return 1;
+ case PASSWORD:
+ return 2;
+ case X509USERPASS:
+ return 3;
+ default:
+ return -1;
+ }
+ return -1;
+}
+
+/************************************
+* OpenVPNConfig
+************************************/
+
+OpenVPNConfig::OpenVPNConfig(TQWidget* parent)
+ : VPNConfigWidget(parent)
+{
+ TQVBoxLayout* layout = new TQVBoxLayout(this, 1, 1);
+ _openvpnWidget = new OpenVPNConfigWidget(this);
+ layout->addWidget(_openvpnWidget);
+
+ connect(_openvpnWidget->chkUseCipher, TQT_SIGNAL(toggled(bool)), _openvpnWidget->cboCipher, TQT_SLOT(setEnabled(bool)));
+ connect(_openvpnWidget->chkUseTLS, TQT_SIGNAL(toggled(bool)), _openvpnWidget->cboDirection, TQT_SLOT(setEnabled(bool)));
+ connect(_openvpnWidget->chkUseTLS, TQT_SIGNAL(toggled(bool)), _openvpnWidget->editTLSAuth, TQT_SLOT(setEnabled(bool)));
+ connect(_openvpnWidget->chkIPAdresses, TQT_SIGNAL(toggled(bool)), _openvpnWidget->routes, TQT_SLOT(setEnabled(bool)));
+
+ // add all Cipher modes to the Combobox
+ getCipherModes();
+
+ // switch to the right configuration interface when selecting the connection type
+ connect(_openvpnWidget->cboConnectionType, TQT_SIGNAL( activated(int)), _openvpnWidget->widgetStack, TQT_SLOT(raiseWidget(int)));
+ this->languageChange();
+}
+
+OpenVPNConfig::~OpenVPNConfig()
+{
+
+}
+
+void OpenVPNConfig::languageChange()
+{
+ _openvpnWidget->cboConnectionType->insertItem(i18n("X.509 Certificates"), OpenVPNConnectionType::X509 );
+ _openvpnWidget->cboConnectionType->insertItem(i18n("Pre-shared key") , OpenVPNConnectionType::SHARED_KEY );
+ _openvpnWidget->cboConnectionType->insertItem(i18n("Password Authentication") , OpenVPNConnectionType::PASSWORD );
+ _openvpnWidget->cboConnectionType->insertItem(i18n("X.509 with Password Authentication") , OpenVPNConnectionType::X509USERPASS );
+
+ _openvpnWidget->cboDirection->insertItem(i18n("none"));
+ _openvpnWidget->cboDirection->insertItem(i18n("0"));
+ _openvpnWidget->cboDirection->insertItem(i18n("1"));
+}
+
+TQString OpenVPNConfig::findOpenVPNBinary()
+{
+ static const char *openvpn_binary_paths[] =
+ {
+ "/usr/sbin/openvpn",
+ "/sbin/openvpn",
+ NULL
+ };
+
+ const char **openvpn_binary = openvpn_binary_paths;
+
+ while (*openvpn_binary != NULL) {
+ if ( TQFileInfo(*openvpn_binary).exists())
+ break;
+ openvpn_binary++;
+ }
+
+ return *openvpn_binary;
+}
+
+
+void OpenVPNConfig::receiveCipherData(KProcess*, char* buffer, int len)
+{
+ // add possible cipher modes to the combobox
+ TQStringList cipherModes = TQStringList::split("\n", TQString::fromLatin1(buffer, len), false );
+ for (TQStringList::ConstIterator it = cipherModes.begin(); it != cipherModes.end(); ++it)
+ {
+ _openvpnWidget->cboCipher->insertItem((*it));
+ }
+}
+
+void OpenVPNConfig::getCipherModes()
+{
+ // get all possible cipher modes
+ TQString openvpn = findOpenVPNBinary();
+ if (!openvpn.isNull()) {
+ KProcess* cipherHelper = new KProcess();
+ cipherHelper->setUseShell(true, "/bin/sh");
+ *cipherHelper << TQString::fromLatin1("%1 --show-ciphers | awk '/^[A-Z][A-Z0-9]+-/ { print $1 }'").arg(openvpn);
+ connect (cipherHelper, TQT_SIGNAL(receivedStdout(KProcess*, char*, int)), this, TQT_SLOT(receiveCipherData(KProcess*, char*, int)));
+ kdDebug() << "starting openvpn to get cipher modes" << endl;
+ if (!cipherHelper->start(KProcess::Block, KProcess::Stdout)) {
+ kdDebug() << "error starting openvpn" << endl;
+ }
+ }
+}
+
+void OpenVPNConfig::setVPNData(TDENetworkSingleRouteConfigurationList& routes, TDENetworkSettingsMap& properties, TDENetworkSettingsMap& secrets)
+{
+ m_vpnProperties = properties;
+ m_vpnSecrets = secrets;
+
+ // fill up our inputfields
+ for(TQMap<TQString, TQString>::ConstIterator it = properties.begin(); it != properties.end(); ++it)
+ {
+ TQString entry = it.key();
+ TQString value = it.data();
+
+ if (entry == "connection-type")
+ {
+ OpenVPNConnectionType::CONNECTIONTYPE type = OpenVPNConnectionType::mapString2ConnectionType(value.toInt());
+ _openvpnWidget->cboConnectionType->setCurrentItem(type);
+ _openvpnWidget->widgetStack->raiseWidget(type);
+ }
+ else if (entry == "remote")
+ {
+ _openvpnWidget->gateway->setText(value);
+ }
+ else if (entry == "port")
+ {
+ if (value.toInt() > 0)
+ {
+ _openvpnWidget->port->setText(value);
+ _openvpnWidget->chkDefaultPort->setChecked(false);
+ }
+ else
+ {
+ _openvpnWidget->chkDefaultPort->setChecked(true);
+ }
+ }
+ else if (entry == "proto" || entry == "proto-tcp")
+ {
+ _openvpnWidget->chkUseTCP->setChecked( value == "yes");
+ }
+ else if (entry == "ca")
+ {
+ _openvpnWidget->editCA->setURL(value);
+ }
+ else if (entry == "cert")
+ {
+ _openvpnWidget->editCert->setURL(value);
+ }
+ else if (entry == "key")
+ {
+ _openvpnWidget->editKey->setURL(value);
+ }
+ else if (entry == "cipher")
+ {
+ _openvpnWidget->chkUseCipher->setChecked(true);
+ _openvpnWidget->cboCipher->setCurrentItem(value);
+ }
+ else if (entry == "comp-lzo")
+ {
+ _openvpnWidget->chkUseLZO->setChecked(value == "true");
+ }
+ else if (entry == "shared-key" || entry == "static-key")
+ {
+ _openvpnWidget->editSharedKey->setURL(value);
+ }
+ else if (entry == "username")
+ {
+ _openvpnWidget->editUsername->setText(value);
+ }
+ else if (entry == "local-ip")
+ {
+ _openvpnWidget->editLocalIP->setText(value);
+ }
+ else if (entry == "remote-ip")
+ {
+ _openvpnWidget->editRemoteIP->setText(value);
+ }
+ else if (entry == "dev" || entry == "tap-dev") {
+ _openvpnWidget->chkUseTAP->setChecked(value == "true");
+ }
+ else if (entry == "ta")
+ {
+ _openvpnWidget->chkUseTLS->setChecked(true);
+ _openvpnWidget->editTLSAuth->setURL(value);
+ }
+ else if (entry == "ta-dir")
+ {
+ _openvpnWidget->cboDirection->setCurrentItem(value);
+ }
+ else
+ {
+ kdDebug() << TQString("OpenVPN: Property '%1' not handled").arg(entry) << endl;
+ }
+ }
+
+ // set routes
+ if (!routes.empty())
+ {
+ _openvpnWidget->chkIPAdresses->setChecked(true);
+ TQStringList routesText;
+ for (TDENetworkSingleRouteConfigurationList::Iterator it = routes.begin(); it != routes.end(); ++it) {
+ routesText.append(TQString("%1/%2").arg((*it).ipAddress.toString()).arg((*it).networkMask.toCIDRMask()));
+ }
+ _openvpnWidget->routes->setText(routesText.join(" "));
+ }
+}
+
+TDENetworkSettingsMap OpenVPNConfig::getVPNProperties()
+{
+ // Build a list of properties
+ m_vpnProperties.insert("connection-type", TQString::number(OpenVPNConnectionType::mapConnectionType2String((OpenVPNConnectionType::CONNECTIONTYPE)_openvpnWidget->cboConnectionType->currentItem())));
+ m_vpnProperties.insert("remote", TQString(_openvpnWidget->gateway->text()));
+
+ // port is not necessary
+ if (!_openvpnWidget->port->text().isEmpty() && !_openvpnWidget->chkDefaultPort->isChecked()) {
+ m_vpnProperties.insert("port", _openvpnWidget->port->text());
+ }
+ else {
+ m_vpnProperties.remove("port");
+ }
+
+ m_vpnProperties.insert("ca", TQString(_openvpnWidget->editCA->url()));
+ m_vpnProperties.insert("cert",TQString(_openvpnWidget->editCert->url() ));
+ m_vpnProperties.insert("key", TQString(_openvpnWidget->editKey->url()));
+
+ if (_openvpnWidget->chkUseCipher->isChecked()) {
+ m_vpnProperties.insert("cipher", TQString(_openvpnWidget->cboCipher->currentText()));
+ }
+ else {
+ m_vpnProperties.remove("cipher");
+ }
+
+ if (_openvpnWidget->chkUseLZO->isChecked()) {
+ m_vpnProperties.insert("comp-lzo", TQString("true"));
+ }
+ else {
+ m_vpnProperties.insert("comp-lzo", TQString("false"));
+ }
+
+ m_vpnProperties.insert("static-key", TQString(_openvpnWidget->editSharedKey->url()));
+ m_vpnProperties.insert("username", TQString(_openvpnWidget->editUsername->text()));
+ m_vpnProperties.insert("local-ip", TQString(_openvpnWidget->editLocalIP->text()));
+ m_vpnProperties.insert("remote-ip", TQString(_openvpnWidget->editRemoteIP->text()));
+
+ if (_openvpnWidget->chkUseTAP->isChecked()) {
+ m_vpnProperties.insert("tap-dev", "true");
+ m_vpnProperties.insert("proto-tcp", "true");
+ }
+ else {
+ m_vpnProperties.insert("tap-dev", "false");
+ m_vpnProperties.insert("proto-tcp", "false");
+ }
+
+ if (_openvpnWidget->chkUseTLS->isChecked()) {
+ m_vpnProperties.insert("ta", TQString(_openvpnWidget->editTLSAuth->url()));
+ }
+ else {
+ m_vpnProperties.remove("ta");
+ }
+
+ m_vpnProperties.insert("ta-dir", TQString(_openvpnWidget->cboDirection->currentText()));
+
+ return m_vpnProperties;
+}
+
+TDENetworkSettingsMap OpenVPNConfig::getVPNSecrets() {
+ // Build a list of secrets
+ // FIXME
+
+ return m_vpnSecrets;
+}
+
+TDENetworkSingleRouteConfigurationList OpenVPNConfig::getVPNRoutes()
+{
+ TDENetworkSingleRouteConfigurationList ret;
+ TQStringList strlist;
+ if(_openvpnWidget->chkIPAdresses->isChecked()) {
+ strlist = TQStringList::split(" ", _openvpnWidget->routes->text());
+ }
+
+ for (TQStringList::Iterator it = strlist.begin(); it != strlist.end(); ++it) {
+ TQStringList pieces = TQStringList::split("/", (*it));
+ TDENetworkSingleRouteConfiguration routeconfig;
+ routeconfig.ipAddress.setAddress(pieces[0]);
+ if (pieces.count() > 1) {
+ routeconfig.networkMask.fromCIDRMask(pieces[1].toUInt());
+ }
+ ret.append(routeconfig);
+ }
+
+ return ret;
+}
+
+bool OpenVPNConfig::hasChanged()
+{
+ return true;
+}
+
+bool OpenVPNConfig::isValid(TQStringList& err_msg)
+{
+ bool retval = true;
+
+ // check gateway
+ if (_openvpnWidget->gateway->text().isEmpty())
+ {
+ err_msg.append(i18n("You have to specify a gateway"));
+ retval = false;
+ }
+
+ bool ok = false;
+ _openvpnWidget->port->text().toULong(&ok);
+ if (!ok && !_openvpnWidget->port->text().isEmpty() )
+ {
+ err_msg.append(i18n("The port number has to be numeric"));
+ retval = false;
+ }
+
+ switch(_openvpnWidget->cboConnectionType->currentItem())
+ {
+ case OpenVPNConnectionType::X509:
+ // check if ca file is correct
+ if (_openvpnWidget->editCA->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no CA file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editCA->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("CA file not valid"));
+ }
+
+ // check if cert file is correct
+ if (_openvpnWidget->editCert->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no CERT file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editCert->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("CERT file not valid"));
+ }
+
+ // check if key file is correct
+ if (_openvpnWidget->editKey->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no Key file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editKey->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("Key file not valid"));
+ }
+
+ break;
+
+
+ case OpenVPNConnectionType::SHARED_KEY:
+ // check if a shared key is selected
+ if (_openvpnWidget->editSharedKey->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("Please provide a valid shared key"));
+ }
+ // check if the shared key file exists
+ else if (!TQFileInfo(_openvpnWidget->editSharedKey->url()).exists())
+ {
+ retval = false;
+ err_msg.append(i18n("Please provide a valid shared key"));
+ }
+
+ // check if local ip is valid
+ if (!TQHostAddress().setAddress(_openvpnWidget->editLocalIP->text()))
+ {
+ retval = false;
+ err_msg.append(i18n("local IP is invalid"));
+ }
+ // check if remote ip is valid
+ if (!TQHostAddress().setAddress(_openvpnWidget->editRemoteIP->text()))
+ {
+ retval = false;
+ err_msg.append(i18n("remote IP is invalid"));
+ }
+
+ break;
+ case OpenVPNConnectionType::PASSWORD:
+ // check if username is suplied
+ if (_openvpnWidget->editUsername->text().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no username provided"));
+ }
+
+ // check if ca file is correct
+ if (_openvpnWidget->editCA->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no CA file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editCA->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("CA file not valid"));
+ }
+
+ break;
+
+
+ case OpenVPNConnectionType::X509USERPASS:
+ // check if username is suplied
+ if (_openvpnWidget->editUsername->text().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no username provided"));
+ }
+
+ // check if ca file is correct
+ if (_openvpnWidget->editCA->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no CA file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editCA->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("CA file not valid"));
+ }
+
+ // check if cert file is correct
+ if (_openvpnWidget->editCert->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no CERT file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editCert->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("CERT file not valid"));
+ }
+
+ // check if key file is correct
+ if (_openvpnWidget->editKey->url().isEmpty())
+ {
+ retval = false;
+ err_msg.append(i18n("no Key file provided"));
+ }
+ else if (!TQFileInfo(_openvpnWidget->editKey->url()).isFile())
+ {
+ retval = false;
+ err_msg.append(i18n("Key file not valid"));
+ }
+ break;
+ }
+
+
+ return retval;
+}
+
+/************************************
+* OpenVPNAuthentication
+************************************/
+
+OpenVPNAuthentication::OpenVPNAuthentication(TQWidget* parent, char* name)
+ : VPNAuthenticationWidget(parent, name)
+{
+ TQVBoxLayout* layout = new TQVBoxLayout(this, 1, 1);
+ _openvpnAuth = new OpenVPNAuthenticationWidget(this);
+ layout->addWidget(_openvpnAuth);
+}
+
+OpenVPNAuthentication::~OpenVPNAuthentication()
+{
+
+}
+
+void OpenVPNAuthentication::setVPNData(TDENetworkSingleRouteConfigurationList& /*routes*/, TDENetworkSettingsMap& properties, TDENetworkSettingsMap& secrets)
+{
+ // find the connection type property
+ for(TQMap<TQString, TQString>::ConstIterator it = properties.begin(); it != properties.end(); ++it)
+ {
+ if (it.key() == "connection-type")
+ {
+ _connectionType = OpenVPNConnectionType::mapString2ConnectionType(it.data().toInt());
+ break;
+ }
+ }
+}
+
+TDENetworkSettingsMap OpenVPNAuthentication::getPasswords()
+{
+ TQMap<TQString, TQString> pwds;
+ if ((_connectionType == OpenVPNConnectionType::PASSWORD) || (_connectionType == OpenVPNConnectionType::X509USERPASS))
+ pwds.insert("password", TQString(_openvpnAuth->editUserPassword->password()));
+ else
+ pwds.insert("no-secret", TQString("true"));
+
+ return pwds;
+}
+
+void OpenVPNAuthentication::setPasswords(TDENetworkSettingsMap secrets) {
+ if (secrets.contains("password")) {
+ _openvpnAuth->editUserPassword->erase();
+ _openvpnAuth->editUserPassword->insert(secrets["password"]);
+ }
+}
+
+bool OpenVPNAuthentication::needsUserInteraction()
+{
+ if ((_connectionType == OpenVPNConnectionType::PASSWORD) || (_connectionType == OpenVPNConnectionType::X509USERPASS))
+ return true;
+ return false;
+}
+
+#include "tdenetman-openvpn.moc" \ No newline at end of file