/*****************************************************************************
 * Copyright (C) 2010 S.R.Haque <srhaque@theiet.org>                         *
 * Christoph Thielecke <crissi99@gmx.de> (contains code from kvpnc.cpp)      *
 *                                                                           *
 * This program is free software; you can redistribute it and/or modify      *
 * it under the terms of the GNU General Public License as published by      *
 * the Free Software Foundation; either version 2 of the License, or         *
 * (at your option) any later version.                                       *
 *                                                                           *
 * This package is distributed in the hope that it will be useful,           *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
 * GNU General Public License for more details.                              *
 *                                                                           *
 * You should have received a copy of the GNU General Public License         *
 * along with this package; if not, write to the Free Software               *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

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

RacoonHandler::RacoonHandler(
    KVpnc *ui,
    KVpncConfig *config,
    QString type,
    QString daemons,
    bool _useL2tpAfterFirstConnection):
        HandlerBase(ui, config, type, daemons, _useL2tpAfterFirstConnection),
        RacoonProcess(0),
        RacoonHelperProcess(0),
        RacoonTailProcess(0),
        RacoonctlProcess(0)
{
    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
        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 RacoonHandler::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 racoon
        if (!Utils(GlobalConfig).getToolInfo(IpsecType)->found) {
            reportError(i18n("Unable to find \"%1\" at \"%2\".", IpsecType, GlobalConfig->pathToRacoon));
            errorLine = __LINE__;
        } else {
            debugMessage(0, i18n("Found helper %1 at %2", IpsecType, GlobalConfig->pathToRacoon));
        }
    }

    if (!errorLine) {
        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
            if (!Utils(GlobalConfig).getToolInfo("l2tpd")->found && !Utils(GlobalConfig).getToolInfo("xl2tpd")->found) {
                reportError(i18n("Unable to find \"%1\" or \"%2\"." , QString("l2tpd") , QString("xl2tpd")));
                errorLine = __LINE__;
            }
        }
    }

    if (!errorLine) {
        // looking for setkey
        if (GlobalConfig->useDefaultPaths) {
            GlobalConfig->pathToSetkey = KStandardDirs::findExe("setkey");
        } else if (GlobalConfig->pathToSetkey.isEmpty() || KStandardDirs::findExe(GlobalConfig->pathToVpnc.section('/', -1, -1), GlobalConfig->pathToSetkey.section('/', 0, -2)).isEmpty()) {
            reportError(i18n("Unable to find \"%1\" at \"%2\"." , QString("setkey") , GlobalConfig->pathToSetkey));
            errorLine = __LINE__;
        }
    }

    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 (!errorLine) {
        if (GlobalConfig->currentProfile->authtype == VpnAccountData::cert) {
            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"));
                errorLine = __LINE__;
            }
        }
    }

    if (!errorLine) {
        RacoonProcess = 0L;
        RacoonctlProcess = 0L;

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

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

    if (!errorLine) {
        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('#', 0) < 0) {
                        GlobalConfig->TmpGroupPassword = line;
                        GlobalConfig->haveUserData = true;
                        break;
                    }
                }
                f.close();
            } else {
                errorMessage(i18n("PSK could not read from file because PSK key file %1 could not be read." , GlobalConfig->currentProfile->getPreSharedKeyFile()));
                errorLine = __LINE__;
            }
        }
        else {
            GlobalConfig->TmpGroupPassword = GlobalConfig->currentProfile->getPreSharedKey();
            if (!GlobalConfig->TmpGroupPassword.isEmpty())
                GlobalConfig->haveUserData = true;
        }

    }

    if (!errorLine) {
        if (GlobalConfig->TmpGroupPassword.isEmpty()) {
            errorMessage(i18n("PSK could not read from file because PSK key file %1 contains no key." , GlobalConfig->currentProfile->getPreSharedKeyFile()));
            errorLine = __LINE__;
        }
    }

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

    if (!errorLine) {
// here we go
        if (GlobalConfig->currentProfile->getExecuteCmdBeforeConnect())
            executeCommandBeforeConnect();
    }

    QString ProfileName = GlobalConfig->currentProfile->getName();
    QString LocalIP;
    QString VirtualLocalIP;
    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 {
            QString device = GlobalConfig->currentProfile->getNetworkDevice();
            tmpInterface = GlobalConfig->currentProfile->getNetworkDevice();
            LocalIP = iface.getInterfaceIP(device);
        }
        if (tmpInterface.isEmpty()) {
            tmpInterface = iface.getDefaultInterface();
            LocalIP = iface.getInterfaceIP(iface.getDefaultInterface());
            if (tmpInterface.isEmpty()) {
                debugMessage(0, i18n("No default interface found, using \"lo\"."));
                tmpInterface = "lo"; // no default interface found :(
            } else {
                debugMessage(0, i18n("No default interface given, tried default interface, got success, using \"%1\"." , tmpInterface));
            }
        }

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

        // FIXME
        // if not virtual ip, its same as LocalIP
        VirtualLocalIP=LocalIP;
        // if not virtual ip, its 32 (only one host)
        QString VirtualLocalNetmask="32";

        if ( GlobalConfig->currentProfile->getUseLeftSourceIp() )
        {
            VirtualLocalIP = GlobalConfig->currentProfile->getLeftSourceIp();
        }

        debugMessage(0, i18n("Default interface: %1", tmpInterface));
        debugMessage(0, i18n("Local IP address: %1", LocalIP));
        debugMessage(0, i18n( "Local IP address (virtual): %1", VirtualLocalIP ) );
        debugMessage(0, i18n( "Local netmask (virtual): %1", VirtualLocalNetmask ) );

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

        QString CertPath = GlobalConfig->currentProfile->getCertPath();

        // write setkey.conf
        QFile file(tmpPath + "setkey." + ProfileName + ".conf");
        QTextStream stream(&file);
        if (file.open(QIODevice::WriteOnly)) {

            QString PolicyRemote = "";
            QString PolicyLocal = "";

            QString Remote = GlobalConfig->currentProfile->getGateway();

            //FIXME make it dynamiclly
            QString LocalPort = "4500";
            QString RemotePort = "4500";

            if (!GlobalConfig->currentProfile->getUseNat()) {
                // Use this for a non NAT-T setup
                PolicyLocal = LocalIP;
                PolicyRemote = GlobalConfig->TmpGatewayIP;
            } else {
                PolicyLocal = LocalIP + "[" + LocalPort + "]";
                PolicyRemote = GlobalConfig->TmpGatewayIP + "[" + RemotePort + "]";
            }

            stream << "flush;" << "\n";
            stream << "spdflush;" << "\n";

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
                stream << "spdadd " << Remote << "[1701] " << LocalIP << "[any] udp -P in ipsec esp/transport//require;" << "\n";
                stream << "spdadd " << LocalIP << "[any] " << Remote << "[1701] udp -P out ipsec esp/transport//require;" << "\n";
                //      stream << "spdadd " << Remote << "[1701] " << LocalIP << "[any] udp -P in ipsec esp/tunnel/" + GlobalConfig->TmpGatewayIP + "-" + LocalIP + "/require;" << "\n";
                //      stream << "spdadd " << LocalIP << "[any] " << Remote << "[1701] udp -P out ipsec esp/tunnel/" + LocalIP + "-" + GlobalConfig->TmpGatewayIP + "/require;" << "\n";
            }
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon || (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getAuthType() == VpnAccountData::hybrid)) {
                //           stream << "spdadd " + LocalIP + " " + RemoteNet + " any -P out ipsec esp/tunnel/" + PolicyLocal + "-" + PolicyRemote + "/require;" << "\n";
                //           stream << "spdadd " + RemoteNet + " " + LocalIP + " any -P in ipsec esp/tunnel/" + PolicyRemote + "-" + PolicyLocal + "/require;" << "\n";

                if (GlobalConfig->currentProfile->getUseRemoteNetwork()) {
                    stream << "spdadd " + VirtualLocalIP + " " + RemoteNet + " any -P out ipsec esp/tunnel/" + LocalIP + "-" + GlobalConfig->TmpGatewayIP + "/require;" << "\n";
                    stream << "spdadd " + RemoteNet + " " + VirtualLocalIP + " any -P in ipsec esp/tunnel/" + GlobalConfig->TmpGatewayIP + "-" + LocalIP + "/require;" << "\n";
                } else {
                    stream << "spdadd " + LocalIP + " " + GlobalConfig->TmpGatewayIP + " any -P out ipsec esp/transport//require;" << "\n";
                    stream << "spdadd " + GlobalConfig->TmpGatewayIP + " " + LocalIP + " any -P in ipsec esp/transport//require;" << "\n";
                }
            }

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {

                stream << "spdadd " + LocalIP + "[1701] " + Remote + "[any] udp -P in ipsec esp/transport//require;" << "\n";
                stream << "spdadd " + Remote + "[any] " + LocalIP + "[1701] udp -P  out ipsec esp/transport//require;" << "\n";
                stream << "spdadd " + LocalIP + "[1701] " + Remote + "[any] udp -P fwd ipsec esp/transport//require;" << "\n";

                // additional network routes
                if (!GlobalConfig->currentProfile->getAdditionalNetworkRoutes().isEmpty()) {
                    QStringList AdditionalNetworkRoutes = GlobalConfig->currentProfile->getAdditionalNetworkRoutes();

                    for (QStringList::Iterator it = AdditionalNetworkRoutes.begin(); it != AdditionalNetworkRoutes.end(); ++it) {
                        QString net = (*it).section('#', 0, 0);
                        //        stream << "spdadd " + LocalIP + " " + net + " any -P out ipsec esp/tunnel/" + PolicyLocal + "-" + PolicyRemote + "/require;" << "\n";
                        //        stream << "spdadd " + net + " " + LocalIP + " any -P in ipsec esp/tunnel/" + PolicyRemote + "-" + PolicyLocal + "/require;" << "\n";
                        stream << "spdadd " + LocalIP + " " + net + " any -P out ipsec esp/tunnel/" + LocalIP + "-" + GlobalConfig->TmpGatewayIP + "/require;" << "\n";
                        stream << "spdadd " + net + " " + LocalIP + " any -P in ipsec esp/tunnel/" + GlobalConfig->TmpGatewayIP + "-" + LocalIP + "/require;" << "\n";
                    }
                }
            }
            file.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , file.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        // write racoon.<profile>.conf
        QFile file(tmpPath + "racoon." + ProfileName + ".conf");
        if (file.open(QIODevice::WriteOnly)) {
            QTextStream stream(&file);
            stream << "# generated by kvpnc. Do not edit it." << "\n";
            stream << "# profile: " + ProfileName << "\n";

            stream << "\n";
            if (GlobalConfig->RacoonDebugLevel != "none")
                stream << "log " + GlobalConfig->RacoonDebugLevel << ";" << "\n"; // FIXME: validate racoon version

            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert ||  GlobalConfig->currentProfile->getAuthType() == VpnAccountData::hybrid)
                stream << "path certificate \"" + GlobalConfig->currentProfile->getCertPath() + "\";" << "\n";

            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk)
                stream << "path pre_shared_key \"" + tmpPath + "psk." + ProfileName + ".key" + "\";" << "\n";

            //stream << "#option of controlling racoon by racoonctl tool is enabled" << "\n";
            stream << "listen {" << "\n";
            stream << " adminsock \"/var/run/racoon/racoon.sock\" \"root\" \"operator\" 0660;" << "\n";

            if ( GlobalConfig->currentProfile->getUseNat() ) {
                stream << "  isakmp_natt " << LocalIP << " [4500];" << "\n";
            }
            //else {
            stream << "  isakmp " << LocalIP << " [500];" << "\n";
            //}
            stream << "}" << "\n";

            //              if ( GlobalConfig->currentProfile->getUseNat() ) {
            //                  stream << "" << "\n";
            //                  stream << "timer" << "\n";
            //                  stream << "{" << "\n";
            //
            //                  //FIXME make it dynamiclly
            //                  stream << "  natt_keepalive 20 sec;" << "\n";
            //                  stream << "}" << "\n";
            //              }
            stream << "" << "\n";
            stream << "remote " << GlobalConfig->TmpGatewayIP << " {" << "\n";
            stream << "  exchange_mode " << GlobalConfig->currentProfile->getExchangeMode() << ";" << "\n";

            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert) {
                stream << "  certificate_type x509 \"" << GlobalConfig->currentProfile->getX509Certificate() << "\" \"" << GlobalConfig->currentProfile->getX509Certificate() + "\";" << "\n";
                if (!GlobalConfig->currentProfile->getCaCertificate().isEmpty())
                    stream << "  ca_type x509 \"" << GlobalConfig->currentProfile->getCaCertificate() << "\";" << "\n";

                // FIXME make it dynamiclly
                stream << "  proposal_check obey;" << "\n";

                if (GlobalConfig->currentProfile->getVerifyCaCert())
                    stream << "  verify_cert on;" << "\n";
                else
                    stream << "  verify_cert off;" << "\n";
            }

            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::hybrid) {
                if (!GlobalConfig->currentProfile->getCaCertificate().isEmpty())
                    stream << "  ca_type x509 \"" << GlobalConfig->currentProfile->getCaCertificate() << "\";" << "\n";

                // FIXME make it dynamiclly
                stream << "  proposal_check obey;" << "\n";

                if (GlobalConfig->currentProfile->getVerifyCaCert())
                    stream << "  verify_cert on;" << "\n";
                else
                    stream << "  verify_cert off;" << "\n";
            }

            if (GlobalConfig->currentProfile->getUseNat() ) {
                stream << "  nat_traversal on;" << "\n";
                debugMessage(0, i18n("Using NAT-T."));
            } else {
                stream << "  nat_traversal off;" << "\n";
                debugMessage(0, i18n("Disabling NAT-T."));
            }

            // FIXME make it dynamiclly
            stream << "  ike_frag on;" << "\n";

            if (GlobalConfig->currentProfile->getUseModeConfig()) {
                stream << "  mode_cfg on;" << "\n";
                debugMessage(0, i18n("Using Mode Config."));
            } else {
                stream << "  mode_cfg off;" << "\n";
            }

            stream << "  passive off;" << "\n";

            //     stream << "  #IKE first phase starting script" << "\n";
            stream << "  script \"" + tmpPath + "racoon-" + ProfileName + ".phase1-up.sh\" phase1_up;" << "\n";
            //     stream << "\n";
            //     stream << "  #IKE first phase ending script" << "\n";
            stream << "  script \"" + tmpPath + "racoon-" + ProfileName + ".phase1-down.sh\" phase1_down;" << "\n";

            /*
            none:       No ID
            address:        The type is the IP address. This is the default type if you do not specify an identifier to use
            user_fqdn:  The type is a USER_FQDN (user fully-qualified domain name)
            fqdn:       The type is a FQDN (fully-qualified domain name)
            keyid (file):   The type is a KEY_ID, read from the file
            keyid:      The type is a KEY_ID, specified in the quoted string
            asn1dn:     The type is an ASN.1 distinguished name. If empty, DN from the Subject field in the certificate will be used
            */

            QString RemoteIDType = GlobalConfig->currentProfile->getRemoteIDType();

            if ( RemoteIDType == "none" ) {
                // no ID
            } else if ( RemoteIDType == "address" ) {
                if ( !GlobalConfig->currentProfile->getSpecialRemoteID().isEmpty() )
                    stream << "  peers_identifier address \"" << GlobalConfig->currentProfile->getSpecialRemoteID() << "\";" << "\n";
                else
                    stream << "  peers_identifier address;" << "\n";
            } else if ( RemoteIDType == "user_fqdn" ) {
                stream << "  peers_identifier user_fqdn \"" << GlobalConfig->currentProfile->getSpecialRemoteID() << "\";" << "\n";
            } else if ( RemoteIDType == "fqdn" ) {
                stream << "  peers_identifier fqdn \"" << GlobalConfig->currentProfile->getSpecialRemoteID() << "\";" << "\n";
            } else if ( RemoteIDType == "keyid (file)" ) {
                stream << "  peers_identifier keyid tag " << GlobalConfig->currentProfile->getSpecialRemoteID() << ";" << "\n";
            } else if ( RemoteIDType == "keyid" ) {
                stream << "  peers_identifier keyid \"" << GlobalConfig->currentProfile->getSpecialRemoteID() << "\";" << "\n";
            } else if ( RemoteIDType == "asn1dn" ) {
                stream << "  peers_identifier asn1dn;" << "\n";
            }

            QString LocalIDType = GlobalConfig->currentProfile->getLocalIDType();
            if ( LocalIDType == "none" ) {
                // no ID
            } else if ( LocalIDType == "address" ) {
                if ( !GlobalConfig->currentProfile->getSpecialLocalID().isEmpty() )
                    stream << "  my_identifier address \"" << GlobalConfig->currentProfile->getSpecialLocalID() << "\";" << "\n";
                else
                    stream << "  my_identifier address;" << "\n";
            } else if ( LocalIDType == "user_fqdn" ) {
                stream << "  my_identifier user_fqdn \"" << GlobalConfig->currentProfile->getSpecialLocalID() << "\";" << "\n";
            } else if ( LocalIDType == "fqdn" ) {
                stream << "  my_identifier fqdn \"" << GlobalConfig->currentProfile->getSpecialLocalID() << "\";" << "\n";
            } else if ( LocalIDType == "keyid (file)" ) {
                stream << "  peers_identifier keyid tag " << GlobalConfig->currentProfile->getSpecialLocalID() << ";" << "\n";
            } else if ( LocalIDType == "keyid" ) {
                stream << "  my_identifier keyid \"" << GlobalConfig->currentProfile->getSpecialLocalID() << "\";" << "\n";
            } else if ( LocalIDType == "asn1dn" ) {
                stream << "  my_identifier asn1dn;" << "\n";
            }

            //     stream << "  passive on;" << "\n";
            if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
                //      stream << "  # XAUTH" << "\n";
                //      stream << "  xauth_login \"" << GlobalConfig->TmpUsername << "\";" <<"\n";
                debugMessage(3, i18n("Using XAUTH."));
            }

            // FIXME: make dynamiclly
            stream << "    proposal_check obey;" << "\n";

            stream << "  proposal {" << "\n";

            //     stream << "    # for phase 1" << "\n";
            stream << "    encryption_algorithm " << GlobalConfig->currentProfile->getIpsecIke() << ";" << "\n";

            if (! GlobalConfig->currentProfile->getHashAlgo().isEmpty())
                stream << "    hash_algorithm " << GlobalConfig->currentProfile->getHashAlgo() << ";" << "\n";

            // x509
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::cert)
                stream << "    authentication_method rsasig;" << "\n";
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk)
                stream << "    authentication_method pre_shared_key;" << "\n";
            if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::hybrid)
                stream << "    authentication_method hybrid_rsa_client;" << "\n";

            /*
            modp768     1
            modp1024    2
            modp1536    5
            modp2048    14
            modp3072    15
            modp4096    16
            modp6144    17
            modp8192    18
            */
            QString DhGroupNumber = "2";
            if (GlobalConfig->currentProfile->getIkeGroup() == "modp768")
                DhGroupNumber = "1";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp1024")
                DhGroupNumber = "2";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp1536")
                DhGroupNumber = "5";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp2048")
                DhGroupNumber = "14";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp3072")
                DhGroupNumber = "15";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp4096")
                DhGroupNumber = "16";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp6144")
                DhGroupNumber = "17";
            else if (GlobalConfig->currentProfile->getIkeGroup() == "modp8192")
                DhGroupNumber = "18";

            stream << "    dh_group " + DhGroupNumber + ";" << "\n";

            stream << "  }" << "\n";
            stream << "}" << "\n";
            stream << "" << "\n";

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


            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon || (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getAuthType() == VpnAccountData::hybrid))
                stream << "sainfo anonymous {" << "\n";
            else {
                if (GlobalConfig->currentProfile->getUseRemoteNetwork())
                    stream << "sainfo address " << VirtualLocalIP << " any subnet " << RemoteNet << " any {" << "\n";
                else
                    stream << "sainfo address " << VirtualLocalIP << " any address " << GlobalConfig->TmpGatewayIP << "/32 any {" << "\n";
            }

            // FIXME make dynamiclly
            stream << "  lifetime time 1 hour;" << "\n";

            if (GlobalConfig->currentProfile->getUsePerfectForwardSecrety()) {
                QString pfs_group = "";
                //                  if ( GlobalConfig->currentProfile->getPerfectForwardSecrety() == "server" )
                //                      pfs_group = "";
                //                  else if ( GlobalConfig->currentProfile->getPerfectForwardSecrety() == "nopfs" )
                //                      pfs_group = "";
                //                  else if ( GlobalConfig->currentProfile->getPerfectForwardSecrety() == "dh1" )
                //                      pfs_group = "1";
                //                  else if ( GlobalConfig->currentProfile->getPerfectForwardSecrety() == "dh2" )
                //                      pfs_group = "2";
                //                  else if ( GlobalConfig->currentProfile->getPerfectForwardSecrety() == "dh5" )
                //                      pfs_group = "5";

                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 << "  pfs_group " << PFSGroupNumber << ";\n";
            } else {
                // racoon allows to empty this if no pfs is requested
                //stream << "  pfs_group modp768;" << "\n";
            }

            stream << "  encryption_algorithm " << GlobalConfig->currentProfile->getEncryptionAlgorithm() << ";" << "\n";
            //if ( GlobalConfig->currentProfile->getAuthWithUsernameAndPassword())
            stream << "  authentication_algorithm " << GlobalConfig->currentProfile->getAuthenticationAlgorithm() << ";" << "\n";
            //else
            //  stream << "  authentication_algorithm " << GlobalConfig->currentProfile->getAuthenticationAlgorithm() << ", non_auth;" << "\n";

            //              Utils::IpsecAlgos KernelCrypto = Utils ( GlobalConfig ).getKernelCrypto();
            //              // phase 2 encr algos from kernel
            //              QString EncrAlgos="";
            //              for ( QStringList::Iterator it = KernelCrypto.IpsecEspEncryptionAlgorithms.begin(); it != KernelCrypto.IpsecEspEncryptionAlgorithms.end(); ++it )
            //              {
            //              if (EncrAlgos.length() > 0)
            //              EncrAlgos+=",";
            //              EncrAlgos+= QString(*it );
            //              }
            //
            //
            //              // phase 2 auth algos from kernel
            //              QString AuthAlgos="";
            //              for ( QStringList::Iterator it = KernelCrypto.IpsecEspAuthenticationAlgorithms.begin(); it != KernelCrypto.IpsecEspAuthenticationAlgorithms.end(); ++it )
            //              {
            //              if (AuthAlgos.length() > 0)
            //              AuthAlgos+=",";
            //              AuthAlgos+= QString(*it );
            //              }
            //
            //
            //              stream << "  encryption_algorithm " << EncrAlgos << ";"<<"\n";
            //              stream << "  authentication_algorithm " << AuthAlgos << ";"<< "\n";

            stream << "  compression_algorithm deflate;" << "\n";
            stream << "}" << "\n";

            //     stream << "listen {" << "\n";
            //
            //     //FIXME make own port useable
            //     stream << "  isakmp " << LocalIP << ";" << "\n";
            //     if ( GlobalConfig->currentProfile->getUseNat() )
            //     {
            //      if ( GlobalConfig->currentProfile->getUseUdpPort() )
            //      {
            //       stream << "  # isakmp port for nat-t" << "\n";
            //       stream << "  isakmp_natt " << LocalIP << "["<< GlobalConfig->currentProfile->getUdpPort() << "];" << "\n";
            //      }
            //      else
            //      {
            //       stream << "  isakmp_natt " << LocalIP << ";" << "\n";
            //      }
            //     }
            //     stream << "}" << "\n";
            file.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , file.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        // write setkey.<profile>.sh
        QFile file(tmpPath + "setkey." + ProfileName + ".sh");
        if (file.open(QIODevice::WriteOnly)) {
            QTextStream stream(&file);
            stream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            stream << "# generated by kvpnc. Do not edit it." << "\n";
            stream << "# profile: " + ProfileName << "\n";
            stream << "" << "\n";
            stream << "# run setkey" << "\n";
            stream << GlobalConfig->pathToSetkey << " -f " << tmpPath + "setkey." + GlobalConfig->currentProfile->getName() + ".conf" << "\n";
            file.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , file.fileName()));
            errorLine = __LINE__;
        }
    }

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

        // write iptables.<profile>.sh
        QFile file(tmpPath + "iptables." + ProfileName + ".add_racoon.sh");
        if (file.open(QIODevice::WriteOnly)) {
            QTextStream stream(&file);
            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->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I OUTPUT -p 50 -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream << "" << "\n";
            stream << "#  ESP" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p 51 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I OUTPUT -p 51 -d " << GlobalConfig->TmpGatewayIP << " -j  ACCEPT" << "\n";
            stream << "" << "\n";
            stream << "#  IKE" << "\n";
            stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I OUTPUT -p udp --dport 500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";

            stream << "" << "\n";
            stream << GlobalConfig->pathToIptables << " -I FORWARD -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream << GlobalConfig->pathToIptables << " -I FORWARD -p udp --dport 500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";

            if (GlobalConfig->currentProfile->getUseNat()) {
                stream << "" << "\n";
                stream << "#  NAT-T" << "\n";
                stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 4500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
                stream << GlobalConfig->pathToIptables << " -I OUTPUT -p udp --sport 4500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            }
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
                stream << "" << "\n";
                stream << "#  L2TP" << "\n";
                stream << GlobalConfig->pathToIptables << " -I INPUT -p udp --dport 1701 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
                stream << GlobalConfig->pathToIptables << " -I OUTPUT -p udp --sport 1701 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            }
            file.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , file.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        QFile file1(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".remove_racoon.sh");
        QTextStream stream1(&file1);
        if (file1.open(QIODevice::WriteOnly)) {
            stream1 <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            stream1 << "# generated by kvpnc. Do not edit it." << "\n";
            stream1 << "# profile: " + ProfileName << "\n";
            stream1 << "" << "\n";
            stream1 << "#  AH" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p 50 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p 50 -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream1 << "" << "\n";
            stream1 << "#  ESP" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p 51 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p 51 -d " << GlobalConfig->TmpGatewayIP << " -j  ACCEPT" << "\n";
            stream1 << "" << "\n";
            stream1 << "#  IKE" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p udp --dport 500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";

            stream1 << "" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D FORWARD -p udp --dport 500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            stream1 << GlobalConfig->pathToIptables << " -D FORWARD -p udp --dport 500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";

            if (GlobalConfig->currentProfile->getUseNat()) {
                stream1 << "" << "\n";
                stream1 << "#  NAT-T" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 4500 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p udp --sport 4500 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            }
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
                stream1 << "" << "\n";
                stream1 << "#  L2TP" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D INPUT -p udp --dport 1701 -i " << tmpInterface2 << " -s " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
                stream1 << GlobalConfig->pathToIptables << " -D OUTPUT -p udp --sport 1701 -i " << tmpInterface2 << " -d " << GlobalConfig->TmpGatewayIP << " -j ACCEPT" << "\n";
            }
            file1.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , file1.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        QFile upfile(tmpPath + "racoon-" + ProfileName + ".phase1-up.sh");
        QTextStream upstream(&upfile);
        if (upfile.open(QIODevice::WriteOnly)) {
            upstream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            upstream << "# generated by kvpnc. Do not edit it." << "\n";
            upstream << "# profile: " + ProfileName << "\n";
            upstream << "" << "\n";
            upstream << "echo \"STATE: phase1 up\"" << "\n";
            if (GlobalConfig->currentProfile->getUseModeConfig()) {
                upstream << "echo \"# modecfg data\" >  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // An IPv4 internal address obtained by ISAKMP mode config
                upstream << "echo \"INTERNAL_ADDR4=$INTERNAL_ADDR4\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // An IPv4 internal netmask obtained by ISAKMP mode config
                upstream << "echo \"INTERNAL_NETMASK4=$INTERNAL_NETMASK4\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // An IPv4 internal netmask obtained by ISAKMP mode config, in CIDR notation
                upstream << "echo \"INTERNAL_CIDR4=$INTERNAL_CIDR4\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // The first internal DNS server IPv4 address obtained by ISAKMP mode config.
                upstream << "echo \"INTERNAL_DNS4=$INTERNAL_DNS4\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // A list of internal DNS servers IPv4 address obtained by ISAKMP mode config, separated by spaces
                upstream << "echo \"INTERNAL_DNS4_LIST=$INTERNAL_DNS4_LIST\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // The first internal WINS server IPv4 address obtained by ISAKMP mode config
                upstream << "echo \"INTERNAL_WINS4=$INTERNAL_WINS4\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // A list of internal WINS servers IPv4 address obtained by ISAKMP mode config, separated by spaces
                upstream << "echo \"INTERNAL_WINS4_LIST=$INTERNAL_WINS4_LIST\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // The space separated list of IPv4 addresses and masks (address slash mask) that define the networks to be encrypted (as opposed to the default where all the traffic should be encrypted) ; obtained by ISAKMP mode config ; SPLIT_INCLUDE and SPLIT_LOCAL are mutually exclusive
                upstream << "echo \"SPLIT_INCLUDE=$SPLIT_INCLUDE\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // The space separated list of IPv4 addresses and masks (address slash mask) that define the networks to be considered local, and thus excluded from the tunnels ; obtained by ISAKMP mode config
                upstream << "echo \"SPLIT_LOCAL=$SPLIT_LOCAL\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";
                upstream << "\n";
                // The DNS default domain name obtained by ISAKMP mode config
                upstream << "echo \"DEFAULT_DOMAIN=$DEFAULT_DOMAIN\" >>  " << tmpPath << "/racoon-" << ProfileName << ".modecfg" << "\n";


                // listing known IP addresses and setting PATH environment variable
                // internal address in local network
                upstream << "echo \"internal address: ${INTERNAL_ADDR4}\"" << "\n";

                // current global IP address
                upstream << "echo \"local address: ${LOCAL_ADDR}\"" << "\n";

                // VPN gateway IP address
                upstream << "echo \"remote address: $REMOTE_ADDR\"" << "\n";
                upstream << "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" << "\n";

                if (GlobalConfig->currentProfile->getUseModeConfig()) {
                    // defining variable to hold the name of virtual network interface
                    upstream << "if=" + tmpInterface << "\n";

                    // adding internal IP address to virtual network interface
                    upstream << "" << GlobalConfig->pathToIp << " address add dev ${if} ${INTERNAL_ADDR4}" << "\n";
                }

                // deleting default route
                //      upstream << "" << GlobalConfig->pathToIp << " route del default" << "\n";

                // adding route to VPN gateway
                upstream << "" << GlobalConfig->pathToIp << " route add ${REMOTE_ADDR} via " << GlobalConfig->TmpGatewayIP << "\n";

                // adding default route with new source address
                //      upstream << "ip route add default via " << GlobalConfig->TmpGatewayIP << " src ${INTERNAL_ADDR4}" << "\n";

                // deleting existing route towards local network
                //      upstream << "ip route delete 192.168.112.0/24 via " << GlobalConfig->TmpGatewayIP << " dev "+tmpInterface+"" << "\n";

                // deleting existing route towards Internet
                //      upstream << "ip route delete 192.168.111.0/24 dev "+tmpInterface+"" << "\n";

                // setting SPs form local network address towards all other IP addresses through tunnel
                // from roadwarrior client to VPN gateway, and vice verse, and also deleting the forwarding SP
                upstream << "echo \"\"" << "\n";
                //      upstream << "spdadd ${INTERNAL_ADDR4}/32[any] 0.0.0.0/0[any] any" << "\n";
                //      upstream << "  -P out ipsec esp/tunnel/${LOCAL_ADDR}-${REMOTE_ADDR}/require;" << "\n";
                //      upstream << "spdadd 0.0.0.0/0[any] ${INTERNAL_ADDR4}[any] any" << "\n";
                //      upstream << "  -P in ipsec esp/tunnel/${REMOTE_ADDR}-${LOCAL_ADDR}/require;" << "\n";
                //      upstream << "\" | " << GlobalConfig->pathToSetkey << " -c" << "\n";
                //      upstream << "echo \"" << "\n";
                //      upstream << "spddelete 0.0.0.0/0[any] ${INTERNAL_ADDR4}[any] any" << "\n";
                //      upstream << "  -P fwd ipsec esp/tunnel/${REMOTE_ADDR}-${LOCAL_ADDR}/require;" << "\n";
                //      upstream << "\" | setkey -c" << "\n";

                upstream << "echo \"STATE: upscript finished\"" << "\n";
            }
            upfile.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , upfile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        QFile downfile(tmpPath + "racoon-" + ProfileName + ".phase1-down.sh");
        QTextStream downstream(&downfile);
        if (downfile.open(QIODevice::WriteOnly)) {
            downstream <<  "#!" << GlobalConfig->InterpreterShell << "\n";
            downstream << "# generated by kvpnc. Do not edit it." << "\n";
            downstream << "# profile: " + ProfileName << "\n";
            downstream << "" << "\n";
            downstream << "echo \"STATE: phase1 down\"" << "\n";

            // listing known IP addresses and setting PATH environment variable
            downstream << "echo \"----------------\"" << "\n";
            downstream << "echo \"internal address: ${INTERNAL_ADDR4}\"" << "\n";
            downstream << "echo \"local address: ${LOCAL_ADDR}\"" << "\n";
            downstream << "echo \"remote address: $REMOTE_ADDR\"" << "\n";
            downstream << "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" << "\n";

            if (GlobalConfig->currentProfile->getUseModeConfig()) {
                // defining variable to hold the name of virtual network interface
                downstream << "if=" + tmpInterface << "\n";

                // deleting internal IP address from virtual network interface
                downstream << "ip address delete ${INTERNAL_ADDR4} dev ${if}" << "\n";
            }

            // deleting route towards VPN gateway" << "\n";
            downstream << "ip route delete ${REMOTE_ADDR} via " << GlobalConfig->TmpGatewayIP << "" << "\n";

            // adding default route through network interface
            //downstream << "ip route add default dev "+tmpInterface+"" << "\n";

            // adding routes towards local network and Internet
            // downstream << "ip route add 192.168.112.0/24 via " << GlobalConfig->TmpGatewayIP << " dev "+tmpInterface+"" << "\n";
            //downstream << "ip route add 192.168.111.0/24 dev "+tmpInterface+" src ${LOCAL_ADDR}" << "\n";

            // flushing SPD and SAD
            downstream << GlobalConfig->pathToSetkey << " -F" << "\n";
            downstream << GlobalConfig->pathToSetkey << " -FP" << "\n";
            downstream << "echo \"STATE: downscript finished\"" << "\n";
            downfile.close();
        } else {
            reportError(i18n("Failed to create \"%1\"." , downfile.fileName()));
            errorLine = __LINE__;
        }
    }

    if (!errorLine) {
        Utils(GlobalConfig, this).doChmod(tmpPath + "racoon-" + ProfileName + ".phase1-up.sh", "a+x");
        Utils(GlobalConfig, this).doChmod(tmpPath + "racoon-" + ProfileName + ".phase1-down.sh" , "a+x");

        if (GlobalConfig->currentProfile->getAuthType() == VpnAccountData::psk) {
            // write iptables.<profile>.sh
            QFile file(tmpPath + "psk." + ProfileName + ".key");
            QTextStream stream(&file);
            if (file.open(QIODevice::WriteOnly)) {
                stream << "# generated by kvpnc. Do not edit it." << "\n";
                stream << "# profile: " + ProfileName << "\n";

                if (GlobalConfig->currentProfile->getPskIsInFile()) {
                    stream << GlobalConfig->TmpGatewayIP + "\t" + GlobalConfig->TmpGroupPassword << "\n";
                } else {
                    if (GlobalConfig->currentProfile->getSavePsk() && !GlobalConfig->currentProfile->getPreSharedKey().isEmpty())
                        stream << GlobalConfig->TmpGatewayIP + "\t" + GlobalConfig->currentProfile->getPreSharedKey() << "\n";
                    else
                        stream << GlobalConfig->TmpGatewayIP + "\t" + GlobalConfig->TmpGroupPassword << "\n";
                }

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

    if (!errorLine) {

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

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

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

        if (useL2tpAfterFirstConnection)
            l2tpPrepare();

        Utils(GlobalConfig).doChmod(tmpPath + "psk." + GlobalConfig->currentProfile->getName() + ".key", "go-rwx");

        QStringList args;
        args.append(tmpPath + "/setkey." + GlobalConfig->currentProfile->getName() + ".sh");
        RacoonHelperProcess = new HelperProcess(this, GlobalConfig->InterpreterShell,
                                                args, *env,
                                                SLOT(readFromStdout_racoon_helper()),
                                                SLOT(readFromStderr_racoon_helper()),
                                                0, SLOT(doRacoon(int, QProcess::ExitStatus)));
        if (!RacoonHelperProcess || !RacoonHelperProcess->start())
        {
            errorLine = __LINE__;
        }
    }  //     doRacoon();


    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 RacoonHandler::vpnStop()
{
    QFile file2(tmpPath + "setkey." + GlobalConfig->currentProfile->getName() + ".remove_setkey.sh");
    QTextStream stream2(&file2);
    if (file2.open(QIODevice::WriteOnly)) {
        stream2 <<  "#!" << GlobalConfig->InterpreterShell << "\n";
        stream2 << "# generated by kvpnc. Do not edit it." << "\n";
        stream2 << "# profile: " + GlobalConfig->currentProfile->getName() << "\n";
        stream2 << GlobalConfig->pathToSetkey << " -PF" << "\n";
        stream2 << GlobalConfig->pathToSetkey << " -F" << "\n";
        file2.close();
        debugMessage(1, i18n("\"%1\" write successful." , QString("setkey (remove)")) );
    } else {
        //      KMessageBox::error( this, i18n( "\"%1\" write failed." , QString( "setkey (remove)" )) );
        errorMessage(i18n("\"%1\" write failed." , QString("setkey (remove)")));
    }

    if (RacoonctlProcess) {
        delete RacoonctlProcess;
        RacoonctlProcess = 0;
    }
    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
        //if (QFile("/var/run/l2tpd.pid").exists())
        //{
        // if (GlobalConfig->KvpncDebugLevel > 1)
        //  logMessage(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
        //{
        // if (QFile("/var/run/l2tpd.pid").exists())
        // {
        //  if (GlobalConfig->KvpncDebugLevel > 1)
        //   logMessage(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();
    }
    if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseLeftSourceIp()) {
        debugMessage(3,  i18n ( "Removing virtual IP address" ) );
        doAddRemoveVirtualIp("del");
    }

    debugMessage(3, i18n("%1 tunnel state: %2"  , QString("racoon"), (QString().setNum(racoon_tunnel_state))) );
    if (racoon_tunnel_state == 1) {
        if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseLeftSourceIp()) {
            debugMessage(3,  i18n ( "Removing virtual IP address" ) );
            doAddRemoveVirtualIp("del");
        }
        stopRacoon();
    }

    if (RacoonTailProcess) {
        delete RacoonTailProcess;
        RacoonTailProcess = 0;
    }

    if (RacoonProcess) {
        delete RacoonProcess;
        RacoonProcess = 0;
    }

    removeSetkey();
    delRouteRacoon();
    removeIptablesRacoon();

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon && (GlobalConfig->currentProfile->getL2tpDaemon() == VpnAccountData::l2tpd ||  GlobalConfig->currentProfile->getL2tpDaemon() == VpnAccountData::l2tpd)) {
        pppdSecretsRemove();
    }
}

bool RacoonHandler::getAuthenticationData(bool AuthRetry)
{
    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->getPskIsInFile() == false ) {
            askUsernamePass = false;
            askPsk = true;
        }
    }

    // L2TP/XAUTH
    if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
        if (!GlobalConfig->haveUserData) {
            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;
            GlobalConfig->haveUserData = true;
        } else {
            debugMessage(4, i18n("User data already collected."));
        }
    }

    if (AuthRetry)
        askUsernamePass = true;

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

        askUsernamePass = true;
    }

    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon && ((!GlobalConfig->currentProfile->getSaveUserPassword() && GlobalConfig->currentProfile->getUserName().isEmpty()) || GlobalConfig->currentProfile->getUserPassword().isEmpty()))
        askUsernamePass = true;

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

            if (!GlobalConfig->currentProfile->getUserName().isEmpty())
                dlg.UsernameEdit->setText(GlobalConfig->currentProfile->getUserName());
            dlg.LabelGroupPassword->setText(i18n("PSK:"));

            if (!GlobalConfig->currentProfile->getUserPassword().isEmpty())
                dlg.PasswordEdit->setText(GlobalConfig->currentProfile->getUserPassword());
            else
                dlg.PasswordEdit->setFocus();
        }
        if (askPsk) {
            if (!GlobalConfig->currentProfile->getPreSharedKey().isEmpty())
                dlg.PSKLineEdit->setText(GlobalConfig->currentProfile->getPreSharedKey());
            else if (!GlobalConfig->currentProfile->getUserPassword().isEmpty())
                dlg.PSKLineEdit->setFocus();
            if (!askUsernamePass) {
                dlg.PasswordEdit->hide();
                dlg.UsernameEdit->hide();
                dlg.LabelPassword->hide();
                dlg.LabelUsername->hide();
            }
        } 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();

            if (askPsk || AuthRetry) {

                if (GlobalConfig->currentProfile->getPreSharedKey().isEmpty() || GlobalConfig->TmpGroupPassword.isEmpty()) {
                    errorMessage(i18n("PSK is empty."));
                    return false;
                }
            }
            bool needSave = false;
            if (dlg.SaveUsernameCheckBox->isChecked()) {
                GlobalConfig->currentProfile->setDontSaveUsername(false);
                GlobalConfig->currentProfile->setUserName(dlg.UsernameEdit->text());
                needSave = true;
            } else {
                GlobalConfig->TmpUsername = dlg.UsernameEdit->text();
                GlobalConfig->currentProfile->setDontSaveUsername(true);
                needSave = true;
            }


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

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

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

