/*****************************************************************************
 * Copyright (C) 2010 S.R.Haque <srhaque@theiet.org>                         *
 * Christoph Thielecke <crissi99@gmx.de> (contains code from kvpnc.cpp)      *
 *                                                                           *
 * 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 package 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 package; if not, write to the Free Software               *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include <QtCore/QProcess>
#include <kmessagebox.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <unistd.h>
#include "openvpnmanagementhandler.h"
#include "OpenVpnHandler.h"
#include "enterpassworddialog.h"
#include "enterxauthinteractivepasscodedialog.h"
#include "kvpnc.h"
#include "kvpncconfig.h"
#include "utils.h"

OpenVpnHandler::OpenVpnHandler(
    KVpnc *ui,
    KVpncConfig *config):
        HandlerBase(ui, config, "OpenVPN", "openvpn", false),
        OpenvpnDevice(""),
        OpenvpnProcess(0),
        managementhandler(0),
        m_tool("openvpn", "2", ".|-|~")
{
    ToolInfo *info = Utils(GlobalConfig).getToolInfo(m_tool.name());
    if (!info->Version.isEmpty()) {
        // Typical version information:
        //
        // OpenVPN 2.1.0 x86_64-pc-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Jan 26 2010
        // Originally developed by James Yonan
        // Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
        //
        // To make the version comparisons easier to write, transform:
        //
        //  "rc"   -> "0.0.0"
        //  "beta" -> "0.1.0"
        //   append   ".0.9"
        //
        // Thus:
        //
        //  "2.1~rc7"  -> "2.1~0.0.07.0.9"
        //  "2.1~beta" -> "2.1~0.1.0.0.9"
        //  "2.1"      -> "2.1.0.9"
        //  "2.1.1"    -> "2.1.1.0.9"
        //
        // which then allows strictly numeric comparisons to work nicely.
        m_tool.setActualVersion(info->Version.replace("rc", "0.0.0", Qt::CaseInsensitive).replace("beta", "0.1.0", Qt::CaseInsensitive).append(".0.9"));
    }
}

bool OpenVpnHandler::vpnStart(bool authenticationRetry)
{
    // Everything step of our logic is guarded by the error state. The error
    // state starts as zero for no error, and is set to the line where any
    // problem is caught.
    unsigned errorLine = 0;

    if (!errorLine) {
        // looking for openvpn
        if (!Utils(GlobalConfig).getToolInfo(m_tool.name())->found) {
            reportError(i18n("Unable to find \"%1\" at \"%2\".", m_tool.name(), GlobalConfig->pathToOpenvpn));
            errorLine = __LINE__;
        } else {
            debugMessage(0, i18n("Found helper %1 at %2", m_tool.name(), GlobalConfig->pathToOpenvpn));
        }
    }

    if (!errorLine) {
        if (!m_tool.isGe()) {
            reportError(i18n("%1 version %2 is too old. Minimum requirement is %3.", m_tool.name(), m_tool.minimumVersion(), m_tool.actualVersion()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        QString OpenvpnSecrectPath = tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".secret";

        if (GlobalConfig->currentProfile->authtype == VpnAccountData::cert) {

            if (GlobalConfig->currentProfile->getUseSmartcard()) {
                /* use cert on smartcard */
                //      Utils(GlobalConfig).getSmartcardInfo();
                //      if ( GlobalConfig->pathToPkcs11Tool.isEmpty() || KStandardDirs::findExe( GlobalConfig->pathToPkcs11Tool.section( '/', -1, -1 ), GlobalConfig->pathTopathToPkcs11Tool.section( '/', 0, -2 ) ).isEmpty() )
                //      {
                //       KMessageBox::error( this, i18n( "Unable to find \"%1\" at \"%2\"!" , "pkcs11-tool" , GlobalConfig->pathToPkcs11Tool) );
                //       errorMessage( i18n( "Unable to find \"%1\" at \"%2\"!" , "pkcs11-tool" , GlobalConfig->pathToPkcs11Tool ) );
                //       ok = false;
                //       setGuiStatus( disconnected );
                //       return ;
                //      }

                if (GlobalConfig->currentProfile->getPkcs11Slot().isEmpty()) {
                    reportError(i18n("Pkcs11 slot cannot be empty."));
                    errorLine = __LINE__;
                }
                if (GlobalConfig->currentProfile->getPkcs11Id().isEmpty()) {
                    reportError(i18n("Pkcs11 id cannot be empty."));
                    errorLine = __LINE__;
                }
                if (GlobalConfig->currentProfile->getUsePkcs11Providers() && GlobalConfig->currentProfile->getPkcs11Providers().isEmpty()) {
                    reportError(i18n("Pkcs11 providers cannot be empty."));
                    errorLine = __LINE__;
                }
            } else {
                /* use cert on filesystem */
                QFile CertTmpFile;
                if (! GlobalConfig->currentProfile->getUseOnlyCaCertAndUserAuth()) {
                    CertTmpFile.setFileName(GlobalConfig->currentProfile->getX509Certificate());
                    if (!CertTmpFile.exists()) {
                        //     KMessageBox::error( 0, i18n( "Certificate file (%1) could not be found. Please check its path." , GlobalConfig->currentProfile->getX509Certificate() ), i18n( "File Not Found" ) );
                        //     errorMessage( i18n( "Certificate file (%1) could not be found. Please check its path." , GlobalConfig->currentProfile->getX509Certificate() ) );
                        //     ok = false;
                        //     setGuiStatus( disconnected );
                        //     return ;
                    } else {
                        CertTmpFile.setFileName(GlobalConfig->currentProfile->getPrivateKey());
                        if (!CertTmpFile.exists()) {
                            reportError(i18n("Private key file (%1) could not be found. Please check its path." , GlobalConfig->currentProfile->getPrivateKey()), i18n("File Not Found"));
                            errorLine = __LINE__;
                        }
                    }
                } // only if real certificate

                CertTmpFile.setFileName(GlobalConfig->currentProfile->getCaCertificate());
                if (!CertTmpFile.exists()) {
                    reportError(i18n("CA certificate file (%1) could not be found. Please check its path." , GlobalConfig->currentProfile->getCaCertificate()), i18n("File Not Found"));
                    errorLine = __LINE__;
                }
            }
        }
    }

    //    GlobalConfig->TmpGatewayIP = Utils( GlobalConfig, parent ).resolveName(GlobalConfig->currentProfile->getGateway());
    //    if (GlobalConfig->TmpGatewayIP=="0.0.0.0" || GlobalConfig->TmpGatewayIP.isEmpty())
    //    {
    //     KMessageBox::error( this, i18n( "Host \"%1\" could not be resolved." ,GlobalConfig->currentProfile->getGateway()) );
    //     logMessage(i18n( "Host \"%1\" could not be resolved." ,GlobalConfig->currentProfile->getGateway()),KVpncEnum::error);
    //     ok =false;
    //    }
    //    else
    //    {
    //      debugMessage(0,  i18n( "Gateway hostname (%1) resolved to \"%2\"." ,GlobalConfig->currentProfile->getGateway(),GlobalConfig->TmpGatewayIP) );
    //    }


    if (!errorLine) {
        if (!getAuthenticationData(authenticationRetry)) {
            errorMessage(i18n("Authentication data dialog cancelled."));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        if (!enableTunnelSupport()) {
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        if (GlobalConfig->currentProfile->getExecuteCmdBeforeConnect()) {
            executeCommandBeforeConnect();
        }
    }

    // here we go
    if (!errorLine) {
        QString tmpInterface;
        QString LocalIP;
        NetworkInterface iface(GlobalConfig, kapp);
        if (GlobalConfig->currentProfile->getNetworkDevice() == "default") {
            tmpInterface = iface.getDefaultInterface();
            debugMessage(0, i18n("Default interface: \"%1\"." , tmpInterface) );
            LocalIP = iface.getInterfaceIP(iface.getDefaultInterface());
            debugMessage(0, i18n("IP address of default interface: \"%1\"." , LocalIP) );
        } else {
            tmpInterface = GlobalConfig->currentProfile->getNetworkDevice();
            LocalIP = iface.getInterfaceIP(GlobalConfig->currentProfile->getNetworkDevice());
        }
        if (tmpInterface.isEmpty()) {
            debugMessage(0, i18n("No default interface found, using \"lo\".") );
            tmpInterface = "lo"; // no default interface found :(
        }

        if (LocalIP.isEmpty()) {
            debugMessage(0, i18n("No IP for default interface found, using \"127.0.0.1\"."));
            LocalIP = "127.0.0.1"; // no IP for default interface found :(
        }

        if (!backupDefaultRoute()) {
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        if (GlobalConfig->currentProfile->getTunnelDeviceType() == "tun")
            OpenvpnDevice = "tun0";
        else
            OpenvpnDevice = "tap0";

        //if (GlobalConfig->KvpncDebugLevel > 0)
        //  {
        //     logMessage( "debug: local virtual ip: "+GlobalConfig->currentProfile->getLocalVirtualIP(),KVpncEnum::debug );
        //     logMessage( "debug: remote virtual ip: "+GlobalConfig->currentProfile->getRemoteVirtualIP(),KVpncEnum::debug );
        // }
        // write openvpn.<profile>.conf
        QFile openvpn_file(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".conf");
        QTextStream openvpn_stream(&openvpn_file);
        if (openvpn_file.open(QIODevice::WriteOnly)) {
            openvpn_stream << "# generated by kvpnc. Do not edit it." << "\n";
            openvpn_stream << "# profile: " + GlobalConfig->currentProfile->getName() << "\n\n";
            openvpn_stream << "# verbosity" << "\n";
            openvpn_stream << "verb " << GlobalConfig->OpenvpnDebugLevel << "\n\n";

            QString certPath = "/etc/openvpn";
            if (!GlobalConfig->currentProfile->getCertPath().isEmpty())
                certPath = GlobalConfig->currentProfile->getCertPath();

            openvpn_stream << "# change to prefix" << "\n";
            openvpn_stream << "cd " << certPath << "\n\n";

            if (GlobalConfig->currentProfile->getTunnelDeviceType() == "tun") {
                openvpn_stream << "# use tun device" << "\n";
                openvpn_stream << "dev tun" << "\n\n";
            } else {
                openvpn_stream << "# use tap device" << "\n";
                openvpn_stream << "dev tap" << "\n\n";
            }

            if (GlobalConfig->currentProfile->getDisableBind()) {
                openvpn_stream << "# do not listen" << "\n";
                openvpn_stream << "nobind" << "\n\n";
            }

            // openvpn > 2.1-rc9 we need script security parameter (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=494998)
            debugMessage(4, i18n("OpenVPN version %1", m_tool.actualVersion()));
            if (GlobalConfig->OpenvpnNeedSecurityParameter || m_tool.actualIsGe("2.1-rc9")) {
                debugMessage(3, i18n("OpenVPN >= 2.1-rc9 detected, adding script security parameter to config."));

                openvpn_stream << "# script security: allow program exec" << "\n";
                openvpn_stream << "script-security 2" << "\n";
                openvpn_stream << "\n";
            }

            if (GlobalConfig->currentProfile->getDisableLzoCompression() == false) {
                openvpn_stream << "# compression" << "\n";
                openvpn_stream << "comp-lzo" << "\n\n";
            }
            openvpn_stream << "" << "\n";

            openvpn_stream << "# try to resolve names infinite" << "\n";
            openvpn_stream << "resolv-retry infinite" << "\n\n";

            openvpn_stream << "" << "\n";
            if (GlobalConfig->currentProfile->getAuthType() ==  VpnAccountData::cert) {
                openvpn_stream << "" << "\n";
                openvpn_stream << "# ca" << "\n";
                openvpn_stream << "ca " << GlobalConfig->currentProfile->getCaCertificate() << "\n\n";
                if (GlobalConfig->currentProfile->getUseSmartcard()) {
                    /* use cert on smartcard */
                    openvpn_stream << "# use smartcard" << "\n";
                    openvpn_stream << "pkcs11-providers \"" << GlobalConfig->currentProfile->getPkcs11Providers() << "\"\n";
                    openvpn_stream << "pkcs11-id \"" << GlobalConfig->currentProfile->getPkcs11Id() << "\"\n";
                    if (!m_tool.actualIsGe("2.1-rc10")) {
                        debugMessage(3, i18n("OpenVPN =< 2.1-rc9 detected, adding additional pkcs11 parameters."));

                        openvpn_stream << "pkcs11-slot-type \"" << GlobalConfig->currentProfile->getPkcs11SlotType() << "\"\n";
                        // we have to split slot id and name ("0 : foobar") => 0
                        QString Pkcs11Slot = GlobalConfig->currentProfile->getPkcs11Slot().section(':', 0, 0).trimmed();
                        openvpn_stream << "pkcs11-slot \"" << Pkcs11Slot << "\"\n";

                        openvpn_stream << "pkcs11-id-type \"" << GlobalConfig->currentProfile->getPkcs11IdType() << "\"\n";
                        openvpn_stream << "pkcs11-sign-mode \"" << GlobalConfig->currentProfile->getPkcs11SignMode() << "\"\n";
                    }
                    openvpn_stream << "\n";
                } else {
                    /* use cert on filesystem */
                    QFile CertTmpFile;
                    if (!GlobalConfig->currentProfile->getUseOnlyCaCertAndUserAuth()) {
                        CertTmpFile.setFileName(GlobalConfig->currentProfile->getX509Certificate());
                        if (CertTmpFile.exists()) {
                            openvpn_stream << "# client cert" << "\n";
                            openvpn_stream << "cert " << GlobalConfig->currentProfile->getX509Certificate() << "\n\n";
                            openvpn_stream << "" << "\n";

                            QFile PrivateKeyTmpFile(GlobalConfig->currentProfile->getPrivateKey());
                            //          if ( PrivateKeyTmpFile.exists() )
                            {
                                openvpn_stream << "# client private key" << "\n";
                                openvpn_stream << "key \"" << GlobalConfig->currentProfile->getPrivateKey() << "\"\n\n";

                            }
                        }
                    } // if real cert
                }

                openvpn_stream << "# client side" << "\n";
                openvpn_stream << "tls-client" << "\n";
                openvpn_stream << "pull" << "\n\n";

                openvpn_stream << "# diffie hellman parameters" << "\n";
                openvpn_stream << "dh dh1024.pem" << "\n\n";

            } else if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::AuthenticationType(VpnAccountData::psk)) {
                openvpn_stream << "# client psk" << "\n";
                if (GlobalConfig->currentProfile->getPskIsInFile()) {
                    QString direction = "";
                    if (GlobalConfig->currentProfile->getAuthenticationDirection() != "none")
                        direction = GlobalConfig->currentProfile->getAuthenticationDirection();
                    openvpn_stream << "secret " << GlobalConfig->currentProfile->getPreSharedKeyFile() << " " << direction << "\n\n";
                } else {
                    // write openvpn.<profile>.secret
                    QFile openvpn_secretfile(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".secret");
                    QTextStream openvpn_secretstream(&openvpn_secretfile);
                    if (openvpn_secretfile.open(QIODevice::WriteOnly)) {
                        openvpn_secretstream << "# generated by kvpnc. Do not edit it." << "\n";
                        openvpn_secretstream << "# profile: " + GlobalConfig->currentProfile->getName() << "\n\n";
                        openvpn_secretstream << GlobalConfig->currentProfile->getPreSharedKey() << "\n\n";
                    }
                    openvpn_secretfile.close();
                    QString direction = "";
                    if (GlobalConfig->currentProfile->getAuthenticationDirection() != "none")
                        direction = GlobalConfig->currentProfile->getAuthenticationDirection();
                    openvpn_stream << "secret " << tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".secret " << direction << "\n\n";
                }
            }

            if (GlobalConfig->currentProfile->getUseUdp()) {
                openvpn_stream << "\n";
                openvpn_stream << "# use udp" << "\n";
                openvpn_stream << "proto udp" << "\n\n";


                if (GlobalConfig->currentProfile->getUseMssfix()) {
                    openvpn_stream << "\n";
                    openvpn_stream << "# userdefined packet size" << "\n";
                    openvpn_stream << "mssfix " << GlobalConfig->currentProfile->getMssfix() << "\n\n";
                }

            } else {
                openvpn_stream << "" << "\n";
                openvpn_stream << "# use tcp" << "\n";
                openvpn_stream << "proto tcp-client" << "\n\n";
            }

            openvpn_stream << "" << "\n";
            openvpn_stream << "# remote side" << "\n";
            openvpn_stream << "remote " << GlobalConfig->currentProfile->getGateway();
            //      openvpn_stream << "remote " << GlobalConfig->TmpGatewayIP;;
            if (GlobalConfig->currentProfile->getUseRemotePort())
                openvpn_stream << " " << GlobalConfig->currentProfile->getRemotePort();
            openvpn_stream << "\n\n";

            if (GlobalConfig->currentProfile->getUseVirtualIP()) {
                openvpn_stream << "" << "\n";
                openvpn_stream << "# virtual ip addresses" << "\n";
                openvpn_stream << "ifconfig " << GlobalConfig->currentProfile->getLocalVirtualIP() << " " << GlobalConfig->currentProfile->getRemoteVirtualIP() << "\n\n";


                //       QString RemoteNetAddr = GlobalConfig->currentProfile->getRemoteNetAddr();
                //       int RemoteNetMaskNum = GlobalConfig->currentProfile->getRemoteNetMask().toInt();
                //       QString RemoteNetMask = "255.255.255.0";
                //       if ( RemoteNetMaskNum == 24 )
                //        RemoteNetMask = "255.255.255.0";
                //       else if ( RemoteNetMaskNum == 25 )
                //        RemoteNetMask = "255.255.255.128";
                //       else if ( RemoteNetMaskNum == 26 )
                //        RemoteNetMask = "255.255.255.192";
                //       else if ( RemoteNetMaskNum == 27 )
                //        RemoteNetMask = "255.255.255.224";
                //       else if ( RemoteNetMaskNum == 28 )
                //        RemoteNetMask = "255.255.255.240";
                //       else if ( RemoteNetMaskNum == 29 )
                //        RemoteNetMask = "255.255.255.248";
                //       else if ( RemoteNetMaskNum == 30 )
                //        RemoteNetMask = "255.255.255.252";
                //       else if ( RemoteNetMaskNum == 31 )
                //        RemoteNetMask = "255.255.255.254";
                //       else if ( RemoteNetMaskNum == 32 )
                //        RemoteNetMask = "255.255.255.255";
                //
                //       openvpn_stream << "" << "\n";
                //       openvpn_stream << "# route to remote network" << "\n";
                //       openvpn_stream << "route " << RemoteNetAddr << " " << RemoteNetMask << "\n";
            }
            //openvpn_stream << "" << "\n";
            //openvpn_stream << "# permissions" << "\n";
            //      openvpn_stream << "user nobody" << "\n";
            //      openvpn_stream << "group nogroup" << "\n";

            openvpn_stream << "" << "\n";
            openvpn_stream << "# port" << "\n";
            if (GlobalConfig->currentProfile->getUseUserdefinedPort())
                openvpn_stream << "port " << GlobalConfig->currentProfile->getUserdefinedPort() << "\n\n";
            else
                openvpn_stream << "port 1194" << "\n";

            if (GlobalConfig->currentProfile->getUseMtu()) {
                openvpn_stream << "# tunnel mtu size" << "\n";
                openvpn_stream << "tun-mtu " << GlobalConfig->currentProfile->getMtu();
            }

            if (GlobalConfig->currentProfile->getUseRenegSec()) {
                openvpn_stream << "# reneg-sec size" << "\n";
                openvpn_stream << "reneg-sec " << GlobalConfig->currentProfile->getRenegSec() << "\n";
            }

            if (GlobalConfig->currentProfile->getUseTunnelPing()) {
                openvpn_stream << "# ping through tunnel" << "\n";
                openvpn_stream << "ping " << GlobalConfig->currentProfile->getTunnelPing() << "\n";
            }

            if (GlobalConfig->currentProfile->getUseTunnelPingRestart()) {
                openvpn_stream << "# restart after tunnel ping failed" << "\n";
                openvpn_stream << "ping-restart " << GlobalConfig->currentProfile->getTunnelPingRestart();
            }


            if (GlobalConfig->currentProfile->getUseFragment()) {
                openvpn_stream << "\n";
                openvpn_stream << "# userdefined packet size for fragmentation" << "\n";
                openvpn_stream << "fragment " << GlobalConfig->currentProfile->getFragment() << "\n\n";
            }

            openvpn_stream << "" << "\n";
            openvpn_stream << "# don't re-read key files across SIGUSR1 or --ping-restart" << "\n";
            openvpn_stream << "persist-key" << "\n\n";

            openvpn_stream << "" << "\n";
            openvpn_stream << "# don't close and reopen TUN/TAP device across SIGUSR1 or --ping-restart restarts" << "\n";
            openvpn_stream << "persist-tun" << "\n\n";

            if (GlobalConfig->currentProfile->getUseNsCertType()) {
                openvpn_stream << "" << "\n";
                if (GlobalConfig->currentProfile->getNsCertType() == "client") {
                    openvpn_stream << "# Require that peer certificate was signed with an explicit nsCertType designation of \"client\"" << "\n";
                    openvpn_stream << "ns-cert-type client" << "\n\n";
                } else {
                    openvpn_stream << "# Require that peer certificate was signed with an explicit nsCertType designation of \"server\"" << "\n";
                    openvpn_stream << "ns-cert-type server" << "\n\n";
                }
            }

            openvpn_stream << "# disable ping restart\n";
            openvpn_stream << "ping-restart 0\n";
            openvpn_stream << "\n";



            //      openvpn_stream << "# keep the connection alive" << "\n";

            //      // TODO make it dynamiclly
            //      openvpn_stream << "keepalive 10 60" << "\n\n";

            //       openvpn_stream << "# keepalive\n";
            // //       openvpn_stream << "keepalive 10000\n";

            if (GlobalConfig->currentProfile->getUseUserdefiniedCipher()) {
                openvpn_stream << "# Use a userdefined cipher\n";
                openvpn_stream << "cipher " << GlobalConfig->currentProfile->getUserdefiniedCipher() << "\n\n";
            }

            if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                openvpn_stream << "# Automatically execute routing commands to cause all outgoing IP traffic to be redirected over the VPN\n";
                openvpn_stream << "redirect-gateway\n\n";
            }

            if (GlobalConfig->currentProfile->getUseTlsAuth() && !GlobalConfig->currentProfile->getTlsAuthFile().isEmpty()) {
                openvpn_stream << "# Add an additional layer of HMAC authentication on top of the TLS control channel to protect against DoS attacks\n";
                QString direction = "";
                if (GlobalConfig->currentProfile->getAuthenticationDirection() != "none")
                    direction = GlobalConfig->currentProfile->getAuthenticationDirection();
                openvpn_stream << "tls-auth " << GlobalConfig->currentProfile->getTlsAuthFile() << " "  << direction << "\n\n";

                if (GlobalConfig->currentProfile->getUseTlsRemoteHost()) {
                    openvpn_stream << "# Accept connections only from a host with X509 name or common name equal to host\n";
                    openvpn_stream << "tls-remote " << GlobalConfig->currentProfile->getTlsRemoteHost() << "\n\n";
                }

                //       if ( GlobalConfig->currentProfile->getUseTlsRemoteHost() && GlobalConfig->currentProfile->getUseTlsAuth() )
                //        openvpn_stream << "tls-client" << "\n\n";


            }

            if (GlobalConfig->currentProfile->getUseHttpProxy()) {
                openvpn_stream << "# Use a HTTP proxy\n";
                QString HttpProxyAuthType = "";

                if (GlobalConfig->currentProfile->getUseHttpProxyAuth())
                    HttpProxyAuthType = GlobalConfig->currentProfile->getHttpProxyAuthType();
                else
                    HttpProxyAuthType = "none";

                openvpn_stream << "http-proxy " << GlobalConfig->currentProfile->getHttpProxy() << " " << GlobalConfig->currentProfile->getHttpProxyPort() << " " << "auto" << " " << HttpProxyAuthType << "\n";

                openvpn_stream << "http-proxy-timeout " << GlobalConfig->currentProfile->getHttpProxyTimeout() << "\n\n";
            }

            openvpn_stream << "up " << tmpPath << "openvpn." << GlobalConfig->currentProfile->getName() << ".up" << "\n";
            openvpn_stream << "down " << tmpPath + "openvpn." << GlobalConfig->currentProfile->getName() << ".down" << "\n";
            //      openvpn_stream << "up-restart" << "\n";
            openvpn_stream << "\n";

            openvpn_stream << "# Use management interface\n";
            openvpn_stream << "management 127.0.0.1 " << GlobalConfig->OpenvpnManagementPort << "\n";
            openvpn_stream << "management-query-passwords" << "\n";
            openvpn_stream << "\n";
            if (GlobalConfig->currentProfile->getUseSmartcard() || GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {

                //       debugMessage( "use auth with pass: " );
                //       openvpn_stream << "management-hold\n";
                //       openvpn_stream << "management-query-passwords\n";

                openvpn_stream << "# What happen if auth fails\n";
                // TODO made option for other types
                openvpn_stream << "auth-retry none\n\n";

                // FIXME: can user auth only used in cert mode?
                if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                    openvpn_stream << "# we want to authenticate with username and password\n";
                    openvpn_stream << "auth-user-pass" << "\n";
                    //        openvpn_stream << "auth-user-pass " << OpenvpnSecrectPath << "\n\n";

                    if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk)
                        openvpn_stream << "pull" << "\n\n";
                }

            }
            if (GlobalConfig->currentProfile->getUseAuthenticationAlgorithm())
                openvpn_stream << "auth " << GlobalConfig->currentProfile->getAuthenticationAlgorithm() << "\n";

            if (GlobalConfig->currentProfile->getAllowIpAddressChangeOfPeer())
                openvpn_stream << "float" << "\n";
            openvpn_file.close();
        } else {
            errorMessage(i18n("Creating %1 has been failed.", openvpn_file.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        // write openvpn.<profile>.up
        QFile upfile(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".up");
        QTextStream upstream(&upfile);
        if (upfile.open(QIODevice::WriteOnly)) {
            upstream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            upstream << "# generated by kvpnc. Do not edit it." << "\n";
            upstream << "# profile: " + GlobalConfig->currentProfile->getName() << "\n\n";
            /* uses parts of http://www.smop.co.uk/node/69 */
            //      upstream << "if [ -f /sbin/resolvconf ]; then\n";
            //          if [ -x /sbin/resolvconf ] ; then
            //         (
            //         if [ "$CISCO_DEF_DOMAIN" ] ; then
            //             echo domain "$CISCO_DEF_DOMAIN"
            //             echo search "$CISCO_DEF_DOMAIN"
            //         fi
            //         for ip in "$INTERNAL_IP4_DNS" ; do
            //             echo nameserver $ip
            //         done
            //         ) | /sbin/resolvconf -a $TUNDEV
            //         return
            //     fi
            //      upstream << "else\n";
            upstream << "cat /etc/resolv.conf > " << tmpPath + "resolv.conf." + GlobalConfig->currentProfile->getName() << "\n";
            /* update dns? */
            if (GlobalConfig->currentProfile->getUseDnsUpdate()) {
                upstream << "echo \"# generated by kvpnc. Do not edit it.\" > /etc/resolv.conf" << "\n";
                upstream << "echo \"# profile: " + GlobalConfig->currentProfile->getName() << "\" >> /etc/resolv.conf" << "\n";

                upstream << "# init variables" << "\n";
                upstream << "" << "\n";
                upstream << "i=1" << "\n";
                upstream << "j=1" << "\n";
                upstream << "unset fopt" << "\n";
                upstream << "unset dns" << "\n";
                upstream << "unset opt" << "\n";
                upstream << "" << "\n";
                upstream << "dns_found=0" << "\n";
                upstream << "domain_found=0" << "\n";
                upstream << "" << "\n";
                upstream << "# Convert ENVs to an array" << "\n";
                upstream << "" << "\n";
                //      upstream << "export > /tmp/a.txt" << "\n";
                //      upstream << "echo \"-------\" >> /tmp/a.txt" << "\n";
                //      upstream << "set >> /tmp/a.txt" << "\n";
                //      upstream << "echo $foreign_option_0 > /tmp/a.txt" << "\n";
                //      upstream << "echo $foreign_option_1 >> /tmp/a.txt" << "\n";
                //      upstream << "echo $foreign_option_2 >> /tmp/a.txt" << "\n";
                //      upstream << "echo $foreign_option_3 >> /tmp/a.txt" << "\n";

                upstream << "while fopt=\"foreign_option_$i\"; [ -n \"${!fopt}\" ]; do" << "\n";
                upstream << "{" << "\n";
                upstream << " opt[i-1]=${!fopt}" << "\n";
                upstream << " case ${opt[i-1]} in" << "\n";
                upstream << "  *DOMAIN* ) domain=`echo ${opt[i-1]} | \\" << "\n";
                upstream << "    sed -e 's/dhcp-option DOMAIN //g'` ;;" << "\n";
                upstream << "  *DNS*    ) dns[j-1]=`echo ${opt[i-1]} | \\" << "\n";
                upstream << "    sed -e 's/dhcp-option DNS //g'`" << "\n";
                upstream << "          let j++ ;;" << "\n";
                upstream << " esac" << "\n";
                upstream << " let i++" << "\n";
                upstream << "}" << "\n";
                upstream << "done" << "\n";
                upstream << "" << "\n";
                upstream << "# Now, do the work" << "\n";
                upstream << "" << "\n";
                upstream << "dns_found=0" << "\n";
                upstream << "if [ -n \"${dns[*]}\" ]; then" << "\n";
                upstream << "if [ -x /sbin/resolvconf ] ; then\n";
                upstream << "  echo > " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "       echo \"# nameservers\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  nameserver_found=0" << "\n";
                upstream << "  for i in \"${dns[@]}\"; do" << "\n";
                upstream << "   echo \"nameserver ${i}\" >> " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "   nameserver_found=1" << "\n";
                upstream << "   dns_found=1" << "\n";
                upstream << "  done" << "\n";
                upstream << "  if [ \"$nameserver_found\" = \"0\" ]; then" << "\n";
                upstream << "   echo \"# old nameserver\" >> " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "   cat   " + tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() + " | grep nameserver >> " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  fi" << "\n";
                upstream << "else" << "\n";
                upstream << "  nameserver_found=0" << "\n";
                upstream << "  for i in \"${dns[@]}\"; do" << "\n";
                upstream << "   nameserver_found=1" << "\n";
                upstream << "   sed -i -e \"1,1 i nameserver ${i}\" /etc/resolv.conf || die" << "\n";
                upstream << "  done" << "\n";
                upstream << "  if [ \"$nameserver_found\" = \"0\" ]; then" << "\n";
                upstream << "    echo \"# old nameserver\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "    cat   "+tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() +" | grep nameserver >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  fi" << "\n";
                upstream << "fi" << "\n";
                upstream << "fi" << "\n";
                upstream << "" << "\n";
                upstream << "echo \"# domains\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "if [ -n \"${domain}\" ]; then" << "\n";
                upstream << "if [ -x /sbin/resolvconf ] ; then\n";
                upstream << "  echo domain \"${domain}\n\" >> " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "else" << "\n";
                upstream << " sed -i -e \"$j,1 i search ${domain}\" /etc/resolv.conf || die" << "\n";
                upstream << "fi" << "\n";
                upstream << "domain_found=1" << "\n";
                upstream << "fi" << "\n";
                upstream << "if [ \"$dns_found\" = \"0\" ]; then" << "\n";
                upstream << "if [ -x /sbin/resolvconf ] ; then\n";
                upstream << "  echo \"# old nameserver\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  cat "+tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() +" |  grep  nameserver >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "else" << "\n";
                upstream << "  echo \"# old nameserver\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  cat "+tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() +" |  grep  nameserver >> /etc/resolv.conf" <<"\n";
                upstream << "fi" << "\n";
                upstream << "fi" << "\n";
                upstream << "if [ \"$domain_found\" = \"0\" ]; then" << "\n";
                upstream << "if [ -x /sbin/resolvconf ] ; then\n";
                upstream << "  echo > /dev/null\n";
                upstream << "  echo \"# old domain\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "  cat "+tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() +" |  grep  domain >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "else" << "\n";
                upstream << "   echo \"# old domain\" >> "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "   cat "+tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() +" |  grep  domain >> /etc/resolv.conf" <<"\n";
                upstream << "fi" << "\n";
                upstream << "fi" << "\n";

                upstream << "if [ -x /sbin/resolvconf ] ; then\n";
                upstream << "  cat   " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << " | /sbin/resolvconf -a $dev\n";

                /* crissi: -u seems not nessary */
                //upstream << "  cat   " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << " | /sbin/resolvconf -u\n";


                //      upstream << "  cat "+tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << " > /tmp/resolv "<< "\n";

                //      upstream << "echo \"dev: ${dev}\" > /tmp/resolvup.txt" << "\n";
                //      upstream << "cat   "+tmpPath + "/openvpn.resolvconf.tmp >> "+tmpPath + "+resolvconf." + GlobalConfig->currentProfile->getName()+ "\n";
                if (!GlobalConfig->holdGeneratedScripts)
                    upstream << "  rm -f   " + tmpPath + "/openvpn.resolvconf.tmp." + GlobalConfig->currentProfile->getName() << "\n";
                upstream << "fi" << "\n";

                //      upstream << "if [ -f " << tmpPath + "resolv.conf." + GlobalConfig->currentProfile->getName() << " ]; then" << "\n";
                //      upstream << " cat  " << tmpPath + "resolv.conf." + GlobalConfig->currentProfile->getName() << " | grep nameserver >> /etc/resolv.conf" << "\n";
                //      upstream << " cat  " << tmpPath + "resolv.conf." + GlobalConfig->currentProfile->getName() << " | grep domain >> /etc/resolv.conf" << "\n";
                //      upstream << "fi" << "\n";
                upstream << "" << "\n";

                //                         upstream << "chmod u-w  /etc/resolv.conf\n";
            } else {
                /* dont update dns */
                setenv("DNS_UPDATE", "NO", 1);
            }
            upstream << "exit 0\n";
            upfile.close();
        } else {
            errorMessage(i18n("Creating %1 has been failed.", upfile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        Utils(GlobalConfig, this).doChmod(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".up", "a+x");

        // write openvpn.<profile>.down
        QFile downfile(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".down");
        QTextStream downstream(&downfile);
        if (downfile.open(QIODevice::WriteOnly)) {
            downstream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            downstream << "# generated by kvpnc. Do not edit it." << "\n";
            downstream << "# profile: " + GlobalConfig->currentProfile->getName() << "\n\n";

            /* update dns? */
            if (GlobalConfig->currentProfile->getUseDnsUpdate()) {
                //                         downstream << "chmod u+w  /etc/resolv.conf\n";
                downstream << "if [ -x /sbin/resolvconf ] ; then\n";
                downstream << " dev=$1\n";
                downstream << " if [ -z $dev ] ; then\n";
                if (GlobalConfig->currentProfile->getTunnelDeviceType() == "tun")
                    downstream << "  dev=\"tun0\"\n";
                else
                    downstream << "  dev=\"tap0\"\n";
                downstream << " fi\n";
                downstream << " /sbin/resolvconf -d $dev\n";
                downstream << "else" << "\n";
                downstream << " cat " << tmpPath + "resolv.conf." + GlobalConfig->currentProfile->getName() << " > /etc/resolv.conf\n";
                downstream << "fi" << "\n";
            } else {
                /* dont update dns */
            }
            QString OldDefaultroute = tmpPath + "default-route." + GlobalConfig->currentProfile->getName(); // default-route.<id>
            if (! pppdHasReplacedefaultrouteSupport && GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                downstream << GlobalConfig->pathToIp << " route add  $(cat " << OldDefaultroute << ")" << "\n";
            }
            if (! pppdHasReplacedefaultrouteSupport && GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                downstream << GlobalConfig->pathToIp << " route add  $(cat " << OldDefaultroute << ")" << "\n";
            }


            downstream << "exit 0";
            downfile.close();
        } else {
            errorMessage(i18n("Creating %1 has been failed.", downfile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        Utils(GlobalConfig, this).doChmod(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".down", "a+x");
        Utils(GlobalConfig, this).doChmod(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".down", "a+x");

        QStringList args;

        args.append("--writepid");
        args.append(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".pid");
        args.append("--config");
        args.append(tmpPath + "openvpn." + GlobalConfig->currentProfile->getName() + ".conf");    // default

        setenv("DNS_UPDATE", (GlobalConfig->currentProfile->getUseDnsUpdate() ? "Yes" : "NO"), 1);

        debugMessage(0, i18n("Setting DNS_UPDATE \"%1\"." , QString(qgetenv("DNS_UPDATE"))));

        OpenvpnProcess = new HelperProcess(this, GlobalConfig->pathToOpenvpn, args, *env,
                                           SLOT(helperOutputReader()),
                                           0,
                                           0, 0);
        if (!OpenvpnProcess || !OpenvpnProcess->start()) {
            reportError(i18n("Failed to start \"%1\"." , QString("openvpn")), QString(), KVpncEnum::info);
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        //      if (OpenvpnVersionOk && ( GlobalConfig->currentProfile->getUseSmartcard() || GlobalConfig->currentProfile->getAuthWithUsernameAndPassword() )  )
        //      {
        debugMessage(0, i18n("Starting Openvpn management handler..."));
        managementhandler = new OpenvpnManagementHandler(this, GlobalConfig);
        connect(managementhandler, SIGNAL(terminate_openvpn()), this, SLOT(disconnectClicked()));
        if (managementhandler->doConnect() ) {

            //      int maxfailManagementHandlerConnectCheckCount=10; // 10 sec should be enough for connecting to 127.0.0.1
            //      int failManagementHandlerConnectCheckCount=0;
            //      while (!managementhandler->isConnectedToManagementPort() && failManagementHandlerConnectCheckCount < maxfailManagementHandlerConnectCheckCount)
            //      {
            //       sleep(1);
            //       GlobalConfig->appPointer->processEvents();
            //       failManagementHandlerConnectCheckCount++;
            //       if (managementhandler->isConnectedToManagementPort())
            //       {
            //        if (! GlobalConfig->KvpncDebugLevel > 1 )
            //         debugMessage( i18n( "Connect to %1 management handler was successful" ,QString("openvpn"))  );
            //        break;
            //       }
            //       if (! GlobalConfig->KvpncDebugLevel > 1 )
            //        debugMessage( i18n( "Trying to connect to %1 management handler..." ,QString("openvpn"))  );
            //      }
            //      //        managementhandler->sendToServer("help");
            //      //      }
            //      if (failManagementHandlerConnectCheckCount  >= maxfailManagementHandlerConnectCheckCount)
            //      {
            // //      KMessageBox::sorry( this, i18n( "Could not connect to %1 management handler!" ,QString("openvpn")) );
            //       errorMessage( i18n( "Could not connect to %1 management handler!" ,QString("openvpn"))  );
            //       if (OpenvpnProcess != 0)
            //        OpenvpnProcess->kill();
            //       setStatusDisconnected(__LINE__);
            //       return;
            //      }

            //     sleep(5);

            debugMessage(0, i18n("\"%1\" started." , QString("openvpn")));
        }
        else {
            errorMessage ( i18n ( "\"%1\" start failed.", QString("openvpn managementhandler") ));
            errorLine = __LINE__;
        }
    } // openvpn

    if (!errorLine) {
        debugMessage(0, i18n("Trying to connect to server \"%1\" with ...\n" , GlobalConfig->currentProfile->getGateway()) );
    } else {
        errorMessage(i18n("Error at line %1.", errorLine));
    }
    return 0 == errorLine;
}

void OpenVpnHandler::vpnStop()
{
    if ( managementhandler )
    {
        managementhandler->greetingtimer->stop();
        managementhandler->closeConnection();
        while ( ! managementhandler->socketReallyClosed )
        {
            if (GlobalConfig->appPointer->hasPendingEvents())
                GlobalConfig->appPointer->processEvents();
            usleep(500);
        }
        delete managementhandler;
        managementhandler = 0L;
    }
    if (OpenvpnProcess) {
        delete OpenvpnProcess;
        OpenvpnProcess = 0;
    }
}

bool OpenVpnHandler::getAuthenticationData(bool AuthRetry)
{
    bool askUsernamePass = false;
    bool requestUsername = false;
    bool requestGrouppassword = false;
    bool needSave = false;

    if (!GlobalConfig->haveUserData) {
        if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
            if ( GlobalConfig->currentProfile->getSaveUserPassword() && GlobalConfig->currentProfile->getUserPassword().isEmpty()) {
                askUsernamePass = true;
                debugMessage(3,  i18n ( "Empty user password" ) );
            }
            if ( !GlobalConfig->currentProfile->getSaveUserPassword() && GlobalConfig->TmpPassword.isEmpty()) {
                askUsernamePass = true;
                debugMessage(3,  i18n ( "Empty tmp user password" ) );
            }

            if ( !GlobalConfig->currentProfile->getDontSaveUsername() ) {
                requestUsername = GlobalConfig->currentProfile->getUserName().isEmpty();
            } else {
                requestUsername = GlobalConfig->TmpUsername.isEmpty();
            }



            if (AuthRetry) {
                askUsernamePass = true;
                requestUsername = true;
            }
        }
        if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk) {
            if (!GlobalConfig->currentProfile->getPskIsInFile() && GlobalConfig->currentProfile->getPreSharedKey().isEmpty())
                askUsernamePass = true;
            debugMessage(3,  i18n ( "Psk is empty" ) );

        }
    }

    if (AuthRetry) {
        askUsernamePass = true;
        requestUsername = true;
    }

    if (GlobalConfig->currentProfile->getAskUserPasswordOnEachConnect()) {
        debugMessage(4, i18n("User password on each connect forced."));

        askUsernamePass = true;
        requestUsername = true;
    }

    if (askUsernamePass) {

        if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk && !GlobalConfig->currentProfile->getPskIsInFile() && GlobalConfig->currentProfile->getPreSharedKey().isEmpty())
            requestGrouppassword = true;

        EnterUsernamePasswordDialog dlg(gui, i18n("Enter Account Data"), requestGrouppassword, requestUsername);
        dlg.SaveUsernameCheckBox->setChecked(!GlobalConfig->currentProfile->getDontSaveUsername());
        dlg.SavePasswordCheckBox->setChecked(GlobalConfig->currentProfile->getSaveUserPassword());

        if ((GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk && !GlobalConfig->currentProfile->getPskIsInFile() && GlobalConfig->currentProfile->getPreSharedKey().isEmpty()) && !GlobalConfig->currentProfile->getUseTlsAuth()) {
            dlg.UsernameEdit->hide();
            dlg.PasswordEdit->hide();

            if (dlg.exec()) {
                GlobalConfig->TmpGroupPassword = dlg.PSKLineEdit->text();

                if (GlobalConfig->TmpGroupPassword.isEmpty()) {
                    errorMessage(i18n("PSK is empty"));
                    return false;
                }

                if (dlg.SavePskCheckBox->isChecked() && requestGrouppassword) {
                    GlobalConfig->currentProfile->setSavePsk(true);
                    GlobalConfig->currentProfile->setPreSharedKey(GlobalConfig->TmpGroupPassword);
                    needSave = true;
                } else {
                    GlobalConfig->currentProfile->setSavePsk(false);
                    needSave = true;
                }

            } else {
                AuthRetry = false;
                debugMessage(0, i18n("Connect canceled because password enter dialog aborted."));
                return false;
            }
        } else {
            if (GlobalConfig->currentProfile->getSaveUserPassword())
                dlg.PasswordEdit->setText(GlobalConfig->currentProfile->getUserPassword());

            dlg.UsernameEdit->setText(GlobalConfig->currentProfile->getUserName());
            if (!dlg.UsernameEdit->text().isEmpty())                  //go straight to pw if username present
                dlg.PasswordEdit->setFocus();

            if (dlg.exec()) {
                GlobalConfig->TmpUsername = dlg.UsernameEdit->text();
                GlobalConfig->TmpPassword = dlg.PasswordEdit->text();


                if (GlobalConfig->TmpPassword.isEmpty()) {
                    errorMessage(i18n("Password is empty"));
                    return false;
                }

                if (requestUsername && GlobalConfig->TmpUsername.isEmpty()) {
                    errorMessage(i18n("Username is empty."));
                    return false;
                }

                if (dlg.SaveUsernameCheckBox->isChecked() && requestUsername) {
                    GlobalConfig->currentProfile->setDontSaveUsername(false);
                    GlobalConfig->currentProfile->setUserName(dlg.UsernameEdit->text());
                    needSave = true;
                }
                if ( dlg.SaveUsernameCheckBox->isChecked()) {
                    GlobalConfig->TmpUsername = dlg.UsernameEdit->text();
                    GlobalConfig->currentProfile->setDontSaveUsername(false);
                    needSave = true;
                }


                if (dlg.SavePskCheckBox->isChecked() && requestGrouppassword) {
                    GlobalConfig->currentProfile->setSavePsk(true);
                    GlobalConfig->currentProfile->setPreSharedKey(GlobalConfig->TmpGroupPassword);
                    needSave = true;
                } else {
                    GlobalConfig->currentProfile->setSavePsk(false);
                    needSave = true;
                }

                if (dlg.SavePasswordCheckBox->isChecked()) {
                    GlobalConfig->currentProfile->setSaveUserPassword(true);
                    GlobalConfig->currentProfile->setUserPassword(GlobalConfig->TmpPassword);
                    needSave = true;
                } else {
                    GlobalConfig->currentProfile->setSaveUserPassword(false);
                    needSave = true;
                }

            } else {
                AuthRetry = false;
                debugMessage(0, i18n("Connect canceled because password enter dialog aborted."));
                return false;
            }

        }

        if (needSave)
            GlobalConfig->saveOptions(true, GlobalConfig->currentProfile->getName());


        debugMessage(0, i18n("Some passwords which were needed were obtained from a password dialog."));

        AuthRetry = false;
        GlobalConfig->haveUserData = true;

        //     QFile OpenvpnSecrectFile (OpenvpnSecrectPath);
        //     QTextStream openvpn_secret_stream( &OpenvpnSecrectFile);
        //     if ( OpenvpnSecrectFile.open( QIODevice::WriteOnly ) )
        //     {
        //      if (GlobalConfig->TmpUsername.isEmpty())
        //       openvpn_secret_stream << GlobalConfig->currentProfile->getUserName() << "\n";
        //      else
        //       openvpn_secret_stream << GlobalConfig->TmpUsername << "\n";
        //      if (GlobalConfig->TmpPassword.isEmpty())
        //       openvpn_secret_stream << GlobalConfig->currentProfile->getUserPassword() << "\n";
        //      else
        //       openvpn_secret_stream << GlobalConfig->TmpPassword<< "\n";
        //     }

    }
    else
    {
        if (GlobalConfig->TmpUsername.isEmpty())
            GlobalConfig->TmpUsername = GlobalConfig->currentProfile->getUserName();
    }

    return true;
}

QString OpenVpnHandler::pingDevice() const
{
    return OpenvpnDevice;
}

void OpenVpnHandler::helperOutputReader()
{
    QStringList msg_list = QString(OpenvpnProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        helperParser(msg, "[openvpn]");
    }
}

void OpenVpnHandler::helperParser(QString msg, const QString &source)
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    bool connectSuccess = false;

    debugMessage(4, source + ": " + msg);
    //  else
    //  {
    //   stderr=true;
    //    msg = QString( OpenvpnProcess->readStderr() );
    //   logMessage ( "stderr openvpn: "+msg, KVpncEnum::debug );
    //  }

    if (msg.indexOf("Connection timed out", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Connection has been timed out. Terminate."));

        errorLine = __LINE__;
    } else if (msg.indexOf("[ECONNREFUSED]: Connection refused", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Connection has been refused. Terminate."));

        errorLine = __LINE__;
    } else if (msg.indexOf("AUTH: Received AUTH_FAILED", 0, Qt::CaseInsensitive) > -1) {
        reason = DISCONNECTION_REASON_AUTHENTICATION_FAILED;
        errorLine = __LINE__;
        //   KMessageBox::error( this, i18n( "Authentication failed (%1)." ,i18n("user password") ));
        serverError(i18n("Authentication failed (%1)." , i18n("user password")));
        //   abort=true;
    } else if (msg.indexOf("ERROR: could not read Auth username/password from management interface", 0, Qt::CaseInsensitive) > -1) {
        //   KMessageBox::error( this, i18n( "Authentication failed (%1)." ,i18n("user password") ));
        serverError(i18n("Username and password could not be read from management interface."));
        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: could not read eToken token username/password/ok from management interface", 0, Qt::CaseInsensitive) > -1) {
        //   KMessageBox::error( this, i18n( "Authentication failed (%1)." ,i18n("user password") ));
        serverError(i18n("eToken password could not be read from management interface."));
        errorLine = __LINE__;
    } else if (msg.indexOf("Insufficient key material or header text not found", 0, Qt::CaseInsensitive) > -1) {
        reason = DISCONNECTION_REASON_AUTHENTICATION_FAILED;
        //   KMessageBox::error( this, i18n( "Authentication failed (%1)." ,i18n("user password") ));
        serverError(i18n("Insufficient key material or header text not found."));
        errorLine = __LINE__;
    } else if (msg.indexOf("not found", 0, Qt::CaseInsensitive) > -1 && msg.indexOf("Message hash algorithm", 0, Qt::CaseInsensitive) > -1) {
        QString hash_algo = msg.section("'", 1, 1);
        serverError(i18n("Hash algorithm \"%1\" not found. Please choose another one." , hash_algo));

        errorLine = __LINE__;
    } else if (msg.indexOf("Cannot load private key file", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error( this, i18n( "Auth username is empty." ) );
        serverError(i18n("Private key file could not be loaded."));
        errorLine = __LINE__;
    } else if (msg.indexOf("'dev-type' is used inconsistently, local='dev-type tun', remote='dev-type tap'", 0, Qt::CaseInsensitive) > -1) {
        //    KMessageBox::error( this, i18n( "Local network type is %1 but remote network type is %2. This must be fixed.\nGo to OpenVPN settings and change it to %2." , QString("tun") , QString("tap") ) );
        //    serverError( i18n( "Local network type is %1 but remote network type is %2. This must be fixed." , QString("tun") , QString("tap") )  );
        //    errorLine = __LINE__;

        debugMessage(0, i18n("Local network type is %1 but remote network type is %2. This will be fixed." , QString("tun") , QString("tap")));
        GlobalConfig->currentProfile->setTunnelDeviceType("tap");
        GlobalConfig->saveOptions(true, GlobalConfig->currentProfile->getName());
        errorLine = __LINE__;
        reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
    } else if (msg.indexOf("'dev-type' is used inconsistently, local='dev-type tap', remote='dev-type tun'", 0, Qt::CaseInsensitive) > -1) {
        //    KMessageBox::error( this, i18n( "Local network type is %1 but remote network type is %2. This must be fixed.\nGo to OpenVPN settings and change it to %2." , "tap" , "tun" ) );
        //    serverError( i18n( "Local network type is %1 but remote network type is %2. This must be fixed." , "tap" , "tun" ) );
        //    errorLine = __LINE__;

        debugMessage(0, i18n("Local network type is %1 but remote network type is %2. This will be fixed." , QString("tap") , QString("tun")));
        GlobalConfig->currentProfile->setTunnelDeviceType("tun");
        GlobalConfig->saveOptions(true, GlobalConfig->currentProfile->getName());
        errorLine = __LINE__;
        reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
    } else if (msg.indexOf("connect to " + QString(GlobalConfig->currentProfile->getHttpProxy() + ":" + QString().setNum(GlobalConfig->currentProfile->getHttpProxyPort()) + " failed"), 0, Qt::CaseInsensitive) > -1) {
        //    else if ( msg.indexOf( "Connection refused",0, Qt::CaseInsensitive ) > -1 ) {
        //     if ( msg.indexOf( "failed",0, Qt::CaseInsensitive ) > -1 ) {
        serverError(i18n("Connection to HTTP proxy (%1:%2) failed." , GlobalConfig->currentProfile->getHttpProxy() , GlobalConfig->currentProfile->getHttpProxyPort()));

        errorLine = __LINE__;
        //    }
    } else if (msg.indexOf("SIGTERM[soft,init_instance] received", 0, Qt::CaseInsensitive) > -1) {

        serverError(i18n("Connection was rejected (wrong HTTP proxy auth data? %1:%2).", GlobalConfig->currentProfile->getHttpProxy() , GlobalConfig->currentProfile->getHttpProxyPort()));

        errorLine = __LINE__;
    } else if (msg.indexOf("MANAGEMENT: Cannot bind TCP socket", 0, Qt::CaseInsensitive) > -1) {

        //    logMessage ( i18n ( "The management port cant bind, please try again later." , GlobalConfig->currentProfile->getHttpProxy() , GlobalConfig->currentProfile->getHttpProxyPort() ) , KVpncEnum::error );
        //    KMessageBox::error ( this, i18n ( "The management port cant bind, please try again later." ) );
        QString NameAndPid = Utils(GlobalConfig).getNameAndPidOfProgramListen(GlobalConfig->OpenvpnManagementPort);
        debugMessage(0, i18n("NameAndPid: %1" , NameAndPid) );
        int pid = -1;
        QString Name = "";
        if (!NameAndPid.isEmpty()) {
            pid = NameAndPid.section('/', 0, 0).toInt();
            Name = NameAndPid.section('/', 1, 1);
            serverError(i18n("Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString().setNum(GlobalConfig->OpenvpnManagementPort) , Name , QString().setNum(pid)));
        } else
            serverError(i18n("Port binding failed"));


        errorLine = __LINE__;
    } else if (msg.indexOf(QString("MANAGEMENT: Socket bind failed on local address 127.0.0.1:" + QString().setNum(GlobalConfig->OpenvpnManagementPort) + ": Address already in use"), 0, Qt::CaseInsensitive) > -1) {

        //    logMessage ( i18n ( "The management port cant bind, please try again later." ) ) , KVpncEnum::error );
        //    KMessageBox::error ( this, i18n ( "The management port cant bind, please try again later." ) );

        QString NameAndPid = Utils(GlobalConfig).getNameAndPidOfProgramListen(GlobalConfig->OpenvpnManagementPort);
        debugMessage(0, i18n("NameAndPid: %1" , NameAndPid) );
        int pid = -1;
        QString Name = "";
        if (!NameAndPid.isEmpty()) {
            pid = NameAndPid.section('/', 0, 0).toInt();
            Name = NameAndPid.section('/', 1, 1);
            serverError(i18n("Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString().setNum(GlobalConfig->OpenvpnManagementPort) , Name , QString().setNum(pid)));
        } else {
            serverError(i18n("Port binding failed"));

        }
        errorLine = __LINE__;
        //    managementhandler->closeConnection();
    } else if (msg.indexOf("TLS key negotiation failed to occur within 60 seconds", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("TLS Error: TLS handshake failed", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("TLS key negotiation failed to occur within 60 seconds, port binding failed"));
        errorLine = __LINE__;
    }
    /*
    else if ( msg.indexOf( "authentication failed", 0, Qt::CaseInsensitive ) > -1 )
    {
        KMessageBox::error( this, i18n( "Authentication has failed." ) );
        errorLine = __LINE__;
    }
    */
    else if (msg.indexOf("Enter Private Key Password", 0, Qt::CaseInsensitive) > -1) {

        debugMessage(0, i18n("Private key password requested, send it...\n"));

        QString PrivKeyPassStr = "";
        //   if (GlobalConfig->currentProfile->getSavePsk())
        PrivKeyPassStr = GlobalConfig->currentProfile->getPrivateKeyPass();
        //   else
        //    PrivKeyPassStr = TmpPrivKeyPassStr;
        if (PrivKeyPassStr.isEmpty()) {
            GlobalConfig->TmpPrivateKeyPass = "";
            QString pass = "";
            EnterXauthInteractivePasscodeDialog dlg(0);
            dlg.setWindowTitle(i18n("Enter private key password"));
            dlg.main->DescriptionLabel->setText(i18n("Enter private key password to unlock private key:"));
            dlg.main->LabelPassword->setText(i18n("Private key password:"));
            dlg.main->SavePasswordCheckBox->setText(i18n("Save private key password"));
            debugMessage(0, "[openvpn] " + i18n("Password for private key requested...\n"));
            if (dlg.exec()) {

                pass = dlg.main->PasswordEdit->text();
                if (!pass.isEmpty()) {

                    debugMessage(2, "OpenvpnManagementHandler: " + i18n("private key password got from user"));

                    if (dlg.main->SavePasswordCheckBox->isChecked()) {
                        GlobalConfig->currentProfile->setSavePrivateKeyPassword(true);
                        GlobalConfig->currentProfile->setPrivateKeyPass(QString(pass));
                    }

                    GlobalConfig->TmpPrivateKeyPass = QString(pass);

                    //             if ( GlobalConfig->KvpncDebugLevel > 5 )
                    //     debugMessage( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass );

                    debugMessage(2, "OpenvpnManagementHandler: " + i18n("Send private key password..."));

                    OpenvpnProcess->write(PrivKeyPassStr.toUtf8());
                    OpenvpnProcess->write("\n");
                } else {
                    serverError("OpenvpnManagementHandler: password empty, stop.");
                    return;
                }
            }
        } else {
            OpenvpnProcess->write(PrivKeyPassStr.toUtf8());
            OpenvpnProcess->write("\n");
            return ;
        }
    } else if (msg.indexOf("Enter Auth Username", 0, Qt::CaseInsensitive) > -1) {
        debugMessage(0, i18n("Username requested, send it...\n"));

        QString UsernameStr = "";
        if (!GlobalConfig->currentProfile->getUserName().isEmpty())
            UsernameStr = GlobalConfig->currentProfile->getUserName();
        else
            UsernameStr = GlobalConfig->TmpUsername;

        debugMessage(0, "OpenVPN Auth User name: " + UsernameStr );

        OpenvpnProcess->write(UsernameStr.toUtf8());
        OpenvpnProcess->write("\n");

        return ;
    } else if (msg.indexOf("Enter Auth Password:", 0, Qt::CaseInsensitive) > -1) {
        debugMessage(0, i18n("User password requested, send it...\n"));

        if (!GlobalConfig->currentProfile->getSaveUserPassword() && (reason != DISCONNECTION_REASON_AUTHENTICATION_FAILED))
            OpenvpnProcess->write(GlobalConfig->currentProfile->getUserPassword().toUtf8());
        else {
            //     if ( GlobalConfig->KvpncDebugLevel > 0 )
            //      logMessage ( "OpenVPN Auth Pass: " + GlobalConfig->TmpPassword , KVpncEnum::debug );


            OpenvpnProcess->write(GlobalConfig->TmpPassword.toUtf8());
            OpenvpnProcess->write("\n");
        }

    } else if (msg.indexOf("Cannot resolve host address", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Host could not be resolved."));

        errorLine = __LINE__;
    } else if (msg.indexOf("could not find module", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Module not found."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Socket bind failed on local address", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Binding to socket on local address failed."));

        errorLine = __LINE__;
    } else if (msg.indexOf("No route to host", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("No route to host found."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Connection terminated", 0, Qt::CaseInsensitive) > -1) {
        //   KMessageBox::error( this, i18n( "Connection has been terminated." ) );
        errorLine = __LINE__;
    } else if (msg.indexOf("Cannot open file key file", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Cannot open the preshared key file."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Authenticate/Decrypt packet error: cipher final failed", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Authentication has failed because decryption failure. Please check OpenVPN settings."));

        errorLine = __LINE__;
    } else if (msg.indexOf("'auth' is used inconsistently", 0, Qt::CaseInsensitive) > -1) {
        QString LocalAuth = msg.section('=', 1, 1).section(',', 0, 0).section(' ', 1, 1).remove("'", Qt::CaseSensitive);
        QString PeerAuth = msg.section('=', 2, 2).section(' ', 1, 1).remove("'", Qt::CaseSensitive);
        //    KMessageBox::error( this, i18n( "Wrong authentication method used. We use \"%1\" but peer wants \"%2\". Please change it in %3 settings." , LocalAuth , PeerAuth , i18n( "OpenVPN" ) ) );
        //    serverError( i18n( "Wrong authentication method used. We use \"%1\" but peer wants \"%2\". Please change it in %3 settings." , LocalAuth , PeerAuth , i18n( "OpenVPN" ) )  );
        //    errorLine = __LINE__;

        debugMessage(0, i18n("Wrong authentication method used. We use \"%1\" but peer wants \"%2\", this will be fixed." , LocalAuth , PeerAuth , i18n("OpenVPN")) );
        GlobalConfig->currentProfile->setUseAuthenticationAlgorithm(true);
        GlobalConfig->currentProfile->setAuthenticationAlgorithm(PeerAuth);
        GlobalConfig->saveOptions(true, GlobalConfig->currentProfile->getName());
        errorLine = __LINE__;
        reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
    } else if (msg.indexOf("WARNING: 'cipher' is used inconsistently", 0, Qt::CaseInsensitive) > -1) {
        // example: WARNING: 'cipher' is used inconsistently, local='cipher BF-CBC', remote='cipher AES-128-CBC'
        QString LocalCipher = msg.section('=', 1, 1).section(',', 0, 0).section(' ', 1, 1).remove("'", Qt::CaseSensitive);
        QString PeerCipher = msg.section('=', 2, 2).section(' ', 1, 1).remove("'", Qt::CaseSensitive);
        //    KMessageBox::error( this, i18n( "Wrong cipher used. We use \"%1\" but peer wants \"%2\". Please change it in %3 settings." , LocalCipher , PeerCipher , i18n( "OpenVPN" ) ) );
        //    serverError( i18n( "Wrong chiper used. We use \"%1\" but peer wants \"%2\". Please change it in %3 settings." , LocalCipher , PeerCipher , i18n( "OpenVPN" ) )  );
        //    errorLine = __LINE__;

        debugMessage(0, i18n("Wrong cipher used. We use \"%1\" but peer wants \"%2\", this will be fixed." , LocalCipher , PeerCipher , i18n("OpenVPN")) );
        GlobalConfig->currentProfile->setUserdefiniedCipher(PeerCipher);
        GlobalConfig->currentProfile->setUseUserdefiniedCipher(true);
        GlobalConfig->saveOptions(true, GlobalConfig->currentProfile->getName());
        errorLine = __LINE__;
        reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
    } else if (msg.indexOf("Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]", 0, Qt::CaseInsensitive) > -1) {
        //    KMessageBox::error( this, i18n( "OpenVPN configuration error. Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]" ) );
        //    serverError( i18n( "OpenVPN configuration error. Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]" ) );
        //    errorLine = __LINE__;
        debugMessage(0, i18n("OpenVPN configuration error. Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]."));
    } else if (msg.indexOf("Options error: Unrecognized option or missing parameter", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("OpenVPN configuration error. Unrecognized option or missing parameter."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Options error: Parameter", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("OpenVPN configuration error. Wrong parameter in config file. Please contact the KVpnc author."));

        errorLine = __LINE__;
    } else if (msg.indexOf("TCP connection established", 0, Qt::CaseInsensitive) > -1) {
        debugMessage(0, "[openvpn]: " + i18n("Low level connection to %1 established." , QString(GlobalConfig->currentProfile->getGateway())));
    } else if (msg.indexOf("UDP connection established", 0, Qt::CaseInsensitive) > -1) {
        debugMessage(0, "[openvpn]: " + i18n("Low level connection to %1 established." , GlobalConfig->currentProfile->getGateway()));
    }
    //   else if ( msg.indexOf( "Options error", 0, Qt::CaseInsensitive ) > -1 )
    //   {
    //    KMessageBox::error( this, i18n( "OpenVPN configuration error." ) );
    //    serverError( i18n( "OpenVPN configuration error." ) );
    //    GlobalConfig->currentProfile->setDoReconnectAfterConnectionLost( false );
    //    errorLine = __LINE__;
    //   }
    else if (msg.indexOf("refused", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error( this, i18n( "Connection to OpenVPN server was refused." ) );
    } else if (msg.indexOf("Connection timed out", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Connection has been timed out. Terminate."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Cannot load certificate file", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Certificate file (%1) could not be load. Please check path of it." , GlobalConfig->currentProfile->getX509Certificate()));

        errorLine = __LINE__;
    } else if (msg.indexOf("ifconfig failed", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("ifconfig has failed."));

        errorLine = __LINE__;
    } else if (msg.indexOf("Auth username is empty", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error( this, i18n( "Auth username is empty." ) );
        serverError(i18n("Auth username is empty."));
        errorLine = __LINE__;
    } else if (msg.indexOf("Cannot load private key file", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error( this, i18n( "Auth username is empty." ) );
        serverError(i18n("Private key file could not be loaded."));
        errorLine = __LINE__;
    } else if (msg.indexOf("Need 'token-insertion-request' confirmation MSG:Please insert SLOT", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Need token to be insert. Please insert token in SLOT...."));

        errorLine = __LINE__;
    } else if (msg.indexOf("process exiting", 0, Qt::CaseInsensitive) > -1) {
        debugMessage(0, i18n("%1 is shutting down." , QString("openvpn")));
        errorLine = __LINE__;
    } else if (msg.indexOf("Initialization Sequence Completed", 0, Qt::CaseInsensitive) > -1) {
        connectSuccess = true;
    } else if (msg.indexOf("TUN/TAP device", 0, Qt::CaseInsensitive) > -1) {
        // TUN/TAP device tun0 opened
        OpenvpnDevice = msg.section(' ', -2, -2);    // tun0
        gui->setTunnelInterfaceIP(msg.section(' ', -5, -5));    // ip
        NetworkInterface iface(GlobalConfig, kapp);
        gui->setTunnelInterfaceIP(iface.getInterfaceIP(OpenvpnDevice));

        debugMessage(0, i18n("Tunnel device: %1\n" , OpenvpnDevice));
    }

    // success

    if (connectSuccess) {
        successMessage(i18n("%1: Connection established.", source));

        setStatusConnected(__LINE__);

        debugMessage(0, "[openvpn] " + i18n("Using %1 as tunnel device." , OpenvpnDevice) );
    }
    if (errorLine) {
        setStatusDisconnected(errorLine, reason);
    }
}
