/*****************************************************************************
 * 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/QObject>
#include <QtCore/QProcess>
#include <kmessagebox.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <unistd.h>
#include "IpsecHandler.h"
#include "enterpassworddialog.h"
#include "enterxauthinteractivepasscodedialog.h"
#include "kvpnc.h"
#include "kvpncconfig.h"
#include "utils.h"

IpsecHandler::IpsecHandler(
    KVpnc *ui,
    KVpncConfig *config,
    QString type,
    QString daemons,
    bool _useL2tpAfterFirstConnection):
        HandlerBase(ui, config, type, daemons, _useL2tpAfterFirstConnection),
        m_tool("ipsec", "0.0", ".|-|/")
{
    ToolInfo *info = Utils(GlobalConfig).getToolInfo(m_tool.name());
    if (!info->Version.isEmpty()) {
        // Typical version information:
        //
        // Linux Openswan U2.6.23/K2.6.32-21-generic (netkey)
        // See `ipsec --copyright' for copyright information.
        //
        // By the time we get here, we have "Openswan U2.6.23"...
        m_tool.setActualVersion(info->Version.right(info->Version.indexOf("U") + 1));
    }
    m_toolIsStrongSwan = m_tool.actualVersion().contains("strongSwan", Qt::CaseInsensitive);
    m_toolIsOpenSwan = m_tool.actualVersion().contains("Openswan", Qt::CaseInsensitive);
    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
        if (!ui->pppdCapabilitiesCollected) {
            debugMessage(3, i18n("Collecting pppd capabilities..."));
            GlobalConfig->pppdcap = Utils(GlobalConfig).checkPppdCapabilities();
            GlobalConfig->appPointer->restoreOverrideCursor();
            pppdHasReplacedefaultrouteSupport = GlobalConfig->pppdcap.pppdHasReplacedefaultrouteSupport;
            ui->pppdCapabilitiesCollected = true;
        }
    }
}

bool IpsecHandler::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 ipsec
        if (!Utils(GlobalConfig).getToolInfo(m_tool.name())->found) {
            reportError(i18n("Unable to find \"%1\" at \"%2\".", m_tool.name(), GlobalConfig->pathToIpsec));
            errorLine = __LINE__;
        } else {
            debugMessage(0, i18n("Found helper %1 at %2", m_tool.name(), GlobalConfig->pathToIpsec));
        }
    }

    if (!errorLine) {
        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
            if (!Utils(GlobalConfig).getToolInfo("l2tpd")->found &&
                    !Utils(GlobalConfig).getToolInfo("xl2tpd")->found) {
                reportError(i18n("Unable to find \"%1\" or \"%2\"!").arg ("l2tpd").arg ("xl2tpd"));
                errorLine = __LINE__;
            } else {
                debugMessage(1,  i18n ( "l2tpd_freeswan" ) );
            }
        }
    }
    if (!errorLine) {
        GlobalConfig->TmpGatewayIP = Utils(GlobalConfig, kapp).resolveName(GlobalConfig->currentProfile->getGateway());
        if (GlobalConfig->TmpGatewayIP == "0.0.0.0" || GlobalConfig->TmpGatewayIP.isEmpty()) {
            reportError(i18n("Host \"%1\" could not be resolved." , GlobalConfig->currentProfile->getGateway()));
            errorLine = __LINE__;
        } else {
            debugMessage(0, i18n("Gateway hostname (%1) resolved to \"%2\"." , GlobalConfig->currentProfile->getGateway() , GlobalConfig->TmpGatewayIP));
        }
    }

    //   if ( !Utils( GlobalConfig, gui ).kernelModuleLoad( "esp4", gui ) )
    //   {
    //    KMessageBox::information( gui, i18n( "Loading of module \"%1\" failed." ,QString( "esp4" ) );
    //    errorMessage( i18n( "Loading module \"%1\" has failed: stop." ,QString( "esp4" ) );
    //    ok = false;
    //   }
    //
    //   if ( !Utils( GlobalConfig, gui ).kernelModuleLoad( "ah4", gui ) )
    //   {
    //    KMessageBox::information( gui, i18n( "Loading of module \"%1\" failed." ,QString( "ah4" ) );
    //    errorMessage( i18n( "Loading module \"%1\" has failed: stop." ,QString( "ah4" ) );
    //    ok = false;
    //   }

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

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

    QString LocalIP;
    if (!errorLine) {
        QString tmpInterface;
        NetworkInterface iface(GlobalConfig, kapp);
        if (GlobalConfig->currentProfile->getNetworkDevice() == "default" || GlobalConfig->currentProfile->getNetworkDevice() == "") {
            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())
            tmpInterface = "lo"; // no default interface found :(

        if (LocalIP.isEmpty())
            LocalIP = "127.0.0.1"; // no IP for default interface found :(

        debugMessage(0, i18n("default interface: %1 LocalIP: %2", tmpInterface, LocalIP));
        if (!backupDefaultRoute()) {
            errorLine = __LINE__;
        }
    }

    //   // here we go
    QString IpsecPrefix = "/etc";
    QString ProfileName = GlobalConfig->currentProfile->getName();
    QString RemoteNetAddr = GlobalConfig->currentProfile->getRemoteNetAddr();
    QString RemoteNet = "";
    QString LocalNet = "";
    if (!errorLine) {
        QString Gateway = GlobalConfig->currentProfile->getGateway();
        QString RemoteNetMask = GlobalConfig->currentProfile->getRemoteNetMask();
        if (!RemoteNetAddr.isEmpty())
            RemoteNet = RemoteNetAddr + "/" + RemoteNetMask;
        QString LocalNetAddr = LocalIP;
        QString LocalNetMask = "/32";

        QString CertPath = GlobalConfig->currentProfile->getCertPath();
        QString PrivateKeyPass = GlobalConfig->currentProfile->getPrivateKeyPass();
        QString PrivateKey = GlobalConfig->currentProfile->getPrivateKey();

        startStopIpsec(true);
        backupIpsecSystemConfig();

        // write /etc/ipsec.secrets
        QFile IpsecSecretsFile(IpsecPrefix + "/ipsec.secrets");    // warning: static
        QTextStream stream(&IpsecSecretsFile);
        if (IpsecSecretsFile.open(QIODevice::WriteOnly)) {
            // cert
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert) {
                stream << "# generated by kvpnc. Do not edit it." << "\n";
                stream << "# profile: " + ProfileName << "\n";
                if (!GlobalConfig->currentProfile->getUseSmartcard())
                    stream << ": RSA " + GlobalConfig->currentProfile->getPrivateKey() + " \"" + GlobalConfig->currentProfile->getPrivateKeyPass() + "\"\n";
                else {
                    stream << ": PIN %smartcard \"" << Pkcs11PIN << "\"" << "\n";
                    //       stream << ": PIN %smartcard \"123456\"" << "\n";
                    //       stream << ": PIN %smartcard %prompt" << "\n";

                }

                //  mw->DebugOutput->append( "cert: private key: : RSA " + PrivateKey + " \"" + PrivateKeyPass );
            }
            // PSK
            else {
                stream << "# generated by kvpnc. Do not edit it." << "\n";
                stream << "# profile: " + ProfileName << "\n";

                if (!GlobalConfig->currentProfile->getPskIsInFile()) {
                    debugMessage(0, QString("ipsec: "+ m_tool.actualVersion() ) );
                    if ( !GlobalConfig->currentProfile->getAuthWithUsernameAndPassword() )
                    {
                        //if ( !GlobalConfig->currentProfile->getUseSpecialLocalID())
                        //  stream << "" << GlobalConfig->TmpGatewayIP  << " : PSK \"" + GlobalConfig->currentProfile->getPreSharedKey() + "\"\n";
                        //else
                        stream << "" << GlobalConfig->TmpGatewayIP  << " " << GlobalConfig->currentProfile->getSpecialLocalID() << " : PSK \"" + GlobalConfig->currentProfile->getPreSharedKey() + "\"\n";
                    } else if ((m_toolIsOpenSwan && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword())) {
                        // XAUTH openswan
                        stream << GlobalConfig->TmpGatewayIP  << " @" << GlobalConfig->currentProfile->getID() << "  : PSK \"" + GlobalConfig->currentProfile->getPreSharedKey() + "\"\n";
                    } else if ((m_toolIsStrongSwan && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword())) {
                        // XAUTH strongSwan
                        stream << ": PSK \"" + GlobalConfig->currentProfile->getPreSharedKey() + "\"\n";
                        stream << ": XAUTH \"" + GlobalConfig->TmpUsername + "\" \"" + GlobalConfig->TmpPassword + "\"" + "\n";
                    }
                } else {
                    QFile PskFile(GlobalConfig->currentProfile->getPreSharedKeyFile());
                    if (PskFile.open(QIODevice::ReadOnly)) {
                        QString PskFileContent = QString(PskFile.readAll());
                        PskFile.close();
                        if (!GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                            // normal
                            stream << ": PSK \"" + PskFileContent + "\"\n";
                        } else {
                            // XAUTH
                            stream << GlobalConfig->TmpGatewayIP  << " @" << GlobalConfig->currentProfile->getID() << "  : PSK \"" + PskFileContent + "\"\n";
                        }
                    }
                }

            }
            IpsecSecretsFile.close();
            debugMessage(6, i18n("---- %1 ---" , IpsecSecretsFile.fileName()));
            debugMessage(6, QString(IpsecSecretsFile.readAll()));
            debugMessage(6, i18n("---- end ---"));
        } else {
            reportError(i18n("Failed to create \"%1\"." , IpsecSecretsFile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        // write /etc/ipsec.conf
        //file.setName( tmpPath + "freeswan." + ProfileName + ".conf" )
        QFile IpsecConfigFile(IpsecPrefix + "/ipsec.conf");    // warning: static
        if (IpsecConfigFile.open(QIODevice::WriteOnly)) {

            QTextStream stream(&IpsecConfigFile);
            stream << "# generated by kvpnc. Do not edit it." << "\n";
            stream << "# profile: " + ProfileName << "\n";
            stream << "# right: remote" << "\n";
            stream << "# left: local" << "\n";
            stream << "" << "\n";

            debugMessage(3, i18n("IPSec version: %1", m_tool.actualVersion()));

            //     if ( realversion.indexOf ( QString("2."), 0, Qt::CaseInsensitive ) > -1 )
            if (!IpsecType.contains("free", Qt::CaseInsensitive)) {    // only version 2
                stream << "version 2" << "\n";
            }

            stream << "config setup" << "\n";
            if (GlobalConfig->currentProfile->getNetworkDevice() == "default")
                stream << "    interfaces=%defaultroute" << "\n";
            else
                stream << "    interfaces=\"ipsec0=" << tmpInterface << "\"" << "\n";

            if (GlobalConfig->currentProfile->getUseSmartcard() /*&& IpsecType.contains( "strongSwan", Qt::CaseInsensitive )*/)
                stream << "    pkcs11module=" + GlobalConfig->currentProfile->getPkcs11Providers() + "\n";

            if (GlobalConfig->currentProfile->getUseVirtualSubnetworks()) {
                if (!GlobalConfig->currentProfile->getVirtualSubnetworks().isEmpty())
                    stream << "    virtual_private=" << GlobalConfig->currentProfile->getVirtualSubnetworks().replace(" virtual_private=", "") << "\n";
            }


            stream << "    klipsdebug=\"";
            for ( QStringList::Iterator it = GlobalConfig->KlipsDebug.begin(); it != GlobalConfig->KlipsDebug.end(); ++it )
            {
                stream << *it << " ";

            }
            if (GlobalConfig->KlipsDebug.isEmpty())
                stream << "none";
            stream << "\"" << "\n";

            stream << "    plutodebug=\"";
            for ( QStringList::Iterator it = GlobalConfig->PlutoDebug.begin(); it != GlobalConfig->PlutoDebug.end(); ++it )
            {
                stream << *it << " ";

            }
            if (GlobalConfig->PlutoDebug.isEmpty())
                stream << "none";
            stream << "\"" << "\n";


            // FIXME add detection for nat-t
            if (GlobalConfig->currentProfile->getUseNat())
                stream << "    nat_traversal=yes" << "\n";
            else
                stream << "    nat_traversal=no" << "\n";

            if (m_tool.actualIsGe("1.0")) {
                if (!m_toolIsStrongSwan)
                    stream << "    plutoload=%search" << "\n";
                if (!m_toolIsStrongSwan)
                    stream << "    plutostart=%search" << "\n";
                if (m_toolIsStrongSwan)
                    stream << "    plutostart=yes" << "\n";
            }
            stream << "" << "\n";
            stream << "conn %default" << "\n";
            stream << "    keyingtries=" << GlobalConfig->currentProfile->getMaxConnectTries() << "\n";

            // FIXME make it dynamiclly
            stream << "    keylife=1200s" << "\n";
            stream << "    ikelifetime=1200s" << "\n";
            stream << "\n";

            // our connection
            stream << "conn " << GlobalConfig->currentProfile->getName() << "\n";
            // x509
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert) {
                stream << "    authby=rsasig" << "\n";
                stream << "    leftrsasigkey=%cert" << "\n";
                stream << "    rightrsasigkey=%cert" << "\n";
            } else if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk) {
                // FIXME maybe we should store rightrsasigkey at better place
                if (GlobalConfig->currentProfile->getUseSpecialServerCertificate())
                {
                    stream << "    rightrsasigkey=" << GlobalConfig->currentProfile->getSpecialServerCertificate() << "\n";
                }

                // FIXME maybe we should store leftrsasigkey at better place
                if (GlobalConfig->currentProfile->getPskIsInFile())
                {
                    stream << "    leftrsasigkey=" << GlobalConfig->currentProfile->getPreSharedKeyFile() << "\n";
                }


                if ( ( m_toolIsStrongSwan && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword() ) ) {
                    stream << "    authby=xauthpsk" << "\n";
                } else {
                    stream << "    authby=secret" << "\n";
                }
            }
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                stream << "    type=transport" << "\n"; // we have to use tunnel mode

                if (GlobalConfig->currentProfile->getIpsecVpnMode() == "tunnel") {
                    GlobalConfig->currentProfile->setIpsecVpnMode("transport");
                    debugMessage(0, i18n("IPsec vpn mode was set to \"tunnel\" but must be \"transport\" for use with L2TP. This was temporarily fixed."));
                }
            } else {
                stream << "    type=" << GlobalConfig->currentProfile->getIpsecVpnMode() << "\n";
            }
            if (GlobalConfig->currentProfile->getExchangeMode() == "aggressive") {
                stream << "    aggrmode=yes" << "\n";
            }

            if (GlobalConfig->currentProfile != 0 && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                // udp/l2tp
                stream << "    rightprotoport=17/1701" << "\n";
                stream << "    leftprotoport=17/1701" << "\n";
            }

            stream << "    keyexchange=ike" << "\n";
            if (GlobalConfig->currentProfile->getUseCustomIke())
                stream << "    ike=" << GlobalConfig->currentProfile->getIpsecIke() << "\n";

            if (GlobalConfig->currentProfile->getUseCustomEsp())
                stream << "    esp=" << GlobalConfig->currentProfile->getIpsecEsp()  << "\n";

            //if ( GlobalConfig->currentProfile->getUseMtu() )
            //  stream << "    overridemtu=" << GlobalConfig->currentProfile->getMtu() << "\n";

            if ( GlobalConfig->currentProfile->getUsePerfectForwardSecrety() ) {
                stream << "    pfs=yes" << "\n";
                QString pfs_group = GlobalConfig->currentProfile->getPerfectForwardSecrety();

                //                      QString PFSGroupNumber = "2";
                //                      if (pfs_group== "modp768")
                //                          PFSGroupNumber = "1";
                //                      else if (pfs_group== "modp1024")
                //                          PFSGroupNumber = "2";
                //                      else if (pfs_group== "modp1536")
                //                          PFSGroupNumber = "5";
                //                      else if (pfs_group== "modp2048")
                //                          PFSGroupNumber = "14";
                //                      else if (pfs_group== "modp3072")
                //                          PFSGroupNumber = "15";
                //                      else if (pfs_group== "modp4096")
                //                          PFSGroupNumber = "16";
                //                      else if (pfs_group== "modp6144")
                //                          PFSGroupNumber = "17";
                //                      else if (pfs_group== "modp8192")
                //                          PFSGroupNumber = "18";
                if ( !pfs_group.isEmpty() )
                    //                          stream << "    pfsgroup=" << PFSGroupNumber << "\n";
                    stream << "    pfsgroup=" << pfs_group << "\n";
            } else {
                stream << "    pfs=no" << "\n";
            }



            //     stream << "    auto=start" << "\n";
            stream << "    left=" + LocalIP << "\n"; // local ip
            //     stream << "    left=%defaultroute" << "\n"; // iface to default route
            //     stream << " leftnexthop = "+LocalNet << "\n";
            //     stream << " leftsubnet = " << "\n"; // local network

            if (!GlobalConfig->currentProfile->getLeftNextHop().isEmpty())
                stream << "    leftnexthop=" + GlobalConfig->currentProfile->getLeftNextHop() << "\n";
            //    stream << " rightnexthop = " << "192.168.1.1"  << "\n";
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert) {
                if (!GlobalConfig->currentProfile->getUseSmartcard())
                    stream << "    leftcert=\"" + GlobalConfig->currentProfile->getX509Certificate() << "\"" << "\n";
                else {
                    // we have to split slot id and name ("0 : foobar") => 0
                    QString Pkcs11Slot = GlobalConfig->currentProfile->getPkcs11Slot().section(':', 0, 0).trimmed();
                    stream << "    leftcert=%smartcard" << Pkcs11Slot << ":" << GlobalConfig->currentProfile->getPkcs11Id() << "\n";
                }

                if (GlobalConfig->currentProfile->getUseSpecialServerCertificate())
                    stream << "    rightcert=\"" + GlobalConfig->currentProfile->getSpecialServerCertificate() << "\"" << "\n";
                //      else
                //       stream << "    rightcert=\"" + rightcert + "\"" << "\n";

                if (GlobalConfig->currentProfile->getUseSpecialRemoteID())
                    stream << "    rightid=\"" + GlobalConfig->currentProfile->getSpecialRemoteID() << "\"" << "\n";
                //stream << "    rightid=\"/C=DE/ST=Sachsen-Anhalt/O=Powersoft/OU=IT/CN=212.100.100.212\"" << "\n";
                //      else
                //      {
                //       if ( GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert )
                //        rightid = getX509CertificateID ( GlobalConfig->currentProfile->getX509Certificate(), false ); // remote
                //      }

                //      if ( !GlobalConfig->currentProfile->getUseSpecialLocalID() )

                QString leftid = "";
                QString rightid = "";
                if (GlobalConfig->currentProfile->getLocalIDType() == i18n("Certificate ID")) {
                    if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert && !GlobalConfig->currentProfile->getUseSmartcard())
                        leftid = getX509CertificateID(GlobalConfig->currentProfile->getX509Certificate(), true);    // local
                    else
                        leftid = "asn1dn";
                    stream << "    leftid=\"" + leftid + "\"" << "\n";
                } else {
                    stream << "    leftid=\"" + GlobalConfig->currentProfile->getSpecialLocalID() << "\"" << "\n";
                }

            }
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk) {
                if (GlobalConfig->currentProfile->getUseSpecialRemoteID()) {
                    if ( GlobalConfig->currentProfile->getRemoteIDType() == "asn1dn" ) {
                        stream << "    rightid=@" << GlobalConfig->TmpGatewayIP << "\n";
                    }
                    else {
                        if (GlobalConfig->currentProfile->getRemoteIDType() == "address" && !Utils(GlobalConfig).isValidIPv4Address( GlobalConfig->currentProfile->getSpecialRemoteID() ) ) {
                            QString resolvedIp = Utils(GlobalConfig).resolveName(GlobalConfig->currentProfile->getSpecialRemoteID());
                            if (resolvedIp.isEmpty()) {
                                errorMessage( i18n("Remote ID \"%1\" (type: address) could not resolved, ommiting right id.", GlobalConfig->currentProfile->getSpecialRemoteID()));

                            } else {
                                debugMessage(3,  i18n("Remote ID \"%1\" (type: address) resolved to: %2", GlobalConfig->currentProfile->getSpecialRemoteID()).arg(resolvedIp) );
                                stream << "    rightid=" + resolvedIp << "\n";
                            }
                        }

                        else {
                            stream << "    rightid=" + GlobalConfig->currentProfile->getSpecialRemoteID() << ""<< "\n";
                        }
                    }
                }

                //stream << "    rightid=\"/C=DE/ST=Sachsen-Anhalt/O=Powersoft/OU=IT/CN=212.100.100.212\"" << "\n";
                //if (GlobalConfig->currentProfile->getUseSpecialLocalID() && !GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                if (GlobalConfig->currentProfile->getUseSpecialLocalID()) {
                    if (GlobalConfig->currentProfile->getLocalIDType() == "asn1dn")
                        stream << "    leftid=" << GlobalConfig->TmpGatewayIP << "\n";
                    else
                    {
                        if (GlobalConfig->currentProfile->getLocalIDType() == "address" && !Utils(GlobalConfig).isValidIPv4Address( GlobalConfig->currentProfile->getSpecialLocalID() ) ) {
                            QString resolvedIp = Utils(GlobalConfig).resolveName(GlobalConfig->currentProfile->getSpecialLocalID());
                            if (resolvedIp.isEmpty()) {
                                errorMessage( i18n("Local ID \"%1\" (type: address) could not resolved, ommiting left id.", GlobalConfig->currentProfile->getSpecialLocalID()));

                            } else {
                                debugMessage(3,  i18n("Local ID \"%1\" (type: address) resolved to: %2", GlobalConfig->currentProfile->getSpecialLocalID()).arg(resolvedIp) );
                                stream << "    leftid=" + resolvedIp << "\n";
                            }
                        }

                        else
                            stream << "    leftid=\"" + GlobalConfig->currentProfile->getSpecialLocalID() << "\""<< "\n";
                    }

                }
            }

            //stream << "    right=" + GlobalConfig->currentProfile->getGateway() << "\n";
            stream << "    right=" + GlobalConfig->TmpGatewayIP << "\n";

            if (!GlobalConfig->currentProfile->getRightNextHop().isEmpty()) {
                stream << "    rightnexthop=" + GlobalConfig->currentProfile->getRightNextHop() << "\n";
            }


            if (GlobalConfig->currentProfile->getUseVirtualIP()) {
                if (!GlobalConfig->currentProfile->getRemoteVirtualIP().isEmpty())
                    stream << "    rightsubnet=" << GlobalConfig->currentProfile->getRemoteVirtualIP() << "\n";
            } else {
                if (GlobalConfig->currentProfile->getUseRemoteNetwork() && !RemoteNetAddr.isEmpty())
                    stream << "    rightsubnet=" << RemoteNet << "\n";
            }

            if (!LocalNet.isEmpty())
                stream << "    leftsubnet=" << LocalNet << "\n";

            if (GlobalConfig->currentProfile->getUseLeftSourceIp()) {
                if ( !GlobalConfig->currentProfile->getLeftSourceIp().isEmpty() )
                {
                    stream << "    leftsourceip=" << GlobalConfig->currentProfile->getLeftSourceIp() << "" << "\n";
                    stream << "    leftsubnet=" << GlobalConfig->currentProfile->getLeftSourceIp() << "/32"  << "\n";
                }
            }
            if (GlobalConfig->currentProfile->getUseRightSourceIp()) {
                if (!GlobalConfig->currentProfile->getRightSourceIp().isEmpty())
                    stream << "    rightsourceip=" << GlobalConfig->currentProfile->getRightSourceIp() << "\n";
            }




            // XAUTH
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                QString LocalID = GlobalConfig->currentProfile->getSpecialLocalID();
                //            if (!LocalID.indexOf( QString("@"), 0, Qt::CaseInsensitive ) > -1)
                //       LocalID="@"+LocalID;
                if (m_toolIsOpenSwan) {
                    stream << "    leftxauthclient=yes" << "\n";
                    stream << "    rightxauthserver=yes" << "\n";
                }
                if (m_toolIsStrongSwan) {
                    stream << "    xauth=client" << "\n";
                }
                stream << "    leftid=" << LocalID << "\n";

                // later
                //      stream << "    modecfgpull=no" << "\n";
            }

            stream << "    auto=add" << "\n";

            if (GlobalConfig->currentProfile->getDisableOpportunisticEncryption()) {
                stream << "\n";
                stream << "# disable opportunistic encryption" << "\n";
                stream << "conn block" << "\n";
                stream << "    auto=ignore" << "\n\n";

                stream << "conn private" << "\n";
                stream << "    auto=ignore" << "\n\n";

                stream << "conn private-or-clear" << "\n";
                stream << "    auto=ignore" << "\n\n";

                stream << "conn clear-or-private" << "\n";
                stream << "    auto=ignore" << "\n";

                stream << "conn clear" << "\n";
                stream << "    auto=ignore" << "\n\n";

                stream << "conn packetdefault" << "\n";
                stream << "    auto=ignore" << "\n";
            }

            IpsecConfigFile.close();

        } else {
            reportError(i18n("Failed to create \"%1\"." , IpsecConfigFile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        debugMessage(6, IpsecPrefix + "/ipsec.conf");
        debugMessage(6, "---------------------");
        QString IpsecContent = "";
        QFile file(IpsecPrefix + "/ipsec.conf");
        if (file.open(QIODevice::ReadOnly)) {
            QStringList contentlist = QString(file.readAll()).split("\n");
            for (int i = 0; i < contentlist.size(); ++i) {
                QString line = contentlist.at(i);
                debugMessage(6, line);
            }
            file.close();
        } else {
            errorMessage(i18n("%1 could not be opened. Stop.", file.fileName()));
            errorLine = __LINE__;
        }
        debugMessage(6, "---------------------");
    }

    QString tmpInterface2 = "";
    if (!errorLine) {
        // iptables need the right interface (eth0:1 => eth0)
        int pointPos = tmpInterface.indexOf(QChar(':'), 0, Qt::CaseInsensitive);
        if (pointPos > 1) {
            tmpInterface2 = tmpInterface.left(pointPos);
        } else
            tmpInterface2 = tmpInterface;

        // write iptables.<profile>_add_ipsec_freeswan.sh
        QFile file(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".add_ipsec_freeswan.sh");
        QTextStream stream(&file);
        if (file.open(QIODevice::WriteOnly)) {
            stream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            stream << "# generated by kvpnc. Do not edit it." << "\n";
            stream << "# profile: " + ProfileName << "\n";
            stream << "" << "\n";
            stream << "#  AH" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p 50 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I OUTPUT -p 50 -d " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream << "" << "\n";
            stream << "#  ESP" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p 51 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I OUTPUT -p 51 -d " << GlobalConfig->currentProfile->getGateway() << " -j  ACCEPT" << "\n";
            stream << "" << "\n";
            stream << "#  IKE" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream << "" << "\n";
            stream << "#  NAT-T" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 4500 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            if (GlobalConfig->currentProfile != 0 && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                stream << "#  L2TP" << "\n";
                stream << GlobalConfig->pathToIptables << " -I OUTPUT -p udp --sport 1701 -o " << tmpInterface2 << " -s " << LocalIP << " -j ACCEPT" << "\n";
                stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 1701 -i " << tmpInterface2 << " -d " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            }
            file.close();
        } else {
            errorMessage(i18n("%1 could not be opened. Stop." , tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".add_ipsec_freeswan.sh"));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        QFile file1(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh");
        QTextStream stream1(&file1);
        if (file1.open(QIODevice::WriteOnly)) {
            stream1 <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            stream1 << "# generated by kvpnc. Do not edit it." << "\n";
            stream1 << "# profile: " + GlobalConfig->currentProfile->getName() << "\n";
            stream1 << "" << "\n";
            stream1 << "#  AH" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p 50 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p 50 -d " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream1 << "" << "\n";
            stream1 << "#  ESP" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p 51 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p 51 -d " << GlobalConfig->currentProfile->getGateway() << " -j  ACCEPT" << "\n";
            stream1 << "" << "\n";
            stream1 << "#  IKE" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            stream1 << "" << "\n";
            stream1 << "#  NAT-T" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 4500 -i " << tmpInterface2 << " -s " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            if (GlobalConfig->currentProfile != 0 && GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                stream1 << "#  L2TP" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p udp --sport 1701 -o " << tmpInterface2 << " -s " << LocalIP << " -j ACCEPT" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 1701 -i " << tmpInterface2 << " -d " << GlobalConfig->currentProfile->getGateway() << " -j ACCEPT" << "\n";
            }
        } else {
            errorMessage(i18n("%1 could not be opened. Stop." , tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh"));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk) {
            // write psk.<profile>.key
            QFile Pskfile(tmpPath + "psk." + ProfileName + ".key");
            QTextStream stream(&Pskfile);
            if (Pskfile.open(QIODevice::WriteOnly)) {
                stream << GlobalConfig->currentProfile->getPreSharedKey() << "\n";
                Pskfile.close();
            } else {
                errorMessage(i18n("%1 could not be opened. Stop.", Pskfile.fileName()));
                errorLine = __LINE__;
            }
        }
    }

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

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

        //    if (GlobalConfig->currentProfile->useVirtualIP()){
        //     if (!setVirtualIP()){
        //      setStatusDisconnected(__LINE__);
        //      return;
        //     }
        //    }



        if (useL2tpAfterFirstConnection)
            l2tpPrepare();

        IpsecPhase1Up = false;
        IpsecPhase2Up = false;


        //    startStopIpsec(false);
        QStringList args;
        if (m_toolIsOpenSwan) {

            debugMessage(0, "[" + IpsecType + "] " + i18n("Starting ipsec setup..."));

            args.append("setup");
            args.append("start");
        }
        if (m_toolIsStrongSwan /*&&  ( (IpsecMajor >= 4 && IpsecMinor >= 2 && IpsecSubMinor >=2 ) || IpsecMajor > 4 )*/) {
            //      logMessage ( "[" + IpsecType + "] " + i18n ( "Starting [strongswan] starter in foreground..." ), KVpncEnum::debug );
            debugMessage(0, "[" + IpsecType + "] " + i18n("Starting ipsec..."));


            //args.append( "starter" );
            //args.append ( "--nofork");
            //QFile("/var/run/pluto.pid").remove();
            //QFile("/var/run/starter.pid").remove();
            //args.append( "setup" );
            args.append("start");
        }

        IpsecGotError = false;

        IpsecStartProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                              SLOT(readFromStdout_ipsec()),
                                              SLOT(readFromStderr_ipsec()),
                                              SLOT(ipsecStarted(int, QProcess::ExitStatus)), 0);
        if (!IpsecStartProcess || !IpsecStartProcess->start()) {
            reportError(i18n("Failed to start \"%1\"." , QString("ipsec (" + IpsecType + "): setup")));
            errorLine = __LINE__;
        } else {
            IpsecStartProcess->waitForFinished(3000000);
            delete IpsecStartProcess;
            IpsecStartProcess = 0L;

            //     if (currentConnectCounter > 500)
            //     {
            //      if ( GlobalConfig->KvpncDebugLevel >3 )
            //       if (IpsecToolInfo->Version.contains ( "strongSwan", Qt::CaseInsensitive ))
            //        logMessage ( i18n ( "\"%1\" still running but needs too long, stopping" , QString( "ipsec start" )) , KVpncEnum::debug );
            //       else
            //        logMessage ( i18n ( "\"%1\" still running but needs too long, stopping" , QString( "ipsec setup start" )) , KVpncEnum::debug );
            //      setStatusDisconnected(__LINE__);
            //      return;
            //     }
            //                     ipsecStarted(0,0);
        }
    }

    if (!errorLine) {
        debugMessage(0, i18n("Trying to connect to server \"%1\" (%2) with user \"%3\" and IPSec ID \"%4\"...\n" , QString(GlobalConfig->currentProfile->getGateway()), GlobalConfig->TmpGatewayIP , GlobalConfig->currentProfile->getUserName() , GlobalConfig->currentProfile->getID()));
    } else {
        errorMessage(i18n("Error at line %1.", errorLine));
    }
    return 0 == errorLine;
}

void IpsecHandler::vpnStop()
{
    // iptables need the right interface (eth0:1 => eth0)
    QString tmpInterface2 = "";
    int pointPos = tmpInterface.indexOf(QChar(':'), 0, Qt::CaseInsensitive);
    if (pointPos > 1) {
        tmpInterface2 = tmpInterface.left(pointPos);
    } else
        tmpInterface2 = tmpInterface;

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
        //      if (QFile("/var/run/l2tpd.pid").exists())
        //      {
        //       if (GlobalConfig->KvpncDebugLevel > 1)
        //        errorMessage(i18n("Using control interface for disconnecting l2tp connection"),KVpncEnum::debug);
        //       QFile L2tpdControlFile ( "/var/run/l2tp-control" );
        //       QTextStream stream( &L2tpdControlFile );
        //       if ( L2tpdControlFile.open( QIODevice::WriteOnly  ) ) {
        //        stream << "d " << GlobalConfig->currentProfile->getName() << "\n";
        //        L2tpdControlFile.close();
        //       }
        //     }
        //      else
        l2tpStop();
    }

    IpsecWhackStatusTimer.stop();

    if (GlobalConfig->currentProfile->getUseLeftSourceIp()) {
        debugMessage(3,  i18n ( "Removing virtual IP address" ) );
        doAddRemoveVirtualIp("del");
    }

    putenv((char*)("LC_ALL=C"));
    QStringList args;
    args.append("whack");
    args.append("--name");
    args.append(GlobalConfig->currentProfile->getName());
    args.append("--delete");

    IpsecWhackDeleteProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
            SLOT(readFromStdout_ipsecwhackdelete()),
            SLOT(readFromStderr_ipsecwhackdelete()),
            0, 0);
    if (!IpsecWhackDeleteProcess || !IpsecWhackDeleteProcess->start()) {
        reportError(i18n("Failed to start \"%1\"." , QString(GlobalConfig->pathToIpsec + " whack' --name " + GlobalConfig->currentProfile->getName() + " --delete")));

    } else {
        debugMessage(0, i18n("\"%1\" started.", QString(GlobalConfig->pathToIpsec + " whack --name " + GlobalConfig->currentProfile->getName() + " --delete")));
        IpsecWhackDeleteProcess->waitForFinished(100000);
        delete IpsecWhackDeleteProcess;
        IpsecWhackDeleteProcess = 0L;
    }

    // prevent old logs...
    IpsecGotError = true;
    args.clear();
    if (!IpsecType.contains("strongSwan", Qt::CaseInsensitive)) {
        args.append("setup");
        args.append("stop");
    }
    if (! IpsecType.contains("free", Qt::CaseInsensitive) && m_tool.actualIsGe("4.2.2")) {
        args.append("stop");
    }

    IpsecStartProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                          SLOT(readFromStdout_ipsec()),
                                          SLOT(readFromStderr_ipsec()),
                                          0, 0);
    if (!IpsecStartProcess || !IpsecStartProcess->start()) {
        if (!IpsecType.contains("strongSwan", Qt::CaseInsensitive)) {
            reportError(i18n("Failed to start \"%1\"." , QString("ipsec setup stop")));

        }
        if (! IpsecType.contains("free", Qt::CaseInsensitive) && m_tool.actualIsGe("4.2.2")) {
            reportError(i18n("Failed to start \"%1\"." , QString("ipsec stop")));

        }
    } else {
        //                 int tryCounter = 0;
        //     while (IpsecStartProcess != 0L && IpsecStartProcess->state() == QProcess::Running) {
        //                     tryCounter++;
        //                     if (tryCounter == 20) {
        //                         tryCounter = 0;
        //                         if (GlobalConfig->KvpncDebugLevel > 8) {
        //        if (!IpsecType.contains("strongSwan", Qt::CaseInsensitive))
        //                                 debugMessage(i18n("\"%1\" is still running, waiting for it to terminate..." , QString("ipsec setup stop")));
        //        if (IpsecType.contains("strongSwan", Qt::CaseInsensitive) && ((IpsecMajor >= 4 && IpsecMinor >= 2 && IpsecSubMinor >= 2) || IpsecMajor > 4))
        //                                 debugMessage(i18n("\"%1\" is still running, waiting for it to terminate...", QString("ipsec stop")));
        //                         }
        //                     }
        //                     usleep(100);
        //                 }
        //                      if (GlobalConfig->appPointer->hasPendingEvents())
        //                          GlobalConfig->appPointer->processEvents();
        IpsecStartProcess->waitForFinished(100000);
        delete IpsecStartProcess;
        IpsecStartProcess = 0L;
    }

    delRouteIpsec();
    removeIptablesFreeswan();

    debugMessage(0,  i18n ( "Restoring original ipsec settings" ) );


    // restore system files
    QString IpsecPrefix = "/etc";
    // ipsec.conf
    QFile originalIpsecConfFile("/etc/ipsec.conf.before.kvpnc");
    QTextStream stream(&originalIpsecConfFile);
    QString originalIpsecConfFileContent = "";

    if (originalIpsecConfFile.exists()) {
        if (originalIpsecConfFile.open(QIODevice::ReadOnly)) {
            originalIpsecConfFileContent = QString(originalIpsecConfFile.readAll());
            originalIpsecConfFile.close();
        }
    }

    QFile backupOriginalIpsecConfFile("/etc/ipsec.conf");
    stream.setDevice(&backupOriginalIpsecConfFile);
    if (backupOriginalIpsecConfFile.open(QIODevice::WriteOnly)) {
        stream << originalIpsecConfFileContent;
        backupOriginalIpsecConfFile.close();
    }
    stream.setDevice(0);

    //if ( GlobalConfig->KvpncDebugLevel > 0 )
    // debugMessage( i18n( "%1 found in %2, assuming %3 as prefix for %4." , QString( "ipsec.conf.before.kvpnc" , IpsecPrefix , IpsecPrefix ,  IpsecType ) );

    // ipsec.secret
    QFile originalIpsecSecretFile("/etc/ipsec.secrets.before.kvpnc");
    stream.setDevice(&originalIpsecSecretFile);
    QString originalIpsecSecretFileContent = "";
    if (originalIpsecSecretFile.open(QIODevice::ReadOnly)) {
        originalIpsecSecretFileContent = QString(originalIpsecSecretFile.readAll());
        originalIpsecSecretFile.close();
    }

    QFile backupOriginalIpsecSecretFile("/etc/ipsec.secrets");
    stream.setDevice(&backupOriginalIpsecSecretFile);
    if (backupOriginalIpsecSecretFile.open(QIODevice::WriteOnly)) {
        stream << originalIpsecSecretFileContent;
        backupOriginalIpsecSecretFile.close();
    }
    stream.setDevice(0);

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
        pppdSecretsRemove();
    }