void RacoonHandler::racoonOutputReader()
{
    QStringList msg_list = QString(RacoonProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        racoonParser(msg, "[racoon raw]");
    }
}

void RacoonHandler::racoonErrorReader()
{
    QStringList msg_list = QString(RacoonProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        racoonParser(msg, "[racoon err raw]");
    }
}

void RacoonHandler::racoonParser(QString msg, const QString &source)
{
    unsigned errorLine = 0;
    debugMessage(3, source + ": " + msg);

    //  if ( pingtest ) {
    //   //   if ( GlobalConfig->KvpncDebugLevel > 0 )
    //   //    mw->DebugOutput->append( "raw out (pingtest): " + msg );
    //
    //   if ( msg.indexOf( QString("time="), 0, Qt::CaseInsensitive ) > -1 ) {
    //    logMessage( "[ping] " + msg, KVpncEnum::success );
    //   } else if ( msg.indexOf( QString("100 % packet loss"), 0, Qt::CaseInsensitive ) > -1 ) {
    //    errorMessage( "[ping err] " + msg );
    //   } else {
    //    if ( msg.indexOf( QString("failed to bind"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Binding interface failed." ) );
    //     errorMessage( i18n( "Binding interface failed." )  );
    //    }
    //    if ( msg.indexOf( QString("Destination Host Unreachable"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Destination host is unreachable." ) );
    //     errorMessage( i18n( "Destination host is unreachable." )  );
    //    }
    //
    //if (GlobalConfig->KvpncDebugLevel > 0)
    //    debugMessage( "[ping] " + msg );
    //   }
    //  }
    //
    //  // normal
    //  else {



//   if (msg.indexOf ( "ERROR: ", 0, Qt::CaseInsensitive ) > -1 && msg.indexOf ( "algorithm mismatched", 0, Qt::CaseInsensitive ) > -1 )
//   {
//   KMessageBox::error( gui, i18n( "Algorithm mismatched, please select another one." ) );
//   logMessage ( i18n ( "[racoon err]: algorithm mismatched, please select another one." ) , KVpncEnum::error );
//   errorLine = __LINE__;
//   }

    if (msg.indexOf("ISAKMP-SA established", 0, Qt::CaseInsensitive) > -1) {
        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon) {
            debugMessage(0, i18n("%1: IPSec phase 1 established.", source));
        } else if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
            debugMessage(0, i18n("%1: Low level IPsec phase 1 established.", source));
        }
        racoon_tunnel_state = 1;
        if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseLeftSourceIp()) {
            debugMessage(3,  i18n ( "Adding virtual IP address" ) );
            doAddRemoveVirtualIp("add");
        }
        doPingKickupTunnel();
    } else if (msg.indexOf("IPsec-SA established", 0, Qt::CaseInsensitive) > -1) {
        racoon_tunnel_state++;
        if ( racoon_tunnel_state== 2 )
        {

            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon )
            {
                debugMessage (1, i18n("%1: IPSec phase 2 established.", source));
            }
            else if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon )
            {
                debugMessage (1, i18n("%1: Low level IPsec phase 2 established.", source));
            }

            doIptablesRacoon();
            addRouteRacoon();

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon) {
                successMessage(i18n("%1: Connection established.", source));

                // TBD: the old code deferred the setFirewallAfterConnect(), executeCommandAfterConnect()
                // addAdditionalNetworkRoutes() and startConnectionStatusCheck() till after the doIptablesRacoon()
                // and addRouteRacoon(). If we need to go back to that, we'll use a virutal callback.
                setStatusConnected(__LINE__);
                doIptablesRacoon();
                addRouteRacoon();
            }

        }

    } else if (msg.indexOf("STATE: phase1 down", 0 , Qt::CaseInsensitive ) > -1 ) {
        //KMessageBox::error ( gui, i18n ( "Phase1 expired, shutting down tunnel..." ) );
        serverError ( i18n ( "Phase1 expired, shutting down tunnel..." ));
        errorLine = __LINE__;
    }

    //  if ( pingtest ) {
    //   // mw->DebugOutput->append( "raw err (pingtest): " + msg );
    //   if ( msg.indexOf( QString("time="), 0, Qt::CaseInsensitive ) > -1 ) {
    //    logMessage( "[ping] " + msg, KVpncEnum::success );
    //   } else if ( msg.indexOf( QString("100 % packet loss"), 0, Qt::CaseInsensitive ) > -1 ) {
    //    errorMessage( "[ping err] " + msg );
    //   } else {
    //    if ( msg.indexOf( QString("failed to bind"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Binding interface failed." ) );
    //     errorMessage( i18n( "Binding interface failed." )  );
    //    }
    //    if ( msg.indexOf( QString("Destination Host Unreachable"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Destination host is unreachable." ) );
    //     errorMessage( i18n( "Destination host is unreachable." )  );
    //    }
    //   }
    //  }

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

        if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
            l2tpStop();
        }

        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);

            if (Name == "racoon") {

                //RacoonProcess->setProcessChannelMode ( QProcess::MergedChannels);
                //disconnect ( RacoonProcess, SIGNAL ( readyReadStandardOutput() ), this, SLOT ( racoonOutputReader() ) );
                //disconnect ( RacoonProcess, SIGNAL ( readyReadStandardError() ), this, SLOT ( racoonErrorReader() ) );

                if (GlobalConfig->doKillRacoonIfStillRunning && !errorLine) {
                    errorMessage(i18n("%1 could not bind to port, trying to kill it...." , QString("racoon")));

                    QProcess killracoonprocess(this);
                    QString proc = GlobalConfig->pathToKillall;
                    QStringList args;
                    args.append("racoon");
                    killracoonprocess.setEnvironment(*env);
                    killracoonprocess.start(proc, args);
                    if (!killracoonprocess.waitForStarted()) {
                        serverError(i18n("%1 could not be killed." , QString("racoon")));
                        serverError(QString(i18n("%1: Bind to given port has failed. Another %2 process is running. Please stop %2 first." , source, QString("racoon"))));
                        errorLine = __LINE__;
                    } else {
                        waitForFinished(&killracoonprocess, 100);
                        sleep(2);

                        // restart racoon
                        //       if ( RacoonProcess != 0)
                        //               {
                        //        //        RacoonProcess->kill();
                        //                delete RacoonProcess;
                        //                RacoonProcess=0L;
                        //               }

                        putenv((char*)("LC_ALL=C"));
                        QStringList args;
                        args.append("-F");    // foreground we want :)
                        //args.append( "-v" );
                        args.append("-f");
                        args.append(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".conf");
                        //args.append ( "-l" ); // logfile (we get content with tail process)
                        //args.append ( tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log" );
                        debugMessage(0, "racoon: " + GlobalConfig->pathToRacoon + " -f " + tmpPath + "/racoon" + GlobalConfig->currentProfile->getName() + ".conf");

                        RacoonProcess = new HelperProcess(this, GlobalConfig->pathToRacoon, args, *env,
                                                          SLOT(racoonOutputReader()),
                                                          SLOT(racoonErrorReader()),
                                                          0, 0);
                        if (!RacoonProcess || !RacoonProcess->start()) {
                            serverError(i18n("Failed to start \"%1\"." , QString("racoon")));

                            serverError(QString(i18n("%1: Bind to given port has failed. Another %2 process is running. Please stop %2 first." , source, QString("racoon"))));
                        } else {
                            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
                                l2tpStart();
                                debugMessage(0, i18n("%1 was already running. %2 and %3 are killed and restarted." , QString("racoon") , QString("racoon") , QString("l2tpd")));
                            } else {
                                doTailRacoonLog();
                                racoonStarted();
                                debugMessage(0, i18n("%1 was already running. It was killed and restarted." , QString("racoon")));
                            }
                        }
                    }
                } else {
                    serverError(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)));
                    errorLine = __LINE__;
                }
            } else {
                serverError(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)));
                errorLine = __LINE__;
            }
        } else {
            serverError(i18n("Port binding failed"));

            errorLine = __LINE__;
        }

    } else if (msg.indexOf("ERROR: fatal BAD-PROPOSAL-SYNTAX", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Bad proposal from peer reported, aborting."));


        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: fatal BAD-PROPOSAL-SYNTAX", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Bad proposal from peer reported, aborting."));


        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: couldn't find the pskey for", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("The pre shared key could not be found, check PSK settings."));


        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: failed to process packet.", 0, Qt::CaseInsensitive) > -1) {
        //   KMessageBox::error( gui, i18n( "failed to process packet" ) );
        errorMessage(i18n("failed to process packet"));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: phase1 negotiation failed.", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));


        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: delete phase1 handle.", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption of phase 1 and hash algorithm."));


        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: none message must be encrypted", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption of phase 1 and hash algorithm."));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: reject the packet, received unexpected payload type 0", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: unknown notify message", 0, Qt::CaseInsensitive) > -1) {
        //    KMessageBox::error( gui, i18n( "ERROR: unknown notify message, no phase2 handle found. " ) );
        errorMessage(i18n("ERROR: unknown notify message, no phase2 handle found. "));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: phase2 negotiation failed due to time up waiting for phase1", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Phase 2 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: the peer's certificate is not verified", 0, Qt::CaseInsensitive) > -1) {
        //    KMessageBox::error( gui, i18n( "ERROR: the peer's certificate is not verified" ) );
        errorMessage(i18n("ERROR: the peer's certificate is not verified"));

        errorLine = __LINE__;
    } else if (msg.indexOf("ignore information because ISAKMP-SAhas not been established yet.", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("ignore information because ISAKMP-SA has not been established yet.", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error( gui, i18n( "ERROR: fatal parse failure" ) );
        serverError(i18n("Phase 2 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

        errorLine = __LINE__;
    } else if (msg.indexOf("has weak file permission", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Wrong file permission. Aborting."));


        errorLine = __LINE__;
    } else if (msg.indexOf("IPsec-SA established", 0, Qt::CaseInsensitive) > -1) {
        racoon_tunnel_state++;
        if (racoon_tunnel_state == 1) {
            debugMessage(1, i18n("%1: First tunnel is now up, waiting for second one...", source));
            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseLeftSourceIp()) {
                debugMessage(3,  i18n ( "Adding virtual IP address" ) );
                doAddRemoveVirtualIp("add");
            }
            doPingKickupTunnel();

        } else if (racoon_tunnel_state == 2) {

            debugMessage(1, i18n("%1: Second tunnel is now up."));
            successMessage(i18n("%1: Low level IPsec connection established."));

            doIptablesRacoon();
            addRouteRacoon();

            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon) {
                debugMessage (1, i18n("%1: IPSec phase 2 established.", source));

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

                // TBD: the old code deferred the setFirewallAfterConnect(), executeCommandAfterConnect()
                // addAdditionalNetworkRoutes() and startConnectionStatusCheck() till after the doIptablesRacoon()
                // and addRouteRacoon(). If we need to go back to that, we'll use a virutal callback.
                setStatusConnected(__LINE__);
                doIptablesRacoon();
                addRouteRacoon();
            }
        }
    } else if (msg.indexOf("no default route, %defaultroute cannot cope!!!", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("No default route found, necessary for %1." , IpsecType));

        errorLine = __LINE__;
    } else if (msg.indexOf("SIOCADDRT: File exists", 0, Qt::CaseInsensitive) > -1) {
        errorMessage(i18n("%1: Setting route failed: route still exists."));
    } else if (msg.indexOf("SIOCDELRT: File exists", 0, Qt::CaseInsensitive) > -1) {
        errorMessage(i18n("%1: Deleting route failed: route does not exist."));
    } else if (msg.indexOf("fatal parse failure", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("failed to parse configuration file", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("fatal parse failure", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("Error in generated configuration file for \"%1\", please contact the KVpnc team." , QString("racoon")));

        errorLine = __LINE__;
    } else if (msg.indexOf("ERROR: ", 0, Qt::CaseInsensitive) > -1 && msg.indexOf("algorithm mismatched", 0, Qt::CaseInsensitive) > -1) {
        serverError(i18n("%1: Algorithm mismatched, please select another one.", source));
        errorLine = __LINE__;
    } else if (msg.indexOf("Error: Peer not responding", 0, Qt::CaseInsensitive) > -1) {
        //KMessageBox::error ( gui, i18n ( "racoonctl: Peer not responding" )  );
        errorMessage(i18n("racoonctl: Peer not responding", source));
        errorLine = __LINE__;
    }
    //  if ( pingtest ) {
    //   // mw->DebugOutput->append( "raw err (pingtest): " + msg );
    //   if ( msg.indexOf( QString("time="), 0, Qt::CaseInsensitive ) > -1 ) {
    //    logMessage( "[ping] " + msg, KVpncEnum::success );
    //   } else if ( msg.indexOf( QString("100 % packet loss"), 0, Qt::CaseInsensitive ) > -1 ) {
    //    errorMessage( "[ping err] " + msg );
    //   } else {
    //    if ( msg.indexOf( QString("failed to bind"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Binding interface failed!" ) );
    //     errorMessage( i18n( "Binding interface failed!" )  );
    //    }
    //    if ( msg.indexOf( QString("Destination Host Unreachable"), 0, Qt::CaseInsensitive ) > -1 ) {
    //     KMessageBox::error( gui, i18n( "Destination host is unreachable!" ) );
    //     errorMessage( i18n( "Destination host is unreachable!" )  );
    //    }
    //   }
    //  }


    if (errorLine) {
        errorMessage(i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("racoon")));
        setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
    }
}

void RacoonHandler::readFromStdout_racoon_helper()
{
    QStringList msg_list = QString(RacoonHelperProcess->readAllStandardOutput()).split('\n');
    for (QStringList::Iterator it = msg_list.begin(); it != msg_list.end(); ++it) {
        QString msg = *it;
        debugMessage(3, "[racoon helper] " + msg);
    }
}

void RacoonHandler::readFromStderr_racoon_helper()
{
    unsigned errorLine = 0;
    QStringList msg_list = QString(RacoonHelperProcess->readAllStandardError()).split('\n');
    for (QStringList::Iterator it = msg_list.begin(); it != msg_list.end(); ++it) {
        QString msg = *it;
        errorMessage("[racoon helper err] " + msg);

        bool wrong_algo = false;

        if (msg.indexOf("libipsec: syntax error while parsing", 0, Qt::CaseInsensitive) > -1 && !wrong_algo) {
            serverError(i18n("Error in generated configuration file for %1\", please contact the KVpnc team. (libipsec has found syntax error while parsing)." , QString("setkey")));
            errorLine = __LINE__;
        }
        // 		if ( ProcessMsg_connect.indexOf ( "algorithm mismatched") > -1)
        // 		{
        // 		KMessageBox::error ( gui, i18n ( "Algorithms mismatched. Please select other values for authentication and encryption." , "setkey" ) );
        // 		logMessage ( i18n ( "Algorithms mismatched. Please select other values for authentication and encryption." ) , KVpncEnum::error );
        // 		wrong_algo = true;
        // 		errorLine = __LINE__;
        // 		}
        if (msg.indexOf("invalid IP address", 0, Qt::CaseInsensitive) > -1)
        {
            serverError(i18n ( "invalid IP address", QString("setkey") ) );
            wrong_algo = true;
            errorLine = __LINE__;
        }

        if (errorLine) {
            errorMessage(i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("racoon")));
            setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
        }
    }
}

void RacoonHandler::readFromStdout_tail_racoon()
{
    unsigned errorLine = 0;
    QStringList msg_list = QString(RacoonTailProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        bool error_found = false;

        if (msg.indexOf("ERROR", 0, Qt::CaseInsensitive) > -1) {
            errorMessage("[racoon tail err] " + msg);
        } else {
            if (msg.indexOf("ERROR", 0, Qt::CaseInsensitive) == -1)
                debugMessage(3, "[racoon tail] " + msg);
        }

//   // binding to port failed
//   if ( msg.indexOf ( "ERROR: failed to bind to address", 0, Qt::CaseInsensitive ) > -1  ||   msg.indexOf ( "ERROR: no address could be bound.", 0, Qt::CaseInsensitive ) > -1)
//   {
//
//    if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon )
//    {
//     if ( L2tpdProcess != 0 && L2tpdProcess->state() == QProcess::Running )
//      L2tpdProcess->kill();
//    }
//
//    QString NameAndPid = Utils ( GlobalConfig ).getNameAndPidOfProgramListen ( 500 );
//    logMessage ( i18n ( "NameAndPid: %1" , QString(NameAndPid )) , KVpncEnum::debug );
//    int pid = -1;
//    QString Name = "";
//    if ( !NameAndPid.isEmpty() )
//    {
//     pid = NameAndPid.section ( '/', 0, 0 ).toInt();
//     Name = NameAndPid.section ( '/', 1, 1 );
//
//     if ( Name == "racoon" )
//     {
//
//      //RacoonProcess->setProcessChannelMode ( QProcess::MergedChannels );
// //      disconnect ( RacoonProcess, SIGNAL ( readyReadStandardOutput() ), this, SLOT ( racoonOutputReader() ) );
// //      disconnect ( RacoonProcess, SIGNAL ( readyReadStandardError() ), this, SLOT ( racoonErrorReader() ) );
//
//      if ( GlobalConfig->doKillRacoonIfStillRunning && abort == false )
//      {
//       if ( GlobalConfig->KvpncDebugLevel > 3 )
//        logMessage ( i18n ( "%1 could not bind to port, trying to kill it...." , QString( "racoon" )) , KVpncEnum::error );
//
//       QProcess killracoonprocess ( this );
//       QString proc = GlobalConfig->pathToKillall;
//       QStringList args;
//       args.append( "racoon" );
//       killracoonprocess.setEnvironment(*env);
//       killracoonprocess.start(proc,args);
//       if ( !killracoonprocess.waitForStarted() )
//       {
//        logMessage ( i18n ( "%1 could not be killed.", QString("racoon" )) , KVpncEnum::error );
//        logMessage ( QString ( "[racoon err] " + i18n ( "Bind to given port has been failed. Another %1 process is running. Please stop %1 first." , QString( "racoon" ) )) , KVpncEnum::error );
        //errorLine = __LINE__;
//       }
//       else
//       {
//        killracoonprocess.waitForFinished();
//         usleep ( 500 );
//
//        sleep ( 2 );
//
//        // restart racoon
//        //       if ( RacoonProcess != 0)
//        //        RacoonProcess->kill();
//
//
//        putenv ( ( char* ) ( "LC_ALL=C" ) );
//        RacoonProcess = new QProcess( this );
//    QString proc = GlobalConfig->pathToRacoon;
//    QStringList args;
//        /*args.append ( "-F" )*/; // foreground we want :)
// //        args.append ( "-v" );
//        args.append( "-f" );
//        args.append ( tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".conf" );
// //        args.append ( "-l" ); // logfile (we get content with tail process)
// //        args.append ( tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log" );
//        if ( GlobalConfig->KvpncDebugLevel > 0 )
//         logMessage ( "racoon: " + GlobalConfig->pathToRacoon + " -f " + tmpPath + "/racoon" + GlobalConfig->currentProfile->getName() + ".conf", KVpncEnum::debug );
//
//
//         //RacoonProcess->setProcessChannelMode(QProcess::MergedChannels );
// //        connect ( RacoonProcess, SIGNAL ( readyReadStandardOutput() ), this, SLOT ( racoonOutputReader() ) );
// //        connect ( RacoonProcess, SIGNAL ( readyReadStandardError() ), this, SLOT ( racoonErrorReader() ) );
//
//    RacoonProcess->setEnvironment(*env);
//    RacoonProcess->start(proc,args);
//        if ( !RacoonProcess->waitForStarted() )
//        {
//         if ( GlobalConfig->KvpncDebugLevel > 0 )
//          logMessage ( i18n ( "Failed to start \"%1\"." , QString( "racoon" )), KVpncEnum::error );
//
//         logMessage ( QString ( "[racoon err] " + i18n ( "Bind to given port has been failed. Another %1 process is running. Please stop %1 first." , QString("racoon" ) ) , KVpncEnum::error );
//         abort = false;
//        }
//        else
//        {
//         if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon )
//         {
//          start_l2tpd();
//          if ( GlobalConfig->KvpncDebugLevel > 0 )
//           logMessage ( i18n ( "%1 was already running. %2 and %3 are killed and restarted." , QString("racoon" ),QString( "racoon") , QString("l2tpd" )), KVpncEnum::debug );
//         }
//         else
//         {
//          doTailRacoonLog();
//          racoonStarted();
//          if ( GlobalConfig->KvpncDebugLevel > 0 )
//           logMessage ( i18n ( "%1 was already running. It was killed and restarted." , QString( "racoon" )), KVpncEnum::debug );
//         }
//        }
//       }
//      }
//      else
//      {
//       KMessageBox::error ( gui, i18n ( "Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first.", QString(QString().setNum ( 500 ) ), Name , QString().setNum ( pid ) ) );
//       logMessage ( i18n ( "Port binding failed" ) , KVpncEnum::error );
//       errorLine = __LINE__;
//      }
//     }
//     else
//     {
//      KMessageBox::error ( gui, i18n ( "Binding port %1 failed. Program \"%2\" with PID \"%3\" is using it. You have to stop it first." , QString(QString().setNum ( 500 ) ),  Name , QString().setNum ( pid ) ) );
//      errorLine = __LINE__;
//     }
//    }
//    else
//    {
//     KMessageBox::error ( gui, i18n ( "Port binding failed" ) );
//     logMessage ( i18n ( "Port binding failed" ) , KVpncEnum::error );
//     errorLine = __LINE__;
//    }
//
//   }

        if (msg.indexOf("ERROR: failed to bind to address", 0, Qt::CaseInsensitive) > -1  ||   msg.indexOf("ERROR: no address could be bound.", 0, Qt::CaseInsensitive) > -1) {
            errorMessage(i18n("Port binding failed"));
            errorLine = __LINE__;
        }

        else if (msg.indexOf("ERROR: couldn't find the pskey for", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("The pre shared key could not be found, check PSK settings."));


            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: failed to process packet.", 0, Qt::CaseInsensitive) > -1) {
            //   KMessageBox::error( gui, i18n( "failed to process packet" ) );
            errorMessage(i18n("failed to process packet"));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: phase1 negotiation failed.", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));


            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: delete phase1 handle.", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption of phase 1 and hash algorithm."));


            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: reject the packet, received unexpected payload type 0", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: unknown notify message", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error( gui, i18n( "ERROR: unknown notify message, no phase2 handle found. " ) );
            errorMessage(i18n("ERROR: unknown notify message, no phase2 handle found. "));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: phase2 negotiation failed due to time up waiting for phase1", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Phase 2 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: the peer's certificate is not verified", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error( gui, i18n( "ERROR: the peer's certificate is not verified" ) );
            errorMessage(i18n("ERROR: the peer's certificate is not verified"));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: no configuration found for", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error( gui, i18n( "ERROR: no configuration found" ) );
            errorMessage(i18n("ERROR: no configuration found"));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: no peer's CERT payload found.", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error( gui, i18n( "ERROR: no peer's CERT payload found." ) );
            errorMessage(i18n("ERROR: no peer's CERT payload found."));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: failed to get subjectAltName", 0, Qt::CaseInsensitive) > -1) {
            //    KMessageBox::error( gui, i18n( "ERROR: failed to get subjectAltName" ) );
            errorMessage(i18n("ERROR: failed to get subjectAltName"));

            errorLine = __LINE__;
        } else if (msg.indexOf("ERROR: such a cert type isn't supported:", 0, Qt::CaseInsensitive) > -1) {
            ////KMessageBox::error( gui, i18n( "ERROR: such a cert type is not supported:" ) );
            //logMessage ( i18n ( "ERROR: such a cert type is not supported:" ) , KVpncEnum::error );
            //
            //errorLine = __LINE__;
        } else if (msg.indexOf("ignore information because ISAKMP-SAhas not been established yet.", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("ignore information because ISAKMP-SA has not been established yet.", 0, Qt::CaseInsensitive) > -1) {
            //KMessageBox::error( gui, i18n( "ERROR: fatal parse failure" ) );
            serverError(i18n("Phase 2 negotiation of IPSec connection has failed. Please check encryption and hash algorithm."));

            errorLine = __LINE__;
        } else if (msg.indexOf("has weak file permission", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Wrong file permission. Aborting."));


            errorLine = __LINE__;
        } else if (msg.indexOf( "ERROR: fatal INVALID-ID-INFORMATION", 0 , Qt::CaseInsensitive ) > -1 ) {
            serverError(i18n ( "Peer refused ID settings. Please verify the local ID in racoon and remote network in Network - General settings." ) );

            errorLine = __LINE__;
        } else if ( msg.indexOf("STATE: phase1 up", 0 , Qt::CaseInsensitive ) > -1  ||  msg.indexOf("ISAKMP-SA established", 0 , Qt::CaseInsensitive ) > -1 ) {
            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon )
            {
                debugMessage (1, "[racoon] " + i18n ( "IPSec phase 1 established." ));
            }
            else if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon )
            {
                debugMessage (1, "[racoon] " + i18n ( "Low level IPsec phase 1 established." ));
            }
            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseLeftSourceIp()) {
                debugMessage(3,  i18n ( "Adding virtual IP address" ) );
                doAddRemoveVirtualIp("add");
            }
            doPingKickupTunnel();
        } else if ( msg.indexOf("STATE: phase1 down", 0 , Qt::CaseInsensitive ) > -1 ) {
            serverError(i18n ( "Phase 1 negotiation failed due to time up." ) );

            errorLine = __LINE__;
        } else if (msg.indexOf("IPsec-SA established", 0, Qt::CaseInsensitive) > -1 || msg.indexOf("STATE: upscript finished", 0, Qt::CaseInsensitive) > -1) {
            racoon_tunnel_state++;
            if (racoon_tunnel_state  == 1) {
                debugMessage(1, "[racoon tail] " + i18n("First tunnel is now up, waiting for second one..."));
            } else if ( racoon_tunnel_state == 2 ) {

                if (GlobalConfig->currentProfile->getUseModeConfig()) {
                    QFile ModeCfgFile(QString(tmpPath + "/racoon-" + GlobalConfig->currentProfile->getName() + ".modecfg"));
                    if (ModeCfgFile.exists()) {
                        QString TmpDns1 = "";
                        QString TmpDns2 = "";
                        QString internal_addr4 = "";
                        QString internal_netmask4 = "";
                        QString internal_cidr4 = "";
                        QString internal_dns4 = "";
                        QString internal_dns4_list = "";
                        QString internal_wins4 = "";
                        QString internal_wins4_list = "";
                        QString split_include = "";
                        QString split_local = "";
                        QString default_domain = "";
                        QString resolvtemp = "";
                        if (ModeCfgFile.open(QIODevice::ReadOnly)) {
                            QStringList contentlist = QString(ModeCfgFile.readAll()).split("\n");
                            for (int i = 0; i < contentlist.size(); ++i) {
                                QString line = contentlist.at(i);
                                debugMessage(5, "[ModeCfg] " + line);

                                QString ModeCfgVar = line.section('=', 0, 0);
                                QString ModeCfgVal = line.section('=', 1, -1);
                                if (ModeCfgVal == "INTERNAL_ADDR4")
                                    internal_addr4 = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_NETMASK4")
                                    internal_netmask4 = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_CIDR4")
                                    internal_cidr4 = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_DNS4")
                                    internal_dns4 = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_DNS4_LIST")
                                    internal_dns4_list = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_WINS4")
                                    internal_wins4 = ModeCfgVal;
                                else if (ModeCfgVal == "INTERNAL_WINS4_LIST")
                                    internal_wins4_list = ModeCfgVal;
                                else if (ModeCfgVal == "SPLIT_INCLUDE")
                                    split_include = ModeCfgVal;
                                else if (ModeCfgVal == "SPLIT_LOCAL")
                                    split_local = ModeCfgVal;
                                else if (ModeCfgVal == "DEFAULT_DOMAIN")
                                    default_domain = ModeCfgVal;
                            }
                            ModeCfgFile.close();
                        }

                        // tmp
                        TmpDns1 = internal_dns4;


                        QFile racoonupfile(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".up");
                        QTextStream racoonupstream(&racoonupfile);
                        if (racoonupfile.open(QIODevice::WriteOnly)) {
                            QString DefaultDevice = NetworkInterface(GlobalConfig, kapp).getDefaultInterface();
                            /* update dns? */
                            if (GlobalConfig->currentProfile->getUseDnsUpdate()) {
                                racoonupstream << "if [ -x /sbin/resolvconf ] ; then\n";
                                racoonupstream << " dev=$1\n";
                                racoonupstream << " if [ -z $dev ] ; then\n";
                                racoonupstream << "  dev=\"" + DefaultDevice + "\"\n";
                                racoonupstream << "fi\n";
                                bool no_nameserver=true;
                                if (!TmpDns1.isEmpty() || !TmpDns2.isEmpty()) {
                                    no_nameserver = false;
                                    racoonupstream << "if [ -x /sbin/resolvconf ] ; then\n";
                                    if (TmpDns2.isEmpty()) {
                                        racoonupstream << "echo \"nameserver " << TmpDns1 << "\"" << " " << "$dev\" > " + tmpPath + "+resolvconf." + GlobalConfig->currentProfile->getName() + "\n";
                                    } else {
                                        racoonupstream << "echo \"nameserver " << TmpDns1 << "\"\nnameserver " << TmpDns2 << " " << "$dev\" > " + tmpPath + "+resolvconf." + GlobalConfig->currentProfile->getName() + "\n";
                                    }
                                    if (no_nameserver == true) {
                                        racoonupstream << "  cat   " + tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() + " | grep nameserver >> " + tmpPath + "+resolvconf." + GlobalConfig->currentProfile->getName() + "\n";
                                    }
                                    racoonupstream << " cat   " + tmpPath + "+resolvconf." + GlobalConfig->currentProfile->getName()+ " | /sbin/resolvconf -a $dev\n";

                                    racoonupstream << "else" << "\n";
                                    racoonupstream << "  echo >> /etc/resolv.conf\n";
                                    racoonupstream << "  echo \"# generated by kvpnc. Do not edit it.\" > /etc/resolv.conf" << "\n";
                                    racoonupstream << "  echo \"# profile: " + GlobalConfig->currentProfile->getName() << "\" >> /etc/resolv.conf" << "\n";
                                    racoonupstream << "  echo \"nameserver " << TmpDns1 << "\" >> /etc/resolv.conf" << "\n";
                                    if (!TmpDns2.isEmpty())
                                        racoonupstream << "  echo \"nameserver " << TmpDns2 << "\" >> /etc/resolv.conf" << "\n";
                                    if (no_nameserver == true) {
                                        racoonupstream << "  cat " << tmpPath + "/resolv.conf.before.kvpnc_" + GlobalConfig->currentProfile->getName() + " | grep nameserver >> /etc/resolv.conf\n";
                                    }
                                    racoonupstream << "fi" << "\n";

                                }

                                QProcess pppdUpProcess(this);
                                QString proc = GlobalConfig->InterpreterShell;
                                QStringList args;
                                args.append(tmpPath + "pppd." + GlobalConfig->currentProfile->getName() + ".up");
                                pppdUpProcess.setEnvironment(*env);
                                pppdUpProcess.start(proc, args);
                                if (!pppdUpProcess.waitForStarted()) {
                                    serverError(i18n("\"%1\" (%2) start failed." , QString("PppdUpScript"), QString(tmpPath + "pppd." + GlobalConfig->currentProfile->getName() + ".up")));
                                } else {
                                    debugMessage(0, i18n("\"%1\" (%2) started." , QString("PppdUpScript"), QString(tmpPath + "pppd." + GlobalConfig->currentProfile->getName() + ".up")) );
                                    waitForFinished(&pppdUpProcess, 100);


                                    debugMessage(0, i18n("\"%1\" (%2) finished.", QString("PppdUpScript"), QString(tmpPath + "pppd." + GlobalConfig->currentProfile->getName() + ".up")) );

                                    Utils(GlobalConfig, this).doChmod(racoonupfile.fileName(), "u+x");
                                }
                            }
                        }

                    }
                }


                doIptablesRacoon();
                addRouteRacoon();

                if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon) {
                    debugMessage (1, "[racoon tail] " + i18n ( "IPSec phase 2 established." ));
                    successMessage("[racoon tail] " + i18n("Connection established."));

                    // TBD: the old code deferred the setFirewallAfterConnect(), executeCommandAfterConnect()
                    // addAdditionalNetworkRoutes() and startConnectionStatusCheck() till after the doIptablesRacoon()
                    // and addRouteRacoon(). If we need to go back to that, we'll use a virutal callback.
                    setStatusConnected(__LINE__);
                    doIptablesRacoon();
                    addRouteRacoon();
                }
                if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
                    successMessage("[racoon tail] " + i18n("Low level IPsec connection established."));
                    l2tpStart();
                }

            }
        } else if ( msg.indexOf("ISAKMP-SA expired", 0 , Qt::CaseInsensitive ) > -1 ) {
            debugMessage(3,  i18n ( "Phase1 expired" )  );
        } else if (msg.indexOf("Reading configuration from", 0, Qt::CaseInsensitive) > -1) {
//    logMessage ( i18n ( "Reading configuration from got" ) , KVpncEnum::debug );
//    sleep(3);
//       racoonStarted();
        } else if (msg.indexOf("ERROR: none message must be encrypted", 0, Qt::CaseInsensitive) > -1) {
            serverError(i18n("Phase 1 negotiation of IPSec connection has failed. Please check encryption of phase 1 and hash algorithm."));

            errorLine = __LINE__;
        } else if ( msg.indexOf("ERROR: fatal NO-PROPOSAL-CHOSEN", 0 , Qt::CaseInsensitive ) > -1 ) {
            if (!error_found)
                serverError( i18n ( "Peer reported wrong connection parameters used. Please verify the connection settings." ) );
            errorLine = __LINE__;
        } else if ( msg.indexOf("ERROR: phase1 negotiation failed due to time up.", 0 , Qt::CaseInsensitive ) > -1 ) {
            if (!error_found)
                serverError(i18n ( "Phase1 negotiation failed due to time up." ) );

            errorLine = __LINE__;
        }



        if (errorLine) {
            errorMessage(i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("racoon")));
            setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
        }

    }
}

void RacoonHandler::readFromStderr_tail_racoon()
{
    unsigned errorLine = 0;
    bool error_found =false;
    QStringList msg_list = QString(RacoonTailProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        //  if ( GlobalConfig->KvpncDebugLevel > 0 ) {
        errorMessage("[racoon tail err] " + msg);
        //}
        if ( msg.indexOf("ERROR: phase1 negotiation failed due to time up.", 0 , Qt::CaseInsensitive ) > -1 ) {
            if (!error_found)
                serverError( i18n ( "Phase1 negotiation failed due to time up." ) );
            errorLine = __LINE__;
        }
        if (errorLine)
        {
            errorMessage ( i18n ( "There is a reason for stop connecting, terminating \"%1\" process.", QString("racoon") ));
            setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
        }

    }
}

void RacoonHandler::readFromStdout_racoonctl()
{
    unsigned errorLine = 0;
    QStringList msg_list = QString(RacoonctlProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);
        debugMessage(3, "[racoonctl] " + msg);
        if (msg.indexOf("ERROR", 0, Qt::CaseInsensitive) > -1) {
            errorMessage("[racoonctl err] " + msg);
        }
        if (msg.indexOf("send: Bad file descriptor", 0, Qt::CaseInsensitive) > -1) {

            //    KMessageBox::error ( gui, i18n ( "Racoon seems to be not running." )  );
            errorMessage(i18n("Racoon seems to be not running."));

            //    if (GlobalConfig->KvpncDebugLevel > 3)
            //     logMessage ( i18n ( "Racoon seems to be not running." )  , KVpncEnum::debug );

            //    if (RacoonctlConnectCounter > 25)
            //    {
            //     logMessage ( "[racoonctl] " + i18n("Waiting for racoon needs too long"), KVpncEnum::debug );
            //     abort=true;
            //    }
            //    else
            //    {
            //
            //     if (GlobalConfig->KvpncDebugLevel > 3)
            //      logMessage ( i18n ( "Racoon seems to be not running, waiting." )  , KVpncEnum::debug );
            //
            //     // we have to give some time to sleep and try again...
            //     RacoonctlProcess->tryTerminate();
            //     sleep(2);
            //     if (RacoonctlProcess->state() == QProcess::Running)
            //     {
            //      disconnect( RacoonctlProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readFromStdout_racoonctl() ) );
            //      disconnect( RacoonctlProcess, SIGNAL( readyReadStandardError() ), this, SLOT( readFromStderr_racoonctl() ) );
            //      disconnect ( RacoonctlProcess, SIGNAL ( finished ( int, QProcess::ExitStatus )), this, SLOT(racoonctlExited(int, QProcess::ExitStatus)) ) );
            //      RacoonctlProcess->kill();
            //      sleep(1);
            //      racoonStarted();
            //     }
            //     RacoonctlConnectCounter++;
            //    }

            //    abort =true;
        } else if (msg.indexOf("racoonctl: Cannot send combuf", 0, Qt::CaseInsensitive) > -1) {
            //KMessageBox::error ( gui, i18n ( "racoonctl: Cannot send combuf" )  );
            errorMessage(i18n("racoonctl: Cannot send combuf"));
            errorLine = __LINE__;
        } else if (msg.indexOf("Error: Peer not responding", 0, Qt::CaseInsensitive) > -1) {
            //KMessageBox::error ( gui, i18n ( "racoonctl: Peer not responding" )  );
            errorMessage(i18n("racoonctl: Peer not responding"));
            errorLine = __LINE__;
        }
        if (msg.indexOf("Password:", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, "[racoonctl] " + i18n("User password requested, send it...\n"));

            QString UserPassStr = "";
            //    if ( !GlobalConfig->currentProfile->getSaveUserPassword() || AuthRetry )
            UserPassStr = GlobalConfig->TmpPassword;
            //    else
            //     UserPassStr = GlobalConfig->currentProfile->getUserPassword();

            debugMessage(8, "[racoonctl] " + i18n("User password: %1\n" , QString(UserPassStr)));


            RacoonctlProcess->write(UserPassStr.toUtf8());
            RacoonctlProcess->write("\n");
        } else if (msg.indexOf("VPN connexion terminated", 0, Qt::CaseInsensitive) > -1) {
            //KMessageBox::error ( gui, i18n ( "VPN connexion terminated" )  );
            debugMessage(0, i18n("VPN connexion terminated")  );
            errorLine = __LINE__;
        } else if (msg.indexOf("VPN connexion established", 0, Qt::CaseInsensitive) > -1) {
            // this is useless because it reports phase 1 only.
//             if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::l2tpd_racoon) {
//                 logMessage("[racoon] " + i18n("Low level connection established."), KVpncEnum::success);
//                 racoon_tunnel_state = 1;
//                 start_l2tpd();
//             } else {
//                 logMessage("[racoon] " + i18n("Connection established."), KVpncEnum::success);
//
//                 sec = hour = min = 0;
//
//                 GlobalConfig->status = KVpncEnum::connected;
//
//                 connect(&durationTimer, SIGNAL(timeout()), this, SLOT(slotDurationEvent()));
//                 durationTimer.start(1000);
//                 setGuiStatus(KVpncEnum::connected);
//
//                 setFirewallAfterConnect();
//                 if (GlobalConfig->currentProfile->getExecuteCmdAfterConnect())
//                     executeCommandAfterConnect();
//
//                 if (GlobalConfig->currentProfile->getUseAdditionalNetworkRoutes() && !GlobalConfig->currentProfile->getAdditionalNetworkRoutes().isEmpty())
//                     addAdditionalNetworkRoutes();
//
//                 if (GlobalConfig->currentProfile->getUseConnectionStatusCheck()) {
//                     startConnectionStatusCheck();
//                 }
//             }
        }
        if (errorLine) {
            errorMessage(i18n("There is a reason to stop connecting, terminating \"%1\" process." , QString("racoon")));
            setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
        }
    }
}