// start ipsec with restored config again
//    startStopIpsec(true);
    startStopIpsec(false, false);
}

bool IpsecHandler::getAuthenticationData(bool AuthRetry)
{

    if (GlobalConfig->currentProfile->authtype == VpnAccountData::cert) {
        if (!GlobalConfig->currentProfile->getUseSmartcard()) {
            QFile CertTmpFile;
            CertTmpFile.setFileName(GlobalConfig->currentProfile->getX509Certificate());
            if (!CertTmpFile.exists()) {
                reportError(i18n("Certificate file (%1) could not be found. Please check its path." , GlobalConfig->currentProfile->getCertPath()), i18n("File Not Found"));
                return false;
            }
        }

        QFile CertTmpFile;
        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"));
            return false;
        }
    }

    bool askUsernamePass = false;
    bool askPsk = false;

    if (!GlobalConfig->haveUserData) {
        if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk && (GlobalConfig->currentProfile->getSavePsk() == false || GlobalConfig->currentProfile->getPreSharedKey().isEmpty()) && GlobalConfig->currentProfile->getAllowEmptyPrivateKeyPassword() == false) {
            askUsernamePass = false;
            askPsk = true;
        }
    }

    // L2TP/XAUTH
    if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
        GlobalConfig->TmpUsername = GlobalConfig->currentProfile->getUserName();
        GlobalConfig->TmpPassword = GlobalConfig->currentProfile->getUserPassword();

        if (GlobalConfig->TmpPassword.isEmpty() || GlobalConfig->TmpUsername.isEmpty())
            askUsernamePass = true;

        if (!GlobalConfig->currentProfile->getPskIsInFile())
            GlobalConfig->TmpGroupPassword = GlobalConfig->currentProfile->getPreSharedKey();
        else {
            QFile PskFile(GlobalConfig->currentProfile->getPreSharedKeyFile());
            if (PskFile.open(QIODevice::ReadOnly)) {
                QString PskFileContent = QString(PskFile.readAll());
                PskFile.close();
                GlobalConfig->TmpGroupPassword = PskFileContent;
            }
        }
        GlobalConfig->WaitingForXauth = false;
    }

    if (AuthRetry)
        askUsernamePass = true;

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

        askUsernamePass = true;
    }

    if (!GlobalConfig->haveUserData) {

        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan && ((!GlobalConfig->currentProfile->getSaveUserPassword() && GlobalConfig->currentProfile->getUserName().isEmpty()) || GlobalConfig->currentProfile->getUserPassword().isEmpty()))
            askUsernamePass = true;
    } else {
        debugMessage(4, i18n("User data already collected."));
    }

    if (askUsernamePass || askPsk) {
        bool requestUsername = false;
        EnterUsernamePasswordDialog dlg(gui, i18n("Enter Account Data"), askPsk, askUsernamePass);
        if (askUsernamePass) {
            requestUsername = GlobalConfig->TmpUsername.isEmpty();

            if (!GlobalConfig->TmpUsername.isEmpty()) {
                dlg.UsernameEdit->setText(GlobalConfig->TmpUsername);
                if (!GlobalConfig->currentProfile->getDontSaveUsername())
                    dlg.SaveUsernameCheckBox->setChecked(true);
            } else
                dlg.UsernameEdit->setFocus();
            dlg.LabelGroupPassword->setText(i18n("PSK:"));

            if (!GlobalConfig->TmpPassword.isEmpty()) {
                dlg.PasswordEdit->setText(GlobalConfig->TmpPassword);
                if (GlobalConfig->currentProfile->getSaveUserPassword())
                    dlg.SaveUsernameCheckBox->setChecked(true);
            } else if (!GlobalConfig->TmpUsername.isEmpty())
                dlg.PasswordEdit->setFocus();
        } else {
            GlobalConfig->TmpUsername = GlobalConfig->currentProfile->getUserName();
            GlobalConfig->TmpPassword = GlobalConfig->currentProfile->getUserName();
        }
        if (askPsk) {
            if (!GlobalConfig->currentProfile->getPreSharedKey().isEmpty()) {
                dlg.PSKLineEdit->setText(GlobalConfig->currentProfile->getPreSharedKey());
                if (GlobalConfig->currentProfile->getSavePsk())
                    dlg.SavePskCheckBox->setChecked(true);
            } else if (!GlobalConfig->currentProfile->getUserPassword().isEmpty())
                dlg.PSKLineEdit->setFocus();
            if (!askUsernamePass) {
                dlg.PasswordEdit->hide();
                dlg.UsernameEdit->hide();
                dlg.LabelPassword->hide();
                dlg.LabelUsername->hide();
                dlg.SavePasswordCheckBox->hide();
                dlg.SaveUsernameCheckBox->hide();
            } else {
                GlobalConfig->TmpUsername = GlobalConfig->currentProfile->getUserName();
                GlobalConfig->TmpPassword = GlobalConfig->currentProfile->getUserName();
            }
        } else {
            dlg.LabelGroupPassword->hide();
            dlg.PSKLineEdit->hide();
        }

        //     dlg.SaveValuesCheckBox->setChecked( GlobalConfig->currentProfile->getSaveUserPassword() || !GlobalConfig->currentProfile->getDontSaveUsername() );

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

            // FIXME
            if (askPsk || AuthRetry) {
                if ((GlobalConfig->currentProfile->getSavePsk() && GlobalConfig->currentProfile->getPreSharedKey().isEmpty()) && GlobalConfig->TmpGroupPassword.isEmpty()) {
                    errorMessage(i18n("PSK is empty."));
                    return false;
                }
            }

            bool needSave = false;

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

                    if (!GlobalConfig->currentProfile->getPskIsInFile()) {
                        GlobalConfig->currentProfile->setPreSharedKey(GlobalConfig->TmpGroupPassword);
                        needSave = true;
                    }
                    else {
                        QFile PskFile(GlobalConfig->currentProfile->getPreSharedKeyFile());
                        if (PskFile.open(QIODevice::WriteOnly)) {
                            QTextStream stream(&PskFile);
                            stream << GlobalConfig->TmpGroupPassword;
                            PskFile.close();
                        }
                    }

                } else {
                    GlobalConfig->currentProfile->setSavePsk(false);
                    needSave = true;
                }
            }

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

            //     if ( /*GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert && */GlobalConfig->currentProfile->getUseMailAddressAsIdentifier() && Utils( GlobalConfig ).getEmailAddressOfCert( GlobalConfig->currentProfile->getX509Certificate()).isEmpty())
            //     {
            //      errorMessage( i18n( "Mail address could not read from certificate!" ) );
            //      ok = false;
            //     }

            debugMessage(0, i18n("Some account data which was needed was obtained from a password dialog."));
            //      saveSessionClicked();
        }
        GlobalConfig->haveUserData = true;
    } else {
        AuthRetry = false;
        debugMessage(0, i18n("Connect canceled because account data dialog aborted."));
        return false;
    }


    if (GlobalConfig->currentProfile->getPskIsInFile()) {
        QFile f(GlobalConfig->currentProfile->getPreSharedKeyFile());
        if (f.open(QIODevice::ReadOnly)) {
            QStringList contentlist = QString(f.readAll()).split("\n");
            for (int i = 0; i < contentlist.size(); ++i) {
                QString line = contentlist.at(i);
                if (!line.indexOf(QChar('#'), 0, Qt::CaseInsensitive) < 0) {
                    GlobalConfig->TmpGroupPassword = line;
                    break;
                }
            }
            f.close();
        } else {
            errorMessage(i18n("PSK could not read from file because PSK key file %1 could not be read." , GlobalConfig->currentProfile->getPreSharedKeyFile()));
            return false;
        }
        if (GlobalConfig->TmpGroupPassword.isEmpty()) {
            errorMessage(i18n("PSK could not read from file because PSK key file %1 contains no key." , GlobalConfig->currentProfile->getPreSharedKeyFile()));
            return false;
        }
    }

    if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert && GlobalConfig->currentProfile->getUseSmartcard()) {
        GlobalConfig->TmpPassword = "";
        QByteArray password;
        QString pass = "";
        Pkcs11PIN = "";

        GlobalConfig->TmpPrivateKeyPass = "";
        EnterXauthInteractivePasscodeDialog dlg(0);
        dlg.setWindowTitle( i18n("Enter smartcard PIN"));
        dlg.main->DescriptionLabel->setText(i18n("Enter PIN for unlocking smartcard \"%1\":" , GlobalConfig->currentProfile->getPkcs11Slot()));
        dlg.main->LabelPassword->setText(i18n("PIN:"));
        dlg.main->SavePasswordCheckBox->hide();
        dlg.adjustSize();
        debugMessage(1, "[ipsec] " + i18n("PIN for unlocking smartcard requested...\n"));
        if (dlg.exec()) {

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

                debugMessage(1, "[ipsec]: " + i18n("PIN got from user"));


                GlobalConfig->TmpPrivateKeyPass = QString(pass);
                Pkcs11PIN = GlobalConfig->TmpPrivateKeyPass;
            } else {
                errorMessage("[ipsec]: PIN empty, stop.");
                return false;
            }
        } else {
            debugMessage(0, "[ipsec]: password dialog canceled and password empty, stop.");
            return false;
        }
    }
    return true;
}