void RacoonHandler::readFromStderr_racoonctl()
{
    unsigned errorLine = 0;
    QStringList msg_list = QString(RacoonctlProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString msg = msg_list.at(i);

        //  if ( GlobalConfig->KvpncDebugLevel > 0 )
        errorMessage("[racoonctl err] " + msg);

        if (msg.indexOf("send: Bad file descriptor", 0, Qt::CaseInsensitive) > -1) {
//    KMessageBox::error ( gui, i18n ( "Racoon seems to be not running." )  );
            errorMessage(i18n("Racoon seems to be not running."));
//    abort =true;
        } else if (msg.indexOf("racoonctl: Cannot send combuf", 0, Qt::CaseInsensitive) > -1) {
//    KMessageBox::error ( gui, i18n ( "racoonctl: Cannot send combuf" )  );
            errorMessage(i18n("racoonctl: Cannot send combuf"));
//    abort =true;
        }
        if (msg.indexOf("Password:", 0, Qt::CaseInsensitive) > -1) {
            debugMessage(0, "[racoonctl err] " + i18n("User password requested, send it...\n"));

            QString UserPassStr = "";
//    if ( !GlobalConfig->currentProfile->getSaveUserPassword() || AuthRetry )
            UserPassStr = GlobalConfig->TmpPassword;
//    else
//     UserPassStr = GlobalConfig->currentProfile->getUserPassword();

            debugMessage(8, "[racoonctl err] " + i18n("User password: %1\n"  , QString(UserPassStr)));


            RacoonctlProcess->write(UserPassStr.toUtf8());
            RacoonctlProcess->write("\n");
        }


        if (errorLine) {
            errorMessage(i18n("There is a reason to stop connecting, terminating \"%1\" process."  , QString("racoon")));
            setStatusDisconnected(errorLine, DISCONNECTION_REASON_FATAL_ERROR);
        }
    }
}

void RacoonHandler::addRouteRacoon()
{

    //  if ( RacoonHelperProcess->normalExit () )
    {
        //   disconnect( ConnectProcess, SIGNAL( processExited () ), this, SLOT( addRouteRacoon() ) );
        //   disconnect( ConnectProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readFromStdout_racoon_helper() ) );
        //   disconnect( ConnectProcess, SIGNAL( readyReadStandardError() ), this, SLOT( readFromStderr_racoon_helper() ) );


        QString RacoonRouteSetScript = 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;

        tmpInterface = iface.getDefaultInterface();

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

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

                stream << GlobalConfig->pathToRoute << " add default gw " << GlobalConfig->currentProfile->getGateway() << " " << iface.getDefaultInterface() << "\n";
            }

            // FIXME racoon_l2tpd too?
            if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseRemoteNetwork() ) {
                if (GlobalConfig->currentProfile->getUseLeftSourceIp())
                {
                    // virtual ip
                }
                else
                {
                    stream << GlobalConfig->pathToRoute << " add -net " << RemoteNet << " " << dev << "\n";
                }
            }

            RacoonSetRouteScript.close();

            QStringList args;
            args.append(RacoonRouteSetScript);

            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 (racoon)")));
                setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
            } else {
                if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                    debugMessage(0, i18n("route (%1): route add default gw %2" , QString("racoon"), GlobalConfig->currentProfile->getGateway() + " " + tmpInterface));

                    // FIXME racoon_l2tpd too?
                    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon  && GlobalConfig->currentProfile->getUseRemoteNetwork() )
                        debugMessage(0, i18n("route (%1): route add -net %2"  , QString("racoon"), RemoteNet + " " + tmpInterface));


                    RouteProcess->waitForFinished(100000);
                    //                     int waitCounter = 0;
                    //                     while (RouteProcess->state() == QProcess::Running && waitCounter < 500) {
                    //                         usleep(100);
                    //                         waitCounter += 100;
                    //                     }
                    //                     if (waitCounter > 500 && RouteProcess->state() == QProcess::Running)
                    //                         RouteProcess->kill();
                    delete RouteProcess;
                    RouteProcess = 0L;
                }
            }
        }
    }
}