void IpsecHandler::readFromStdout_ipsec()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecStartProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        bool NormalMsg = true;
        bool ErrorMsg = false;

        if (pingtest) {
            //   if ( GlobalConfig->KvpncDebugLevel > 0 )
            //    mw->DebugOutput->append( "raw out (pingtest): " + msg );

            if (msg.indexOf("time=", 0, Qt::CaseInsensitive) > -1) {
                successMessage("[ping] " + msg);
            } else if (msg.indexOf("100 % packet loss", 0, Qt::CaseInsensitive) > -1) {
                NormalMsg = false;
                errorMessage("[ping err] " + msg);
            } else {
                if (msg.indexOf("Destination Host Unreachable", 0, Qt::CaseInsensitive) > -1) {
                    NormalMsg = false;
                    reportError(i18n("Destination host is unreachable."));

                }
            }
        } else {
            // FATAL ERROR:
            if (msg.indexOf("failed to bind", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("Address already in use", 0, Qt::CaseInsensitive) > -1) {
                QString NameAndPid = Utils(GlobalConfig).getNameAndPidOfProgramListen(500);
                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);
                    reportError(i18n("Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString().setNum(500) , Name , QString().setNum(pid)));
                } else
                    reportError(i18n("Port binding failed"));

                errorLine = __LINE__;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            } else if ( msg.indexOf ( "error fetching interface information: Device not found", 0, Qt::CaseInsensitive ) > -1 ) {
                QString interfacemissing = msg.section(" ", 1,1).replace(':', "");
                reportError(i18n ( "Specified network device (%1) does not exist. Please specify an existing device or default at settings.", interfacemissing) );
                errorLine = __LINE__;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            } else if (msg.indexOf("apguily already active", 0, Qt::CaseInsensitive) > -1 ||  msg.indexOf("ipsec_setup: Openswan IPsec apguily already active, start aborted", 0, Qt::CaseInsensitive) > -1) {
                //    KMessageBox::error ( gui, i18n ( "Unsupported card found. Please use a smartcard with openct support. This is a Openswan limitation, sorry." ) );
                debugMessage(0, i18n("Openswan seems still running, restart it.") );
                //    errorLine = __LINE__;
                startStopIpsec(true);
                sleep(5);
                startStopIpsec();
                if ( !IpsecGotError)
                    ipsecStarted(0,QProcess::NormalExit);
            }

            else if (msg.indexOf("no default route, %defaultroute cannot cope!!!", 0, Qt::CaseInsensitive) > -1) {
                reportError(i18n("No default route found, necessary for %1." , IpsecType));

                errorLine = __LINE__;
                ErrorMsg = true;
            }
        }

        // normal
        if (NormalMsg) {
            debugMessage(1, "[ipsec] " + msg);
            //   if (GlobalConfig->KvpncDebugLevel > 0)
            //    debugMessage( "out: " + ProcessMsg_connect );
        } else if (ErrorMsg) {
            errorMessage("[ipsec err] " + msg);
        }

        if (errorLine) {
            debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("l2tpd")) );
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStderr_ipsec()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecStartProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        if (msg.indexOf("failed to bind", 0, Qt::CaseInsensitive) > -1 ||  msg.indexOf("FATAL ERROR: bind() failed in find_raw_ifaces(). Errno 98: Address already in use", 0, Qt::CaseInsensitive) > -1) {
            QString NameAndPid = Utils(GlobalConfig).getNameAndPidOfProgramListen(500);
            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);
                reportError(i18n("Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString().setNum(500) , Name , QString().setNum(pid)));
            } else
                reportError(i18n("Port binding failed"));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("no default route, %defaultroute cannot cope!!!", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("No default route found, necessary for %1." , IpsecType));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("SIOCADDRT: File exists", 0, Qt::CaseInsensitive) > -1) {
            //   errorMessage( "[ipsec err] "+i18n( "setting route failed: route still exists" ) );
            //   abort=true;
        } else if (msg.indexOf("SIOCDELRT: File exists", 0, Qt::CaseInsensitive) > -1) {
            errorMessage("[ipsec err] " + i18n("deleting route failed: route does not exist"));
            errorLine = __LINE__;
        } else if (msg.indexOf("we only support version 2", 0, Qt::CaseInsensitive) > -1) {
            errorMessage("[ipsec err] " + i18n("Only freeswan version 2.x is supported ."));
            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        }

        else if (msg.indexOf("error loading RSA private key file", 0, Qt::CaseInsensitive) > -1) {
            errorMessage("[ipsec err] " + i18n("RSA private key file could not be loaded."));
            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("unable to start strongSwan -- fatal errors in config", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("Unable to start strongSwan -- fatal errors in config. Please contact the KVpnc author."), "[ipsec err]");
            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("Starting strongSwan", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, "[ipsec] " + msg);
        } else if (msg.indexOf("apguily already active", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("Openswan IPsec apguily already active, start aborted", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error ( gui, i18n ( "Unsupported card found. Please use a smartcard with openct support. This is an Openswan limitation, sorry." ) );
            errorMessage(i18n("Openswan seems to be still running, restart it."));
            //    errorLine = __LINE__;
            startStopIpsec(true);
            sleep(5);
            startStopIpsec();
            if ( !IpsecGotError)
                ipsecStarted(0,QProcess::NormalExit);
        } else if (pingtest) {
            // mw->DebugOutput->append( "raw err (pingtest): " + ProcessMsg_connect );
            if (msg.indexOf("time=", 0, Qt::CaseInsensitive) > -1) {
                successMessage("[ping] " + msg);
            } else if (msg.indexOf("100 % packet loss", 0, Qt::CaseInsensitive) > -1) {
                errorMessage("[ping err] " + msg);
            } else {
                if (msg.indexOf("failed to bind", 0, Qt::CaseInsensitive) > -1) {
                    reportError(i18n("Binding interface failed."));

                }
                if (msg.indexOf("Destination Host Unreachable", 0, Qt::CaseInsensitive) > -1) {
                    reportError(i18n("Destination host is unreachable."), i18n("Binding interface failed."));
                }
            }
        } else {
            errorMessage("[ipsec err] " + msg);
        }

        if (errorLine) {
            debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("l2tpd")) );
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStdout_ipsecwhack()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecWhackProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        bool NormalMsg = true;
        bool ErrorMsg = false;

        if (msg.indexOf("encountered fatal error in state STATE_XAUTH", 0, Qt::CaseInsensitive) > -1) {
            // xauth failed openswan
            ErrorMsg = true;
            reportError(i18n("Authentication failed (%1).", QString(i18n("XAUTH"))));

            reason = DISCONNECTION_REASON_AUTHENTICATION_FAILED;
            errorLine = __LINE__;
        } else if (msg.indexOf("extended authentication failed", 0, Qt::CaseInsensitive) > -1 || (GlobalConfig->WaitingForXauth == true && msg.indexOf("expected ISAKMP_CFG_SET, got ISAKMP_CFG_REQUEST", 0, Qt::CaseInsensitive) > -1)) {
            // xauth failed strongswan
            reportError(i18n("Authentication failed (%1).", QString(i18n("XAUTH"))));

            reason = DISCONNECTION_REASON_AUTHENTICATION_FAILED;
            errorLine = __LINE__;
        } else if (msg.indexOf("Can't authenticate: no preshared key found", 0, Qt::CaseInsensitive) > -1) {
            ErrorMsg = true;
            reportError(i18n("Preshared key not found for connection."));
            errorLine = __LINE__;

        } else if (msg.indexOf("prompt for Username:", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(1, i18n("XAUTH username requested, send it...") );

            debugMessage(5, i18n("XAUTH username: %1" , QString(GlobalConfig->TmpUsername)) );

            IpsecWhackProcess->write(GlobalConfig->TmpUsername.toUtf8());
            IpsecWhackProcess->write("\n");
        } else if (msg.indexOf("prompt for Password:", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(1, i18n("XAUTH password requested, send it...") );
            debugMessage(5, i18n("XAUTH password: %1" , QString(GlobalConfig->TmpPassword)) );

            IpsecWhackProcess->write(GlobalConfig->TmpPassword.toUtf8());
            IpsecWhackProcess->write("\n");
        } else if (msg.indexOf("listening for IKE messages", 0, Qt::CaseInsensitive) > -1) {
            // strongswan after ipsec whack --listen
            /*   disconnect ( IpsecWhackProcess, SIGNAL ( readyReadStandardOutput() ), gui, SLOT ( readFromStdout_ipsecwhack() ) );
               disconnect ( IpsecWhackProcess, SIGNAL ( readyReadStandardError() ), gui, SLOT ( readFromStderr_ipsecwhack() ) );
               delete IpsecWhackProcess;*/
            putenv((char*)("LC_ALL=C"));
            QStringList args;
            args.append("whack");
            args.append("--name");
            args.append(GlobalConfig->currentProfile->getName());
            args.append("--initiate");

            IpsecWhackProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                                  SLOT(readFromStdout_ipsecwhack()),
                                                  SLOT(readFromStderr_ipsecwhack()),
                                                  0, SLOT(ipsecwhack_exited(int, QProcess::ExitStatus)));
            if (!IpsecWhackProcess) {
                reportError(i18n("Failed to start \"%1\"." , QString(GlobalConfig->pathToIpsec + " whack' --name " + GlobalConfig->currentProfile->getName() + " --initiate")));

                errorLine = __LINE__;
            } else {
                debugMessage(0, i18n("\"%1\" started.", QString(GlobalConfig->pathToIpsec + " whack --name " + GlobalConfig->currentProfile->getName() + " --initiate")));
            }
        } else if (msg.indexOf("added connection", 0, Qt::CaseInsensitive) > -1) {
//    XAUTH
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                if (m_toolIsOpenSwan) {
                    sleep(3);
                    //openswan
                    putenv((char*)("LC_ALL=C"));
                    QStringList args;
                    args.append("whack");
                    args.append("--name");
                    args.append(GlobalConfig->currentProfile->getName());
                    args.append("--initiate");

                    QString LogPassword = "";
                    if (GlobalConfig->KvpncDebugLevel > 5)
                        LogPassword = GlobalConfig->TmpPassword;
                    else
                        LogPassword = "*****";
                    IpsecWhackProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                                          SLOT(readFromStdout_ipsecwhack()),
                                                          SLOT(readFromStderr_ipsecwhack()),
                                                          0, SLOT(ipsecwhack_exited(int, QProcess::ExitStatus)));
                    if (!IpsecWhackProcess || !IpsecWhackProcess->start()) {
                        reportError(i18n("Failed to start \"%1\".", QString(GlobalConfig->pathToIpsec + " whack' --name " + GlobalConfig->currentProfile->getName() + " --initiate")));

                        errorLine = __LINE__;
                    } else {
                        debugMessage(0, i18n("\"%1\" started." , QString(GlobalConfig->pathToIpsec + " whack --name " + GlobalConfig->currentProfile->getName() + " --initiate")));
                    }
                }
            }

        } else if (msg.indexOf("XAUTH: Successfully Authenticated", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, i18n("Authentication succeeded.") );
        } else if (msg.indexOf("parsing XAUTH status", 0, Qt::CaseInsensitive) > -1) {
            GlobalConfig->WaitingForXauth = true;
        } else if (msg.indexOf("added connection", 0, Qt::CaseInsensitive) > -1) {
//    XAUTH
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan && GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                if (m_toolIsOpenSwan) {
                    sleep(3);
                    //openswan
                    putenv((char*)("LC_ALL=C"));
                    QStringList args;
                    args.append("whack");
                    args.append("--name");
                    args.append(GlobalConfig->currentProfile->getName());
                    args.append("--initiate");

                    QString LogPassword = "";
                    if (GlobalConfig->KvpncDebugLevel > 5)
                        LogPassword = GlobalConfig->TmpPassword;
                    else
                        LogPassword = "*****";
                    IpsecWhackProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                                          SLOT(readFromStdout_ipsecwhack()),
                                                          SLOT(readFromStderr_ipsecwhack()),
                                                          0, SLOT(ipsecwhack_exited(int, QProcess::ExitStatus)));
                    if (!IpsecWhackProcess || !IpsecWhackProcess->start()) {
                        reportError(i18n("Failed to start \"%1\".", QString(GlobalConfig->pathToIpsec + " whack' --name " + GlobalConfig->currentProfile->getName() + " --initiate")));

                        errorLine = __LINE__;
                    } else {
                        debugMessage(0, i18n("\"%1\" started." , QString(GlobalConfig->pathToIpsec + " whack --name " + GlobalConfig->currentProfile->getName() + " --initiate")));
                    }
                }
            }

        } else if ( msg.indexOf ("ISAKMP SA established", 0, Qt::CaseInsensitive ) > -1 ) {
            if (IpsecPhase2Up)
                return;

            if (IpsecPhase1Up)
                return;
            else
                IpsecPhase1Up=true;

            IpsecWhackStatusTimer.stop();
            errorLine = __LINE__;
            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan ) {
                debugMessage (1, "[ipsec] " + i18n ( "IPSec phase 1 established." ));
            }
            else if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan ) {
                debugMessage (1, "[ipsec] " + i18n ( "Low level IPsec phase 1 established." ));
            }
        } else if (msg.indexOf("IPsec SA established", 0, Qt::CaseInsensitive) > -1) {
            ipsecPhase2Established();
        } else if (msg.indexOf("XAUTH: Successfully Authenticated", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, i18n("Authentication succeeded.") );
        } else if (msg.indexOf("apguily already active", 0, Qt::CaseInsensitive) > -1) {
//    KMessageBox::error ( gui, i18n ( "Openswan seems still running, restart it." ) );
            debugMessage(0, i18n("Openswan seems still running, restart it.") );
//       abort = true;
            startStopIpsec(true);
            sleep(5);
            startStopIpsec();
            if ( !IpsecGotError)
                ipsecStarted(0,QProcess::NormalExit);
        } else if (msg.indexOf("no default route, %defaultroute cannot cope!!!", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("No default route found, necessary for %1." , QString(IpsecType)));

            errorLine = __LINE__;
            ErrorMsg = true;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("ignoring informational payload, type NO_PROPOSAL_CHOSEN", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer reported wrong connection parameters used. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("perhaps peer likes no proposal", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer reported wrong connection parameters used. Please verify in IPSec settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("INVALID_ID_INFORMATION", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer refused ID settings. Please verify the local ID in IPsec and remote network in Network - General settings."));

                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("cannot initiate connection with ID wildcards", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Cannot initiate connection with ID wildcards. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf(QString("Can not opportunistically initiate"), 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Cannot opportunistically initiate. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("unable to locate my private key", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("Private key could not be found. Please check certificate settings."));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("SMARTCARD support is deactivated in pluto/Makefile", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("Smartcard not supported", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("SMARTCARD support is deactivated. Please enable smartcard support in %1 package" , QString(IpsecType)));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("Unsupported card", 0, Qt::CaseInsensitive) > -1 &&  msg.indexOf("pkcs15", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("Unsupported card found. Please use a smartcard with openct support. This is a Openswan limitation, sorry."));

            errorLine = __LINE__;
        } else if (msg.indexOf("we require peer to have ID", 0, Qt::CaseInsensitive) > -1 && msg.indexOf("but peer declares", 0, Qt::CaseInsensitive) > -1) {
            QString PeerID = msg.section('\'', 3, 3);
            QString OurID = msg.section('\'', 1, 1);
            reportError(i18n("Wrong ID \"%1\" from peer, expected \"%2\"." , QString(PeerID), OurID));

            int result = KMessageBox::questionYesNo(gui, i18n("Do you want to use \"%1\" instead of \"%2\" as remote ID and reconnect?", QString(PeerID), OurID), i18n("Fix remote ID?"));
            if (result == 3) { // Yes
                GlobalConfig->currentProfile->setUseSpecialRemoteID(true);
                GlobalConfig->currentProfile->setSpecialRemoteID(PeerID);
                GlobalConfig->currentProfile->setRemoteIDType("user");
                errorLine = __LINE__;
                reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
            } else {
                if (!stopContinue) {

                    errorLine = __LINE__;
                    stopContinue = true;
                }
            }
        }
        else if ( msg.indexOf( "no connection named", 0 , Qt::CaseInsensitive ) > -1 )
        {
            reportError(i18n ( "Connection not found. This seems like the configuration is invalid or too fast connect/disconnect." ) );

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        }
        else if ( msg.indexOf( "deleting state (STATE_QUICK_I1)", 0 , Qt::CaseInsensitive ) > -1 || msg.indexOf( "deleting state (STATE_MAIN_I3)", 0 , Qt::CaseInsensitive ) > -1  || msg.indexOf( "deleting state (STATE_MAIN_I2)", 0 , Qt::CaseInsensitive ) > -1  )
        {
            //KMessageBox::error ( gui, i18n ( "Phase 1 was deleted. Disconnecting." );
            errorMessage ( i18n ( "Phase 1 was deleted. Disconnecting." ));
            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        }


        // normal
        if (NormalMsg) {
            debugMessage(1, "[ipsec whack] " + msg);
            //   if (GlobalConfig->KvpncDebugLevel > 0)
            //    debugMessage( "out: " + msg );
        } else if (ErrorMsg) {
            errorMessage("[ipsec whack err] " + msg);
        }

        if (errorLine) {
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStderr_ipsecwhack()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecWhackProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        bool ErrorMsg = false;

        errorMessage("[ipsec whack err] " + msg);

        //   // binding to port failed
        //   if ( msg.indexOf ( "ERROR: failed to bind to address", 0, Qt::CaseInsensitive ) > -1 )
        //   {

        //    if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_ipsec )
        //    {
        //     if (IpsecProcess != 0 && IpsecProcess->state() == QProcess::Running)
        //      IpsecProcess->kill();
        //    }
        //
        //    if (GlobalConfig->doKillIpsecIfStillRunning)
        //    {
        //      QProcess killipsecprocess(gui);
        //      QStringList args;
        //      args.append(GlobalConfig->pathToKillall);
        //      args.append("ipsec");
        //      killipsecprocess.setEnvironment(*env);
        //      killipsecprocess.start(proc,args);
        //      if (!killipsecprocess.waitForStarted())
        //      {
        //       errorMessage( i18n( "%1 could not be killed." ,"ipsec") ,KVpncEnum::error);
        //       logMessage ( QString( "[ipsec err] " + i18n( "Bind to given port has been failed. Another %1 process is running. Please stop %1 first." ,"ipsec") ) , KVpncEnum::debug );
        //       errorLine = __LINE__;
        //      }
        //      else
        //      {
        //       killipsecprocess.waitForFinished();
        //
        //       // restart ipsec
        // //       if ( IpsecProcess != 0)
        // //        IpsecProcess->kill();
        //
        //
        //       putenv( ( char* ) ( "LC_ALL=C" ) );
        //       IpsecProcess = new QProcess( this );
        //  QString proc = GlobalConfig->pathToIpsec ;
        //  QStringList args;
        //      args.append( "-F" ); // foreground we want :)
        //      args.append( "-f" );
        //      args.append( tmpPath + "ipsec." + GlobalConfig->currentProfile->getName() + ".conf" );
        //      args.append( "-l" ); // logfile (we get content with tail process)
        //      args.append( tmpPath + "ipsec." + GlobalConfig->currentProfile->getName() + ".log" );
        //       if ( GlobalConfig->KvpncDebugLevel > 0 )
        //        logMessage ( "ipsec: " + GlobalConfig->pathToIpsec + " -f " + tmpPath + "/ipsec" + GlobalConfig->currentProfile->getName() + ".conf", KVpncEnum::debug );
        //
        //  IpsecProcess->setEnvironment(*env);
        //  IpsecProcess->start(proc,args);
        //       if ( !IpsecProcess->waitForFinished() )
        //       {
        //        if ( GlobalConfig->KvpncDebugLevel > 0 )
        //         logMessage ( i18n( "Failed to start \"%1\"." ,QString("l2tpd")), KVpncEnum::error );
        //
        //        logMessage ( QString( "[ipsec err] " + i18n( "Bind to given port has been failed. Another %1 process is running. Please stop %1 first." ,"ipsec") ) , KVpncEnum::debug );
        //        abort=false;
        //       }
        //       else
        //       {
        //        if ( GlobalConfig->KvpncDebugLevel > 0 )
        //         logMessage ( i18n( "%1 was already running. It was killed and restarted." ,QString("ipsec")), KVpncEnum::debug );
        //       }
        //      }
        //    }
        //    else
        //    {
        //     KMessageBox::error ( gui, i18n ( "Port binding failed" ) );
        //     logMessage ( i18n ( "Port binding failed" ) , KVpncEnum::error );
        //     errorLine = __LINE__;
        //    }
        //   }


        if (msg.indexOf("failed to bind", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("Address already in use", 0, Qt::CaseInsensitive) > -1) {
            QString NameAndPid = Utils(GlobalConfig).getNameAndPidOfProgramListen(500);
            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);
                reportError(i18n("Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString().setNum(500) , Name , QString().setNum(pid)));
            } else
                reportError(i18n("Port binding failed"));

            errorLine = __LINE__;
        }

        else if (msg.indexOf("no default route, %defaultroute cannot cope!!!", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("No default route found, necessary for %1.", QString(IpsecType)));

            errorLine = __LINE__;
            ErrorMsg = true;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("ignoring informational payload, type NO_PROPOSAL_CHOSEN", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer reported wrong connection parameters used. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("perhaps peer likes no proposal", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer reported wrong connection parameters used. Please verify in IPSec settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("INVALID_ID_INFORMATION", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Peer refused ID settings. Please verify the local ID in IPsec and remote network in Network - General settings."));

                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("cannot initiate connection with ID wildcards", 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Cannot initiate connection with ID wildcards. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf(QString("Can not opportunistically initiate"), 0, Qt::CaseInsensitive) > -1) {
            if (!stopContinue) {
                reportError(i18n("Cannot opportunistically initiate. Please verify the connection settings."));
                errorLine = __LINE__;
                stopContinue = true;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            }
        } else if (msg.indexOf("unable to locate my private key", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("Private key could not be found. Please check certificate settings."));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("SMARTCARD support is deactivated in pluto/Makefile", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("Smartcard not supported", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("SMARTCARD support is deactivated. Please enable smartcard support in %1 package", QString(IpsecType)));

            errorLine = __LINE__;
            IpsecGotError = true;
            IpsecWhackStatusTimer.stop();
        } else if (msg.indexOf("Unsupported card", 0, Qt::CaseInsensitive) > -1 &&  msg.indexOf("pkcs15", 0, Qt::CaseInsensitive) > -1) {
            reportError(i18n("Unsupported card found. Please use a smartcard with openct support. This is a Openswan limitation, sorry."));

            errorLine = __LINE__;
        } else if (msg.indexOf("we require peer to have ID", 0, Qt::CaseInsensitive) > -1 && msg.indexOf("but peer declares", 0, Qt::CaseInsensitive) > -1) {
            QString PeerID = msg.section('\'', 3, 3);
            QString OurID = msg.section('\'', 1, 1);
            reportError(i18n("Wrong ID \"%1\" from peer, expected \"%2\"." , QString(PeerID), OurID));

            int result = KMessageBox::questionYesNo(gui, i18n("Do you want to use \"%1\" instead of \"%2\" as remote ID and reconnect?", QString(PeerID), OurID), i18n("Fix remote ID?"));
            if (result == 3) { // Yes
                GlobalConfig->currentProfile->setUseSpecialRemoteID(true);
                GlobalConfig->currentProfile->setSpecialRemoteID(PeerID);
                GlobalConfig->currentProfile->setRemoteIDType("user");
                errorLine = __LINE__;
                reason = DISCONNECTION_REASON_CONFIGURATION_CHANGED;
            } else {
                if (!stopContinue) {

                    errorLine = __LINE__;
                    stopContinue = true;
                }
            }
        }

        if (errorLine) {
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStdout_ipsecwhacklisten()
{
    if (IpsecWhackListenProcess == 0 || IpsecGotError)
        return;
    QStringList msg_list = QString(IpsecWhackListenProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        debugMessage(1, "[ipsec whack listen] " + msg);

        if (msg.indexOf("listening for IKE messages", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(3, "[ipsec whack listen] " + i18n("Listen was successful."));
            start_ipsec_initiate();
        } else if (msg.indexOf("ISAKMP SA established", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("transition from state STATE_QUICK_I1 to state STATE_QUICK_I2", 0, Qt::CaseInsensitive) > -1 ) {

            IpsecWhackStatusTimer.stop();

            if (IpsecPhase1Up)
                return;
            else
                IpsecPhase1Up = true;
            IpsecWhackStatusTimer.stop();
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
                debugMessage(1, "[ipsec] " + i18n("IPSec phase 1 established."));
            } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                debugMessage(1, "[ipsec] " + i18n("Low level IPsec phase 1 established."));
            }
            if (GlobalConfig->currentProfile->getUseLeftSourceIp()) {
                debugMessage(3,  i18n ( "Adding virtual IP address" ) );
                doAddRemoveVirtualIp("add");
            }
            doPingKickupTunnel();


        } else if (msg.indexOf("IPsec SA established", 0, Qt::CaseInsensitive) > -1) {
            IpsecWhackStatusTimer.stop();

            if (IpsecPhase2Up)
                return;
            else
                IpsecPhase2Up = true;

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
                debugMessage(1, "[ipsec] " + i18n("IPSec phase 2 established."));
            } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                debugMessage(1, "[ipsec] " + i18n("Low level IPsec phase 2 established."));
            }

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
                successMessage("[ipsec] " + i18n("Connection established."));
            } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                successMessage("[ipsec] " + i18n("Low level IPsec connection established."));
            }

            doIptablesFreeswan();
            addRouteIpsec();

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                l2tpStart();
            } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {

                setStatusConnected(__LINE__);
            }
        }



//   // normal
//   if ( NormalMsg )
//   {
//    if ( GlobalConfig->KvpncDebugLevel > 1 )
//     logMessage ( "[ipsec whack listen] " + msg, KVpncEnum::debug );
//    //   if (GlobalConfig->KvpncDebugLevel > 0)
//    //    debugMessage( "out: " + msg );
//   }
//   else if ( ErrorMsg )
//   {
//    logMessage ( "[ipsec whack listen err] " + msg, KVpncEnum::error );
//   }

//   if ( abort )
//   {
        //			IpsecGotError = true;
        //			IpsecWhackStatusTimer.stop();
//    if ( GlobalConfig->KvpncDebugLevel > 0 )
//     logMessage ( i18n ( "There is a reason to stop connecting, terminating \"%1\" process.", QString( "ipsec whack --listen" )) , KVpncEnum::debug );
//    setStatusDisconnected(__LINE__);
//    setStatusDisconnected(__LINE__);
//    setGuiStatus ( disconnected );
//    return ;
//   }
    }
}

void IpsecHandler::readFromStderr_ipsecwhacklisten()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    if ( IpsecWhackListenProcess ==0  || IpsecGotError )
        return;
    QStringList msg_list = QString(IpsecWhackListenProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
//   logMessage ( "[ipsec whack listen err] " + msg, KVpncEnum::error );


        if (msg.indexOf("Pluto is not running", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, "[ipsec whack listen " + i18n("Waiting for pluto"));
            if (connectCounter > 25) {
                errorMessage("[ipsec whack listen " + i18n("Waiting for pluto needs too long"));
                errorLine = __LINE__;
                IpsecGotError = true;
                IpsecWhackStatusTimer.stop();
            } else {
                // we have to give some time to sleep and try again...
                if (IpsecWhackListenProcess) {
                    IpsecWhackListenProcess->waitForFinished(2000000);
                    delete IpsecWhackListenProcess;
                    IpsecWhackListenProcess = 0L;
                }

                connectCounter++;
                if ( !IpsecGotError)
                    ipsecStarted(0,QProcess::NormalExit);
            }
            return;
        }
        if (msg.indexOf("listening for IKE messages", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(3, "[ipsec whack listen] " + i18n("Listen was successful."));
            start_ipsec_initiate();
        } else {
            errorMessage("[ipsec whack listen err] " + msg);
        }

        if (errorLine) {
            debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("ipsec whack --listen")) );
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStdout_ipsecwhackstatus()
{
    if ( IpsecWhackStatusProcess ==0 || IpsecGotError )
        return;

    QStringList msg_list = QString(IpsecWhackStatusProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        debugMessage(5, "[ipsec whack status] " + msg);

        if (msg.indexOf(QString(GlobalConfig->currentProfile->getName()), 0, Qt::CaseInsensitive) > -1) {

            if (msg.indexOf("ISAKMP SA established", 0, Qt::CaseInsensitive) > -1  || msg.indexOf("transition from state STATE_QUICK_I1 to state STATE_QUICK_I2", 0, Qt::CaseInsensitive) > -1) {

                IpsecWhackStatusTimer.stop();

                if (IpsecPhase2Up)
                    return;

                if (IpsecPhase1Up)
                    return;
                else
                    IpsecPhase1Up = true;



                if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
                    debugMessage(1, "[ipsec] " + i18n("IPSec phase 1 established."));
                } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                    debugMessage(1, "[ipsec] " + i18n("Low level IPsec phase 1 established."));
                }
                if (GlobalConfig->currentProfile->getUseLeftSourceIp()) {
                    debugMessage(3,  i18n ( "Adding virtual IP address" ) );
                    doAddRemoveVirtualIp("add");
                }
                doPingKickupTunnel();

            }

            else if (msg.indexOf("IPsec SA established", 0, Qt::CaseInsensitive) > -1) {
                ipsecPhase2Established();
            }
        }

//   // normal
//   if ( GlobalConfig->KvpncDebugLevel > 3 )
//   {
//    if ( NormalMsg )
        //    {
//      logMessage ( "[ipsec whack status] " + msg, KVpncEnum::debug );
//     //   if (GlobalConfig->KvpncDebugLevel > 0)
//     //    debugMessage( "out: " + msg );
//    }
        //    }
//   else if ( ErrorMsg )
        //      {
//    logMessage ( "[ipsec whack status err] " + msg, KVpncEnum::error );
        //      }
        //
//   if ( abort )
        //       {
        //        if ( GlobalConfig->KvpncDebugLevel > 0 )
//     logMessage ( i18n ( "There is a reason to stop connecting, terminating \"%1\" process.", QString( "ipsec whack status" )) , KVpncEnum::debug );
//    setStatusDisconnected(__LINE__);
//    setStatusDisconnected(__LINE__);
//    setGuiStatus ( disconnected );
//    return ;
        //       }
    }
}

void IpsecHandler::readFromStderr_ipsecwhackstatus()
{
    QStringList msg_list = QString(IpsecWhackStatusProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        if (IpsecStatusCheck == true) {

            errorMessage("[ipsec whack status err] " + msg);


            if (msg.indexOf("Pluto is not running", 0, Qt::CaseInsensitive) > -1) {
                debugMessage(0, i18n("ipsec daemon is not running, restarting it..."));
                startStopIpsec(true);
                sleep(1);
                startStopIpsec(false);
            }



        } else {
            errorMessage("[ipsec whack status err] " + msg);

            if (msg.indexOf("Pluto is not running", 0, Qt::CaseInsensitive) > -1) {
                if (!IpsecStartingInProgress) {
                    debugMessage(0, i18n("ipsec daemon is not running, restarting it..."));
                    startStopIpsec(true);
                    sleep(1);
                    startStopIpsec(false);
                }
            }
        }

//   if ( abort )
        //   {
//    logMessage ( i18n ( "There is a reason to stop connecting, terminating \"%1\" process." , QString("l2tpd" )) , KVpncEnum::error );
//    setStatusDisconnected(__LINE__);
//    setStatusDisconnected(__LINE__);
//    setGuiStatus ( disconnected );
//    return ;
        //    }
    }
}

void IpsecHandler::readFromStdout_ipsecwhackdelete()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecWhackDeleteProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        bool NormalMsg = true;
        bool ErrorMsg = false;

        // normal
        if (NormalMsg) {
            debugMessage(1, "[ipsec whack delete] " + msg);
            //   if (GlobalConfig->KvpncDebugLevel > 0)
            //    debugMessage( "out: " + msg );
        } else if (ErrorMsg) {
            errorMessage("[ipsec whack delete err] " + msg);
        }

        if (errorLine) {
            debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("ipsec whack --delete")) );
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::readFromStderr_ipsecwhackdelete()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    QStringList msg_list = QString(IpsecWhackDeleteProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);


        errorMessage("[ipsec whack delete err] " + msg);

        if (errorLine) {
            debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("ipsec whack --delete")) );
            setStatusDisconnected(errorLine, reason);
            return ;
        }
    }
}

void IpsecHandler::doIptablesFreeswan()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    //  if ( ConnectProcess->normalExit () )
    {
        /*
        iptables -I INPUT -p 50 -i $IFACE -s $VPNGW_IP -j ACCEPT
        */
        putenv((char*)("LC_ALL=C"));
        QProcess IptablesFreeswanProcess(gui);
        QString proc = GlobalConfig->InterpreterShell;
        QStringList args;
        args.append(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".add_ipsec_freeswan.sh");
        IptablesFreeswanProcess.setEnvironment(*env);
        IptablesFreeswanProcess.start(proc, args);
        if (!IptablesFreeswanProcess.waitForStarted()) {
            reportError(i18n("Failed to start \"%1\"."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".add_ipsec_freeswan.sh")));

            errorLine = __LINE__;
        } else {
            debugMessage(0, i18n("\"%1\" started."  , QString(i18n("iptables.%1.add_ipsec_freeswan.sh" , GlobalConfig->currentProfile->getName()))));

            setFirewallAfterConnect();
            if (GlobalConfig->currentProfile->getExecuteCmdAfterConnect())
                executeCommandAfterConnect();
            waitForFinished(&IptablesFreeswanProcess, 100);
        }
    }
    if (errorLine) {
        debugMessage(0, i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("ipsec whack --delete")) );
        setStatusDisconnected(errorLine, reason);
        return ;
    }
}