void RacoonHandler::delRouteRacoon()
{

    //  if ( DisconnectProcess != 0 )
    {
        // TBD disconnect(DisconnectProcess, SIGNAL(processExited()), this, SLOT(delRouteRacoon()));

        tmpPath = KStandardDirs::locateLocal("data", "kvpnc/");
        QString RacoonRouteSetScript = 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;

        tmpInterface = iface.getDefaultInterface();

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

        QFile RacoonSetRouteScript(RacoonRouteSetScript);
        QTextStream stream(&RacoonSetRouteScript);
        if (RacoonSetRouteScript.open(QIODevice::WriteOnly)) {
            if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                stream << GlobalConfig->pathToRoute << " del default" << "\n";
                stream << GlobalConfig->pathToIp << " route add `cat " + tmpPath + "/defaultroute_before." + GlobalConfig->currentProfile->getName() << "`" << "\n";
            }

            // FIXME racoon_l2tpd too?
            if ( GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseRemoteNetwork() ) {
                if (GlobalConfig->currentProfile->getUseLeftSourceIp())
                {
                    // virtual ip
                }
                else
                {
                    stream << GlobalConfig->pathToRoute << " del -net " << RemoteNet << " " << dev << "\n";
                }
            }

            RacoonSetRouteScript.close();

            QStringList args;
            args.append(RacoonRouteSetScript);

            //    connect( RouteProcess, SIGNAL( processExited () ), this, SLOT( removeIptablesRacoon() ) );
            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("del route (racoon)")));
                setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
            } else {
                if (GlobalConfig->currentProfile->getReplaceDefaultRoute()) {
                    debugMessage(0, i18n("route (%1): route del default gw %2"  , QString("racoon"), QString(GlobalConfig->currentProfile->getGateway() + " " + tmpInterface)));

                    // FIXME racoon_l2tpd too?
                    if (GlobalConfig->currentProfile->getConnectionType() == VpnAccountData::racoon && GlobalConfig->currentProfile->getUseRemoteNetwork() )
                        debugMessage(0, i18n("route (%1): route del -net %2"  , QString("racoon"), QString(RemoteNet + " " + tmpInterface)));
                }
                RouteProcess->waitForFinished(100000);
                //                 int waitCounter = 0;
                //                 while (RouteProcess->state() == QProcess::Running && waitCounter < 500) {
                //                     usleep(100);
                //                     waitCounter += 100;
                //                 }
                //                 if (waitCounter > 500 && RouteProcess->state() == QProcess::Running)
                //                     RouteProcess->kill();
                delete RouteProcess;
                RouteProcess = 0L;
            }

        }
    }
}