void IpsecHandler::addRouteIpsec()
{
    tmpPath = KStandardDirs::locateLocal("data", "kvpnc/");
    QString IpsecRouteSetScript = tmpPath + "/set_route." + GlobalConfig->currentProfile->getName() + ".sh";
    NetworkInterface iface(GlobalConfig, kapp);
    QString defaultinterface = iface.getDefaultInterface();
    QString dev = "lo";

    QString RemoteNetAddr = GlobalConfig->currentProfile->getRemoteNetAddr();
    QString RemoteNetMask = GlobalConfig->currentProfile->getRemoteNetMask();
    QString RemoteNet = RemoteNetAddr + "/" + RemoteNetMask;

    if (iface.interfaceExist("ipsec0"))
        tmpInterface = "ipsec0";
    else
        tmpInterface = iface.getDefaultInterface();

    if (GlobalConfig->currentProfile->getUseVirtualIP())
        dev = QString(dev + ":100");
    else
        dev = tmpInterface;

    QFile IpsecSetRouteScript(IpsecRouteSetScript);
    QTextStream stream(&IpsecSetRouteScript);
    if (IpsecSetRouteScript.open(QIODevice::WriteOnly)) {
        if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
            stream << GlobalConfig->pathToIp << " route show  | grep 'default via' > " + tmpPath + "default-route." + GlobalConfig->currentProfile->getName() << "\n";
            stream << GlobalConfig->pathToRoute << " del default" << "\n";

            stream << GlobalConfig->pathToRoute << " add default gw " << GlobalConfig->currentProfile->getGateway() << " " << iface.getDefaultInterface() << "\n";
        }
        //      stream << GlobalConfig->pathToRoute << " add -net " << RemoteNet << " " << dev << "\n"; // set by opnswan
        IpsecSetRouteScript.close();

        QStringList args;
        args.append(IpsecRouteSetScript);

        RouteProcess = new HelperProcess(this, GlobalConfig->InterpreterShell, args, *env,
                                         SLOT(readFromStdout_route()),
                                         SLOT(readFromStderr_route()),
                                         0, 0);
        if (!RouteProcess || !RouteProcess->start()) {
            reportError(i18n("Failed to start \"%1\"."  , QString("route (%1)") , QString(IpsecType)));

            //    setStatusDisconnected(__LINE__);
        } else {
            if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                debugMessage(0, i18n("route (%1): route add default gw "  , QString("ipsec"  + GlobalConfig->currentProfile->getGateway() + " " + tmpInterface)));
                //        logMessage ( i18n( "route (%1): route add -net "  , QString("ipsec" + RemoteNet << " " + tmpInterface), KVpncEnum::debug );
                delete RouteProcess;
                RouteProcess = 0L;
                return;
            }
            RouteProcess->waitForFinished(100000);
            delete RouteProcess;
            RouteProcess = 0L;
        }

    }
}

void IpsecHandler::delRouteIpsec()
{
    tmpPath = KStandardDirs::locateLocal("data", "kvpnc/");
    QString IpsecRouteSetScript = tmpPath + "/remove_route." + GlobalConfig->currentProfile->getName() + ".sh";
    NetworkInterface iface(GlobalConfig, kapp);
    QString dev = "lo";

    QString RemoteNetAddr = GlobalConfig->currentProfile->getRemoteNetAddr();
    QString RemoteNetMask = GlobalConfig->currentProfile->getRemoteNetMask();
    QString RemoteNet = RemoteNetAddr + "/" + RemoteNetMask;

    if (iface.interfaceExist("ipsec0"))
        tmpInterface = "ipsec0";
    else
        tmpInterface = iface.getDefaultInterface();

    if (GlobalConfig->currentProfile->getUseVirtualIP())
        dev = QString(dev + ":100");
    else
        dev = tmpInterface;

    QFile IpsecSetRouteScript(IpsecRouteSetScript);
    QTextStream stream(&IpsecSetRouteScript);
    if (IpsecSetRouteScript.open(QIODevice::WriteOnly)) {
        stream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
        if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
            stream << GlobalConfig->pathToRoute << " del default" << "\n";

            stream << GlobalConfig->pathToIp << " route add `cat " + tmpPath + "default-route." + GlobalConfig->currentProfile->getName() << "`" << "\n";
        }

        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan)
            stream << GlobalConfig->pathToRoute << " del -net " << RemoteNet << " " << dev << "\n";
        IpsecSetRouteScript.close();

        QStringList args;
        args.append(IpsecRouteSetScript);

        RouteProcess = new HelperProcess(this, GlobalConfig->InterpreterShell, args, *env,
                                         SLOT(readFromStdout_route()),
                                         SLOT(readFromStderr_route()),
                                         0, 0);
        if (!RouteProcess || !RouteProcess->start()) {
            //    KMessageBox::error( gui, i18n( "Failed to start \"%1\"."  , QString( "del route ("+IpsecType+")" ) ));
            errorMessage(i18n("Failed to start \"%1\"."  , QString("del route (" + IpsecType + ")")));
        } else {
            debugMessage(0, i18n("route (ipsec): route del started."));
            RouteProcess->waitForFinished(100000);
            delete RouteProcess;
            RouteProcess = 0L;
        }

    }
}