void RacoonHandler::doIptablesRacoon()
{
    //  if ( ConnectProcess->normalExit () )
    {
        //   if ( ConnectProcess )
        //    disconnect( ConnectProcess, SIGNAL( processExited () ), this, SLOT( doIptablesRacoon() ) );
        /*
        iptables -I INPUT -p 50 -i $IFACE -s $VPNGW_IP -j ACCEPT
        */
        putenv((char*)("LC_ALL=C"));
        QProcess IptablesProcess(this);
        QString proc = GlobalConfig->InterpreterShell;
        QStringList args;
        args.append(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".add_racoon.sh");

        //   connect( IptablesProcess, SIGNAL( processExited () ), this, SLOT( doRacoon() ) );
        IptablesProcess.setEnvironment(*env);
        IptablesProcess.start(proc, args);
        if (!IptablesProcess.waitForStarted()) {
            reportError(i18n("Failed to start \"%1\"."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".add_racoon.sh")));
            setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
        } else {
            debugMessage(0, i18n("\"%1\" started."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".add_racoon.sh")) );
            waitForFinished(&IptablesProcess, 100);
        }

    }
}


void RacoonHandler::doRacoon(int, QProcess::ExitStatus exitStatus)
{
    delete RacoonHelperProcess;
    RacoonHelperProcess = 0;

    if (exitStatus == QProcess::NormalExit) {
        debugMessage(0, "[racoon]: " + i18n("%1 finished." , QString("setkey")));

        /*
        /usr/sbin/racoon -f <configfile> -l <logfile>
        */
        QFile f(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log");
        if (f.exists())
            f.remove();
        QTextStream s(&f);
        if (f.open(QIODevice::WriteOnly)) {
            s << "\n";
        }
        f.close();
        s.setDevice(0);
        putenv((char*)("LC_ALL=C"));
        QStringList args;
        args.append("-F");    // foreground we want :)
        //args.append ( "-v" );
        //args.append ( "-dd" );
        args.append("-f");
        args.append(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".conf");
        args.append("-l");    // logfile (we get content with tail process)
        args.append(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log");
        debugMessage(0, "racoon: " + GlobalConfig->pathToRacoon + " -f " + tmpPath + "/racoon." + GlobalConfig->currentProfile->getName() + ".conf");

        RacoonProcess = new HelperProcess(this, GlobalConfig->pathToRacoon, args, *env,
                                          SLOT(racoonOutputReader()),
                                          SLOT(racoonErrorReader()),
                                          0, 0);
        if (!RacoonProcess || !RacoonProcess->start()) {
            reportError(i18n("Failed to start \"%1\"."  , QString("racoon")));
            setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
        } else {
            racoon_tunnel_state = 0;

            if (GlobalConfig->RacoonDebugLevel > 0)
                debugMessage(0, i18n("%1 started. " , QString("racoon")));

            doTailRacoonLog();
            sleep(3);
            racoonStarted();

            //   sec = hour = min = 0;

            //    setStatusDisconnected(errorLine);
            //   connect( &durationTimer, SIGNAL( timeout() ), this, SLOT( slotDurationEvent() ) );
            //   durationTimer.start( 1000);
        }
    } else {
        errorMessage("[racoon]: " + i18n("%1 finished with error." , QString("setkey")));
    }
}

void RacoonHandler::stopRacoon()
{
    debugMessage(2, i18n("Stopping %1." , QString("racoon")));

    putenv((char*)("LC_ALL=C"));
    QString PathToRacoonctl = "";
    ToolInfo* Tool = Utils(GlobalConfig).getToolInfo("racoonctl");
    PathToRacoonctl = Tool->PathToExec;

    QString proc = PathToRacoonctl;
    QStringList args;
    args.append("vpn-disconnect");

    args.append(GlobalConfig->TmpGatewayIP);

    RacoonctlProcess = new HelperProcess(this, PathToRacoonctl, args, *env,
                                         SLOT(readFromStdout_racoonctl()),
                                         SLOT(readFromStderr_racoonctl()),
                                         0, SLOT(racoonctlExited(int, QProcess::ExitStatus)));

    if (!RacoonctlProcess || !RacoonctlProcess->start()) {
        reportError(i18n("Failed to start \"%1\"."  , QString(QString("racoonctl vpn-disconnect " + GlobalConfig->TmpGatewayIP))));
        setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
    } else {
        debugMessage(2, i18n("%1 started. " , QString(QString("racoonctl vpn-disconnect " + GlobalConfig->TmpGatewayIP))));

        RacoonctlProcess->waitForFinished(100000);
        debugMessage(0, i18n("\"%1\" finished."  , QString(QString("racoonctl vpn-disconnect " + GlobalConfig->TmpGatewayIP))));
    }
    delete RacoonctlProcess;
    RacoonctlProcess = 0L;
}

void RacoonHandler::doTailRacoonLog()
{
    putenv((char*)("LC_ALL=C"));
    QStringList args;
    args.append("-n");
    args.append("1000");
    args.append("-f");
    args.append(tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log");

    RacoonTailProcess = new HelperProcess(this, GlobalConfig->pathToTail, args, *env,
                                          SLOT(readFromStdout_tail_racoon()),
                                          SLOT(readFromStderr_tail_racoon()),
                                          0, 0);
    if (!RacoonTailProcess || !RacoonTailProcess->start()) {
        reportError(i18n("Failed to start \"%1\"."  , QString(GlobalConfig->pathToTail + " -f " + tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log")));
        setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
    } else {
        //         status=connected;
        //         setGuiStatus(KVpncEnum::connected);

        debugMessage(0, i18n("\"%1\" started."  , QString(GlobalConfig->pathToTail + " -f " + tmpPath + "racoon." + GlobalConfig->currentProfile->getName() + ".log")));
    }
}

void RacoonHandler::removeIptablesRacoon()
{
    putenv((char*)("LC_ALL=C"));
    QProcess RemoveIptablesRacoonProcess(this);
    QString proc = GlobalConfig->InterpreterShell;
    QStringList args;
    args.append(tmpPath + "iptables." + GlobalConfig->currentProfile->getName() + ".remove_racoon.sh");
    RemoveIptablesRacoonProcess.setEnvironment(*env);
    RemoveIptablesRacoonProcess.start(proc, args);
    if (!RemoveIptablesRacoonProcess.waitForStarted()) {
        reportError(i18n("Failed to start \"%1\"."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".remove_racoon.sh")));
        setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
    } else {
        debugMessage(0, i18n("\"%1\" started."  , QString("iptables." + GlobalConfig->currentProfile->getName() + ".remove_racoon.sh")));
        waitForFinished(&RemoveIptablesRacoonProcess, 100);
    }
}


void RacoonHandler::removeSetkey()
{

    putenv((char*)("LC_ALL=C"));
    QProcess RemoveSetkeyProcess(this);
    QString proc = GlobalConfig->InterpreterShell;
    QStringList args;
    args.append(tmpPath + "setkey." + GlobalConfig->currentProfile->getName() + ".remove_setkey.sh");

    RemoveSetkeyProcess.start(proc, args);
    if (!RemoveSetkeyProcess.waitForStarted()) {
        //   KMessageBox::error( this, i18n( "Failed to start \"%1\"."  , QString("setkey (remove)" ) ));
        errorMessage(i18n("Failed to start \"%1\"."  , QString("setkey (remove)")));
    } else {
        debugMessage(1, i18n("\"%1\" started."  , QString("setkey (remove)")));
        waitForFinished(&RemoveSetkeyProcess, 100);
        debugMessage(1, i18n("\"%1\" finished."  , QString("setkey (remove)")));

    }
    //  connectionEnded();
}

QString RacoonHandler::pingDevice() const {
    return useL2tpAfterFirstConnection ? L2tpPppDevice : "";
}

void RacoonHandler::racoonStarted()
{

    debugMessage(0, i18n("Policy was successful activated and daemon (%1) is running, starting up tunnel..."  , QString("racoon")));

    bool AdminSockExist = false;
    int tryCounter = 0;
    while (!AdminSockExist && tryCounter < 20) {
        AdminSockExist = QFile("/var/run/racoon/racoon.sock").exists();
        tryCounter++;
        if (tryCounter == 20)
            break;
        else {
            tryCounter = 0;
            debugMessage(8, i18n("Waiting admin sock of %1..."  , QString("racoon")));
        }
        usleep(100);
        GlobalConfig->appPointer->processEvents();
    }

    if (tryCounter == 20) {
        errorMessage(i18n("Waiting admin sock of %1 needs too long. Stop."  , QString("racoon")));
        setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
        return;
    }

    putenv((char*)("LC_ALL=C"));
    QStringList args;
    args.append("vpn-connect");

    if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
        args.append("-u");
        args.append(GlobalConfig->TmpUsername);
    }

    args.append(GlobalConfig->TmpGatewayIP);

    RacoonctlProcess = new HelperProcess(this, GlobalConfig->pathToRacoonctl, args, *env,
                                         SLOT(readFromStdout_racoonctl()),
                                         SLOT(readFromStderr_racoonctl()),
                                         0, 0);
    if (!RacoonctlProcess || !RacoonctlProcess->start()) {
        if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword())
            reportError(i18n("Failed to start \"%1\"."  , QString("racoonctl vpn-connect -u " + GlobalConfig->TmpUsername + " " + GlobalConfig->TmpGatewayIP)));
        else
            reportError(i18n("Failed to start \"%1\"." , QString("racoonctl vpn-connect " + GlobalConfig->TmpGatewayIP)));
        setStatusDisconnected(__LINE__, DISCONNECTION_REASON_FATAL_ERROR);
    } else {
        if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword())
            debugMessage(0, i18n("\"%1\" started." , QString("racoonctl vpn-connect -u " + GlobalConfig->TmpUsername + " " + GlobalConfig->TmpGatewayIP)));
        else
            debugMessage(0, i18n("\"%1\" started.", QString("racoonctl vpn-connect " + GlobalConfig->TmpGatewayIP)));

        if (GlobalConfig->currentProfile->getAuthWithUsernameAndPassword()) {
            //    for (int waitforconnect=0;waitforconnect< 25;waitforconnect++)
            //     usleep(500);

            //    sleep(10);
            debugMessage(0, "[racoonctl] " + i18n("User password requested, send it...\n"));

            QString UserPassStr = "";
            if (!GlobalConfig->currentProfile->getSaveUserPassword() /* TBD || AuthRetry */)
                UserPassStr = GlobalConfig->TmpPassword;
            else
                UserPassStr = GlobalConfig->currentProfile->getUserPassword();

            debugMessage(8, "[racoonctl] " + i18n("User password: %1\n"  , QString(UserPassStr)));


            RacoonctlProcess->write(UserPassStr.toUtf8());
            RacoonctlProcess->write("\n");
        }

        RacoonctlProcess->waitForFinished(1000000);
        delete RacoonctlProcess;
        RacoonctlProcess = 0L;
    }

    //   else
    //   {
    //    //    setStatusDisconnected(errorLine);
    //   }
    //   logMessage( "[racoon] " + i18n( "Connection established." ), KVpncEnum::success );
    //
    //   sec = hour = min = 0;
    //
    //   GlobalConfig->status = KVpncEnum::connected;
    //
    //   connect( &durationTimer, SIGNAL( timeout() ), this, SLOT( slotDurationEvent() ) );
    //   durationTimer.start( 1000);
    //   setGuiStatus( connected );
    //
    //  setFirewallAfterConnect();
    //   if ( GlobalConfig->currentProfile->getExecuteCmdAfterConnect() )
    //    executeCommandAfterConnect();
    //
    //   if ( GlobalConfig->currentProfile->getUseAdditionalNetworkRoutes() && !GlobalConfig->currentProfile->getAdditionalNetworkRoutes().isEmpty() )
    //    addAdditionalNetworkRoutes();
    //
    //   if ( GlobalConfig->currentProfile->getUseConnectionStatusCheck() ) {
    //    startConnectionStatusCheck();
    //   }
}

void RacoonHandler::racoonctlExited(int, QProcess::ExitStatus)
{
    //     disconnect( RacoonctlProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readFromStdout_racoonctl() ) );
    //     disconnect( RacoonctlProcess, SIGNAL( readyReadStandardError() ), this, SLOT( readFromStderr_racoonctl() ) );
//     disconnect ( RacoonctlProcess, SIGNAL ( finished ( int, QProcess::ExitStatus )), this, SLOT(racoonctlExited(int, QProcess::ExitStatus)) );
}