void IpsecHandler::removeIptablesFreeswan()
{
    putenv((char*)("LC_ALL=C"));
    QProcess RemoveIptablesFreeswanProcess(gui);
    QString proc = GlobalConfig->InterpreterShell;
    QStringList args;
    args.append(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh");
    RemoveIptablesFreeswanProcess.setEnvironment(*env);
    RemoveIptablesFreeswanProcess.start(proc, args);
    if (!RemoveIptablesFreeswanProcess.waitForStarted()) {
        //    KMessageBox::error( gui, i18n( "Failed to start \"%1\"."  , QString( "iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh" )) );
        errorMessage(i18n("Failed to start \"%1\"."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh")));
    } else {
        debugMessage(0, i18n("\"%1\" started."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".remove_ipsec_freeswan.sh")));
        waitForFinished(&RemoveIptablesFreeswanProcess, 100);
    }

}

void IpsecHandler::ipsecStarted(int, QProcess::ExitStatus)
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    delete IpsecStartProcess;
    IpsecStartProcess = 0L;

//  ToolInfo *IpsecToolInfo = Utils ( GlobalConfig ).getToolInfo ( "ipsec" ) ;

//  if ( GlobalConfig->KvpncDebugLevel > 0 )
//   logMessage ( "[ipsec] " + i18n ( "Starting connection \"%1\"..."  , QString( GlobalConfig->currentProfile->getName() )) , KVpncEnum::debug );

//  /* Kick up the connection */
//  IpsecProcess = new QProcess( this );
//  QString proc = GlobalConfig->pathToIpsec;
//  QStringList args;
//  args.append ( "auto" );
//  //  if ( GlobalConfig->enableFreeswanVerbose )
//  //   args.append( "--verbose" );
//  args.append ( "--up" );
//  args.append ( GlobalConfig->currentProfile->getName() );
//
//
//  connect ( IpsecStartProcess, SIGNAL ( readyReadStandardOutput() ), gui, SLOT ( readFromStderr_ipsec() ) );
//  connect ( IpsecStartProcess, SIGNAL ( readyReadStandardError() ), gui, SLOT ( readFromStderr_ipsec() ) );
//  //    connect( IpsecStartProcess, SIGNAL( finished (int, QProcess::ExitStatus) ), gui, SLOT( doRouteFreeswan(int, QProcess::ExitStatus) ) );
//
//  IpsecStartProcess->setEnvironment(*env);
//  IpsecStartProcess->start(proc,args);
//  if ( !IpsecStartProcess->waitForStarted() )
//  {
//   KMessageBox::error ( gui, i18n ( "Failed to start \"%1\"."  , QString( "ipsec: connection" )) );
//   logMessage ( i18n ( "Failed to start \"%1\"."  , QString( "ipsec: connection" )) , KVpncEnum::error );
//   //   setStatusDisconnected(__LINE__);
//  }
//  else
//  {
//   if ( GlobalConfig->KvpncDebugLevel > 2 )
//    logMessage ( i18n ( "\"%1\" started."  , QString( "ipsec: connection" )) , KVpncEnum::debug );
// IpsecProcess->waitForFinished();
//  disconnect ( IpsecStartProcess, SIGNAL ( readyReadStandardOutput() ), gui, SLOT ( readFromStderr_ipsec() ) );
//  disconnect ( IpsecStartProcess, SIGNAL ( readyReadStandardError() ), gui, SLOT ( readFromStderr_ipsec() ) );
// delete IpsecProcess;
// IpsecProcess=0L;
//  }

    IpsecStatusCheck = true;
    checkIpsecWhackStatus();
    IpsecStatusCheck = false;

    debugMessage(0, "[ipsec] " + i18n("Starting \"%1\"..."  , QString(GlobalConfig->pathToIpsec + " whack' --listen")) );


    connectCounter = 0;
    sleep(1);
    putenv((char*)("LC_ALL=C"));
    QStringList args;
    args.append("whack");
    args.append("--listen");

    IpsecWhackListenProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
            SLOT(readFromStdout_ipsecwhacklisten()),
            SLOT(readFromStderr_ipsecwhacklisten()),
            0, 0);
    if (!IpsecWhackListenProcess || !IpsecWhackListenProcess->start()) {
        reportError(i18n("Failed to start \"%1\"."  , QString(GlobalConfig->pathToIpsec + " whack' --listen")));

        errorLine = __LINE__;
    } else {
        debugMessage(0, i18n("\"%1\" started."  , QString(GlobalConfig->pathToIpsec + " whack  --listen")));
    }

    if (errorLine) {
        setStatusDisconnected(errorLine, reason);
        return ;
    }
}

void IpsecHandler::checkIpsecWhackStatus()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    putenv((char*)("LC_ALL=C"));
    QStringList args;

    args.append("whack");
    args.append("--status");
    IpsecWhackStatusProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
            SLOT(readFromStdout_ipsecwhackstatus()),
            SLOT(readFromStderr_ipsecwhackstatus()),
            0, SLOT(IpsecWhackStatusProcessExited(int, QProcess::ExitStatus)));
    if (!IpsecWhackStatusProcess || !IpsecWhackStatusProcess->start()) {
        if (IpsecStatusCheck == false && IpsecPhase2Up == false) {
            reportError(i18n("Failed to start \"%1\"."  , QString(GlobalConfig->pathToIpsec + " whack' --status")));

            errorLine = __LINE__;
        }
    } else {
        debugMessage(5, i18n("\"%1\" started."  , QString(GlobalConfig->pathToIpsec + " whack  --status")));
        if (IpsecStatusCheck == true && IpsecPhase2Up == false) {
            if (!IpsecWhackStatusTimer.isActive()) {
                disconnect(&IpsecWhackStatusTimer, SIGNAL(timeout()), gui, SLOT(checkIpsecWhackStatus()));
                connect(&IpsecWhackStatusTimer, SIGNAL(timeout()), gui, SLOT(checkIpsecWhackStatus()));
                IpsecWhackStatusTimer.start(5 * 1000);
            }
        }
    }

    if (errorLine) {
        setStatusDisconnected(errorLine, reason);
        return ;
    }
}

void IpsecHandler::startStopIpsec(bool stop, bool silent)
{
    // FIXME replace with StartStopIpsecProcess
    QStringList args;

    if (m_toolIsOpenSwan)
        args.append("setup");

    if (stop == false) {
        if (silent == false || GlobalConfig->KvpncDebugLevel > 5) {
            if (m_toolIsStrongSwan /*&&  ( (IpsecMajor >= 4 && IpsecMinor >= 2 && IpsecSubMinor >=2 ) || IpsecMajor > 4 )*/) {
                debugMessage(0, "[" + IpsecType + "] " + i18n("Starting %1..." , QString("openswan")));
            }

            if (m_toolIsOpenSwan) {
                debugMessage(0, "[" + IpsecType + "] " + i18n("Starting %1..."  , QString("strongSwan")));
            }
        }

        GlobalConfig->currentConnectRetry++;
        args.append("start");
    } else {
        if (silent == false || GlobalConfig->KvpncDebugLevel > 5) {
            if (m_toolIsStrongSwan /*&&  ( (IpsecMajor >= 4 && IpsecMinor >= 2 && IpsecSubMinor >=2 ) || IpsecMajor > 4 )*/) {
                debugMessage(0, "[" + IpsecType + "] " + i18n("Stopping %1..."  , QString("openswan")));
            }

            if (m_toolIsOpenSwan) {
                debugMessage(0, "[" + IpsecType + "] " + i18n("Stopping %1..."  , QString("strongSwan")));
            }
        }
        args.append("stop");
    }

    IpsecStartingInProgress = true;
    if (silent == false || GlobalConfig->KvpncDebugLevel > 8) {
        IpsecStartProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                              SLOT(readFromStdout_ipsec()),
                                              SLOT(readFromStderr_ipsec()),
                                              SLOT(ipsecStarted(int, QProcess::ExitStatus)), 0);
    } else {
        IpsecStartProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                              0,
                                              0,
                                              SLOT(ipsecStarted(int, QProcess::ExitStatus)), 0);
    }
    if (!IpsecStartProcess || !IpsecStartProcess->start()) {
        if (silent == false) {
            reportError(i18n("Failed to start \"%1\"."  , QString("ipsec")));
        }
        IpsecStartingInProgress = false;
    } else {
        if (silent == false) {
            debugMessage(2, i18n("\"%1\" started."  , QString("ipsec")) );
        }
        IpsecStartProcess->waitForFinished(GlobalConfig->currentProfile->getMaxConnectTries() * 1000 * 200);

        delete IpsecStartProcess;
        IpsecStartProcess = 0;
        IpsecStartingInProgress = false;
    }
}

void IpsecHandler::addIpsecConnection()
{


}

void IpsecHandler::start_ipsec_initiate()
{
    unsigned errorLine = 0;
    DisconnectionReason reason = DISCONNECTION_REASON_FATAL_ERROR;

    // strongswan after ipsec whack --listen
    /*   disconnect ( IpsecWhackProcess, SIGNAL ( readyReadStandardOutput() ), gui, SLOT ( readFromStdout_ipsecwhack() ) );
       disconnect ( IpsecWhackProcess, SIGNAL ( readyReadStandardError() ), gui, SLOT ( readFromStderr_ipsecwhack() ) );
       delete IpsecWhackProcess;*/
    if ( IpsecGotError)
        return;

    sleep(4);

    putenv((char*)("LC_ALL=C"));
    QStringList args;
    args.append("whack");
    args.append("--name");
    args.append(GlobalConfig->currentProfile->getName());
    args.append("--initiate");

    IpsecWhackProcess = new HelperProcess(this, GlobalConfig->pathToIpsec, args, *env,
                                          SLOT(readFromStdout_ipsecwhack()),
                                          SLOT(readFromStderr_ipsecwhack()),
                                          0, SLOT(ipsecwhack_exited(int, QProcess::ExitStatus)));
    if (!IpsecWhackProcess || !IpsecWhackProcess->start()) {
        reportError(i18n("Failed to start \"%1\"." , QString(GlobalConfig->pathToIpsec + " whack' --name " + GlobalConfig->currentProfile->getName() + " --initiate")));

        errorLine = __LINE__;
    } else {
        debugMessage(0, i18n("\"%1\" started."  , QString(GlobalConfig->pathToIpsec + " whack --name " + GlobalConfig->currentProfile->getName() + " --initiate")));

        if (!IpsecGotError)
            checkIpsecWhackStatus();
    }

    if (errorLine) {
        setStatusDisconnected(errorLine, reason);
        return ;
    }
}

void IpsecHandler::ipsecPhase2Established()
{
    if (IpsecPhase2Up)
        return;
    else {
        IpsecWhackStatusTimer.stop();

        // hack: if from status phase2 is first
        if (IpsecPhase1Up == false) {

            if (IpsecPhase1Up)
                return;
            else
                IpsecPhase1Up = true;

            if (IpsecPhase2Up)
                return;

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
                debugMessage(1, "[ipsec] " + i18n("IPSec phase 2 established."));
            } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
                debugMessage(1, "[ipsec] " + i18n("Low level IPsec phase 2 established."));
            }
        }
        IpsecPhase2Up = true;
    }

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
        debugMessage(1, "[ipsec] " + i18n("IPSec phase 2 established."));
    } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
        debugMessage(1, "[ipsec] " + i18n("Low level IPsec phase 2 established."));
    }

    doIptablesFreeswan();
    addRouteIpsec();

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_freeswan) {
        l2tpStart();
    } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::freeswan) {
        setStatusConnected(__LINE__);
    }

}

QString IpsecHandler::pingDevice() const {
    return useL2tpAfterFirstConnection ? gui->l2tpPppDevice() : "ipsec0";
}

void IpsecHandler::ipsecwhack_exited(int, QProcess::ExitStatus)
{
    delete IpsecWhackProcess;
    IpsecWhackProcess = 0;
}

void IpsecHandler::IpsecWhackStatusProcessExited(int, QProcess::ExitStatus)
{
    //  disconnect ( IpsecWhackStatusProcess, SIGNAL ( readAllStandardOutput() ), this, SLOT ( readFromStdout_ipsecwhackstatus() ) );
    //  disconnect ( IpsecWhackStatusProcess, SIGNAL ( readyReadStandardError() ), this, SLOT ( readFromStderr_ipsecwhackstatus() ) );
    //  disconnect ( IpsecWhackStatusProcess, SIGNAL ( finished(int, QProcess::ExitStatus) ), this, SLOT ( IpsecWhackStatusProcessExited(int, QProcess::ExitStatus) ) );
    //  delete(IpsecWhackStatusProcess);
    //  IpsecWhackStatusProcess=0;
}

