/*****************************************************************************
 * Copyright (C) 2004-2009 Christoph Thielecke <crissi99@gmx.de>             *
 * Alon Bar-Lev <alon.barlev@gmail.com> (contains some code from             *
 * openvpn-kde-dialogs.pl)                                                   *
 *                                                                           *
 * 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 "openvpnmanagementhandler.h"

#include <QTextStream>
#include <QDataStream>
#include <QtCore/QBitArray>
#include <QtCore/QRegExp>
#include <QtGui/QCheckBox>
#include <QtGui/QLabel>
#include <QByteArray>

#include <kinputdialog.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpassworddialog.h>

#include <unistd.h>

#include "enterxauthinteractivepasscodedialog.h"
#include "utils.h"

OpenvpnManagementHandler::OpenvpnManagementHandler(QObject *, KVpncConfig *GlobalConfig)
{
    this->GlobalConfig = GlobalConfig;
    fInHold = false;
    gotGreeting = false;
    connectedToManagementPort = false;
    errormsg = "";

    if (GlobalConfig->KvpncDebugLevel > 2)
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: start", KVpncEnum::debug);
    greetingtimer = NULL;
    greetingtimer = new QTimer();

}

OpenvpnManagementHandler::~OpenvpnManagementHandler()
{
    delete greetingtimer;
}

void OpenvpnManagementHandler::closeConnection()
{
	if (socket) {
		disconnect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
		disconnect(socket, SIGNAL(connectionClosed()), this, SLOT(socketConnectionClosed()));
		disconnect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
		disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
		disconnect(socket, SIGNAL(hostFound() ), this, SLOT( hostFound() ) );
		
		socket->close();
		if (socket->state() == QTcpSocket::Closing) {
			// We have a delayed close.
			connect(socket, SIGNAL(disconnected()),
					SLOT(socketClosed()));
		} else {
			// The socket is closed.
			socketClosed();
		}
	}
}

void OpenvpnManagementHandler::socketConnectionClosed()
{


    if (GlobalConfig->KvpncDebugLevel > 1)
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Disconnected to the OpenVPN manage port (%1)." ,  QString().setNum(GlobalConfig->OpenvpnManagementPort)), KVpncEnum::debug);
}

void OpenvpnManagementHandler::socketClosed()
{
	socketReallyClosed = false;
	disconnect( socket, SIGNAL( delayedCloseFinished() ), this, SLOT( socketClosed() ) );
	delete socket;
	greetingtimer->stop();
	disconnect ( greetingtimer, SIGNAL ( timeout() ), this, SLOT ( greetingTimedOut() ) );
	
    if (GlobalConfig->KvpncDebugLevel > 1)
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Socket to the OpenVPN manage port (%1) closed." ,  QString().setNum(GlobalConfig->OpenvpnManagementPort)), KVpncEnum::debug);
	socketReallyClosed = true;
	//emit terminate_openvpn();
}

void OpenvpnManagementHandler::socketConnected()
{

    connect(socket, SIGNAL(connectionClosed()), this, SLOT(socketConnectionClosed()));
    connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));

//  KMessageBox::error ( 0, QString("bar"), QString("foo") );
    connectedToManagementPort = true;

    if (GlobalConfig->KvpncDebugLevel > 1)
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Connected to the OpenVPN manage port (%1)." ,  QString().setNum(GlobalConfig->OpenvpnManagementPort)), KVpncEnum::debug);


    socketReadyRead();

}

void OpenvpnManagementHandler::socketError(QAbstractSocket::SocketError)
{
    //         infoText->append( tr("Error number %1 occurred\n", socket->errorString()) );
    GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + socket->errorString() , KVpncEnum::error);
}

void OpenvpnManagementHandler::greetingTimedOut()
{
    disconnect(greetingtimer, SIGNAL(timeout()), this, SLOT(greetingTimedOut()));
    greetingtimer->stop();

    GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18np("Got no greeting within %1 second from management interface, retrying.", "Got no greeting within %1 seconds from management interface, retrying.", 3), KVpncEnum::error);


    closeConnection();
	while( ! socketReallyClosed ) {
		if (GlobalConfig->appPointer->hasPendingEvents())
			GlobalConfig->appPointer->processEvents();
		usleep(500);
	}
    doConnect();
}

void OpenvpnManagementHandler::sendToServer(QString cmd)
{
    // write to the server
    QTextStream os(socket);
    os << cmd << "\n";
}

void OpenvpnManagementHandler::socketReadyRead()
{
    bool abort = false;
	if (socket) {
		while (!abort && socket->canReadLine()) {
			if (socket->canReadLine()) {
				QString line = socket->readLine();

				//  {
				//    QCString s;
				//      s.resize( socket->bytesAvailable() + 1 );
				//      socket->read( s.data(), socket->bytesAvailable() );
				//      QString line( s );
				//      {

				if (GlobalConfig->KvpncDebugLevel > 2)
					GlobalConfig->appendLogEntry("OpenvpnManagementHandler raw: " + line, KVpncEnum::debug);

	//    if ( line.indexOf( "NOOP", 0, false ) > -1 )
	//    {
	//     // NOOP
	//    }
				//   else if ( line.indexOf( ">HOLD:", 0, false ) > -1 ) {
				//
				//    if ( GlobalConfig->KvpncDebugLevel > 2 )
				//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message." , QString("'hold'")), KVpncEnum::debug );
				//
				//    fInHold = true;
				//    int ret = 0;
				//    do {
				//     ret = KMessageBox::questionYesNo ( 0, i18n( "Release hold?" ), i18n( "OpenVPN" ) );
				//    } while ( ret != 0 );
				//
				//    sendToServer( "hold release\n" );
				//
				//    if ( GlobalConfig->KvpncDebugLevel > 2 )
				//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "hold release sent." ), KVpncEnum::debug );
				//
				//    socket->close();
				//    fInHold = false;
				//   }


				if (line.indexOf("INFO:OpenVPN Management Interface", 0, Qt::CaseInsensitive) > -1) {
					gotGreeting = true;
					disconnect(greetingtimer, SIGNAL(timeout()), this, SLOT(greetingTimedOut()));
					greetingtimer->stop();

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Got greeting from management interface."), KVpncEnum::debug);

				} else if (line.indexOf("> NEED - OK:", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("'need ok'")), KVpncEnum::debug);

					QString req = line.section(QRegExp(".*'(.*)'. * MSG:( .* )"), 0, 0);       // $1;
					QString msg = line.section(QRegExp(".*'(.*)'. * MSG:( .* )"), 1, 1);       // $2;

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry(QString("OpenvpnManagementHandler: req: ") + req + QString(", msg: ") + msg , KVpncEnum::debug);

					//TODO: look for possible messages, msg2 is the translatable msg
					QString msg2 = msg;

					int ret = KMessageBox::questionYesNo(0, msg2, i18n("OpenVPN"));


					if (ret == 0) {

						if (GlobalConfig->KvpncDebugLevel > 2)
							GlobalConfig->appendLogEntry(QString("OpenvpnManagementHandler: ") + QString("'needok': ok") , KVpncEnum::debug);

						sendToServer("needok \"" + req + "\" ok\n");
					} else {

						if (GlobalConfig->KvpncDebugLevel > 2)
							GlobalConfig->appendLogEntry(QString("OpenvpnManagementHandler: ") + QString("'needok': cancel") , KVpncEnum::debug);

						sendToServer("needok \"" + req + "\" cancel\n");
					}
					socket->close();
					// if ( line.indexOf( " >PASSWORD:", 0, Qt::CaseInsensitive ) > -1 ) {
					//
					//    if ( GlobalConfig->KvpncDebugLevel > 2 )
					//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" , QString("'password'")), KVpncEnum::debug );
					//
					//    QString req = line.section( QRegExp( ".*'(.*)'.*" ), 0, 0 ); // $1;
					//    QCString password;
					//    QString pass = "";
					//    int result = KPasswordDialog::getPassword( password, QString( req + i18n( " password:" ) ) );
					//    QTextStream os( socket );
					//    //   os.setEncoding( QTextStream::UnicodeUTF8 );
					//    if ( result == KPasswordDialog::Accepted ) {
					//     if ( GlobalConfig->KvpncDebugLevel > 2 )
					//      GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "password got from user" ), KVpncEnum::debug );
					//     pass = QString( password );
					//
					//     pass = pass.remove( '\r' );
					//     pass = pass.remove( '\n' );
					//    } else {
					//     pass = "";
					//    }
					//    sendToServer( "password \"" + req + "\" \"" + pass + "\"\n" );
				}

				else if (line.indexOf("PASSWORD:Need 'Auth' username/password", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("'need username/password'")), KVpncEnum::debug);

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send username..."), KVpncEnum::debug);
					GlobalConfig->appendLogEntry(i18n("Send username..."), KVpncEnum::info);

					if (!GlobalConfig->currentProfile->getUserName().isEmpty()       /* && !GlobalConfig->currentProfile->getDontSaveUsername() */) {
						if (GlobalConfig->KvpncDebugLevel > 2)
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: username: " + GlobalConfig->currentProfile->getUserName(), KVpncEnum::debug);

						sendToServer("username Auth " + GlobalConfig->currentProfile->getUserName() + "\n");
					} else {
						if (GlobalConfig->TmpUsername.isEmpty()) {
							bool ok = false;
							QString username = KInputDialog::getText(i18n("Username"), i18n("Enter username:"), "", &ok);
							QTextStream os(socket);
							os.setCodec("UTF-8");
							if (ok == true && !username.isEmpty()) {
								if (GlobalConfig->KvpncDebugLevel > 2)
									GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("username got from user"), KVpncEnum::debug);
								GlobalConfig->TmpUsername = username;

								if (GlobalConfig->KvpncDebugLevel > 5)
									GlobalConfig->appendLogEntry("OpenvpnManagementHandler: username: " + GlobalConfig->TmpUsername, KVpncEnum::debug);

								sendToServer("username Auth " + GlobalConfig->TmpUsername + "\n");
							} else {
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: username dialog canceled and username empty, stop.", KVpncEnum::info);
								abort = true;
							}
						} else {
							if (GlobalConfig->KvpncDebugLevel > 5)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: username: " + GlobalConfig->TmpUsername, KVpncEnum::debug);
							sendToServer("username Auth " + GlobalConfig->TmpUsername + "\n");
						}
					}
				}

				else if (line.indexOf("SUCCESS: 'Auth' username entered", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("SUCCESS: 'Auth' username entered")), KVpncEnum::debug);

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send password..."), KVpncEnum::debug);
					GlobalConfig->appendLogEntry(i18n("Send password..."), KVpncEnum::info);

					if (!GlobalConfig->currentProfile->getUserPassword().isEmpty()       /* && GlobalConfig->currentProfile->getSaveUserPassword()  */) {
						//     if ( GlobalConfig->KvpncDebugLevel > 5 )
						//      GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: " +GlobalConfig->currentProfile->getUserPassword(), KVpncEnum::debug );

						sendToServer("password Auth " + GlobalConfig->currentProfile->getUserPassword() + "\n");
					} else {
						if (GlobalConfig->TmpPassword.isEmpty()) {
							QString password;
							KPasswordDialog dlg((QWidget *) 0);
							dlg.setPrompt(i18n(" password:"));
							int result = dlg.exec();
							QTextStream os(socket);
							//   os.setEncoding( QTextStream::UnicodeUTF8 );
							if (result == KPasswordDialog::Accepted) {
								password = dlg.password();
								if (GlobalConfig->KvpncDebugLevel > 2)
									GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("password got from user"), KVpncEnum::debug);
								GlobalConfig->TmpPassword = QString(password);


								//       if ( GlobalConfig->KvpncDebugLevel > 5 )
								//        GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: "+GlobalConfig->TmpPassword, KVpncEnum::debug );

								sendToServer("password Auth " + GlobalConfig->TmpPassword + "\n");
							} else {
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and password empty, stop.", KVpncEnum::info);
								abort = true;
							}
						} else {
							//       if ( GlobalConfig->KvpncDebugLevel > 5 )
							//        GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: "+GlobalConfig->TmpPassword, KVpncEnum::debug );
							sendToServer("password Auth " + GlobalConfig->TmpPassword + "\n");

						}
					}
				}

				//   else if ( line.indexOf( "SUCCESS: 'Auth' username entered", 0, false ) > -1 ) {
				//
				//    if ( GlobalConfig->KvpncDebugLevel > 2 )
				//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message, 2. step" , QString("'need username/password'")), KVpncEnum::debug );
				//
				//    if ( GlobalConfig->KvpncDebugLevel > 2 )
				//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send password..." ), KVpncEnum::debug );
				//
				//    if (  GlobalConfig->currentProfile->getUserPassword().isEmpty() )
				//     sendToServer( "password Auth " + GlobalConfig->TmpPassword + "\"\n" );
				//    else
				//     sendToServer( "password Auth " + GlobalConfig->currentProfile->getUserPassword() + "\"\n" );
				//
				//   }

				else if (line.indexOf("PASSWORD:Need 'HTTP Proxy' username/password", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("'HTTP Proxy password'")), KVpncEnum::debug);

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send HTTP Proxy username..."), KVpncEnum::debug);
					GlobalConfig->appendLogEntry(i18n("Send HTTP Proxy username..."), KVpncEnum::info);

					if (!GlobalConfig->currentProfile->getHttpProxyUser().isEmpty()) {
						if (GlobalConfig->KvpncDebugLevel > 5)
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: HTTP proxy user: " + GlobalConfig->currentProfile->getHttpProxyUser() , KVpncEnum::debug);

						sendToServer("username  \"HTTP Proxy\"" + GlobalConfig->currentProfile->getHttpProxyUser() + "\n");
					}
				}

				else if (line.indexOf("SUCCESS: 'HTTP Proxy' username entered", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("SUCCESS: 'HTTP Proxy' username entered")), KVpncEnum::debug);

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send HTTP Proxy password..."), KVpncEnum::debug);
					GlobalConfig->appendLogEntry(i18n("Send HTTP Proxy password..."), KVpncEnum::info);

					if (!GlobalConfig->currentProfile->getHttpProxyPass().isEmpty()) {
						if (GlobalConfig->KvpncDebugLevel > 5)
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->currentProfile->getHttpProxyPass(), KVpncEnum::debug);
						sendToServer("password  \"HTTP Proxy\"" + GlobalConfig->currentProfile->getHttpProxyPass() + "\n");
					} else {
						if (GlobalConfig->TmpHttpProxyPassword.isEmpty()) {
							QByteArray password;
							QString pass = "";

							QTextStream os(socket);
							os.setCodec("UTF-8");

							GlobalConfig->TmpHttpProxyPassword = "";
							EnterXauthInteractivePasscodeDialog dlg(0);
							dlg.setWindowTitle( i18n("Enter HTTP proxy auth password"));
							dlg.main->DescriptionLabel->setText(i18n("Enter HTTP proxy auth password:"));
							dlg.main->LabelPassword->setText(i18n("HTTP proxy auth password:"));
							dlg.main->SavePasswordCheckBox->setText(i18n("Save HTTP proxy auth password"));
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry("[openvpn] " + i18n("HTTP proxy auth password requested...\n"), KVpncEnum::debug);
							if (dlg.exec()) {

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

									if (GlobalConfig->KvpncDebugLevel > 2)
										GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("HTTP proxy auth password got from user"), KVpncEnum::debug);

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

									GlobalConfig->TmpHttpProxyPassword = QString(pass);

									if (GlobalConfig->KvpncDebugLevel > 5)
										GlobalConfig->appendLogEntry("OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->TmpHttpProxyPassword, KVpncEnum::debug);

									if (GlobalConfig->KvpncDebugLevel > 2)
										GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send HTTP proxy auth password..."), KVpncEnum::debug);

									sendToServer("password  \"HTTP Proxy\"" + GlobalConfig->TmpHttpProxyPassword + "\n");
								} else {
									GlobalConfig->appendLogEntry("OpenvpnManagementHandler: HTTP proxy auth password empty, stop.", KVpncEnum::error);
									abort = true;
								}
							} else {
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and HTTP proxy auth password empty, stop.", KVpncEnum::info);
								abort = true;
							}
						} else {
							sendToServer("password  \"HTTP Proxy\"" + GlobalConfig->TmpHttpProxyPassword + "\n");
							if (GlobalConfig->KvpncDebugLevel > 5) {
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->TmpHttpProxyPassword, KVpncEnum::debug);
								GlobalConfig->appendLogEntry(QString("OpenvpnManagementHandler: HTTP proxy auth password string: ") + QString("password  \"HTTP Proxy\" " + GlobalConfig->TmpHttpProxyPassword + "\n"), KVpncEnum::debug);
							}
						}
					}
				}

				else if (line.indexOf("PASSWORD:Need 'Private Key' password", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("'private key password'")), KVpncEnum::debug);

					if (!GlobalConfig->currentProfile->getPrivateKeyPass().isEmpty()) {
						//             if ( GlobalConfig->KvpncDebugLevel > 5 )
						//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );

						if (GlobalConfig->KvpncDebugLevel > 2)
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send private key password..."), KVpncEnum::debug);
						GlobalConfig->appendLogEntry(i18n("Send private key password..."), KVpncEnum::info);

						sendToServer("password  \"Private Key\" " + GlobalConfig->currentProfile->getPrivateKeyPass() + "\n");
					} else {
						if ((Utils(GlobalConfig).getNeedsPassphrase(GlobalConfig->TmpPrivateKeyPass) && GlobalConfig->TmpPrivateKeyPass.isEmpty()) || GlobalConfig->currentProfile->getPrivateKeyPass().isEmpty()) {
							GlobalConfig->TmpPassword = "";
							QByteArray password;
							QString pass = "";

							QTextStream os(socket);
							//   os.setEncoding( QTextStream::UnicodeUTF8 );

							GlobalConfig->TmpPrivateKeyPass = "";
							EnterXauthInteractivePasscodeDialog dlg(0);
							dlg.setWindowTitle(i18n("Enter private key password"));
							dlg.main->DescriptionLabel->setText(i18n("Enter private key password to unlock private key:"));
							dlg.main->LabelPassword->setText(i18n("Private key password:"));
							dlg.main->SavePasswordCheckBox->setText(i18n("Save private key password"));
							dlg.resize(600, 200);
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry("[openvpn] " + i18n("Password for private key requested...\n"), KVpncEnum::debug);
							if (dlg.exec()) {

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

									if (GlobalConfig->KvpncDebugLevel > 2)
										GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("private key password got from user"), KVpncEnum::debug);

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

									GlobalConfig->TmpPrivateKeyPass = QString(pass);

									//             if ( GlobalConfig->KvpncDebugLevel > 5 )
									//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );

									if (GlobalConfig->KvpncDebugLevel > 2)
										GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send private key password..."), KVpncEnum::debug);

									sendToServer("password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n");
								} else {
									GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password empty, stop.", KVpncEnum::error);
									abort = true;
								}
							} else {
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and password empty, stop.", KVpncEnum::info);
								abort = true;
							}
						} else {
							sendToServer("password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n");
							//             if ( GlobalConfig->KvpncDebugLevel > 5 )
							//      {
							//      GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );
							//      GlobalConfig->appendLogEntry( QString("OpenvpnManagementHandler: private key password string: ") + QString("password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n"),KVpncEnum::debug);
							//      }
						}
					}
				}

				else if (line.indexOf("PASSWORD:Verification Failed: 'Private Key'", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("wrong private key password"), KVpncEnum::debug);

					GlobalConfig->TmpPassword = "";
					QByteArray password;
					QString pass = "";

					QTextStream os(socket);
					//   os.setEncoding( QTextStream::UnicodeUTF8 );

					GlobalConfig->TmpPrivateKeyPass = "";
					EnterXauthInteractivePasscodeDialog dlg(0);
					dlg.setWindowTitle(i18n("Enter private key password"));
					dlg.main->DescriptionLabel->setText(i18n("Enter private key password to unlock private key:"));
					dlg.main->LabelPassword->setText(i18n("Private key password:"));
					dlg.main->SavePasswordCheckBox->setText(i18n("Save private key password"));
					if (GlobalConfig->KvpncDebugLevel > 0)
						GlobalConfig->appendLogEntry("[openvpn] " + i18n("Password for private key requested...\n"), KVpncEnum::debug);
					if (dlg.exec()) {
						pass = dlg.main->PasswordEdit->text();

						if (!pass.isEmpty()) {

							if (GlobalConfig->KvpncDebugLevel > 2)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("private key password got from user"), KVpncEnum::debug);

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

							GlobalConfig->TmpPrivateKeyPass = QString(pass);

							//             if ( GlobalConfig->KvpncDebugLevel > 5 )
							//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );

							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send private key password..."), KVpncEnum::info);

							sendToServer("password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n");
						} else {
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password empty, stop.", KVpncEnum::error);
							abort = true;
						}
					} else {
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and password empty, stop.", KVpncEnum::info);
						abort = true;
					}
				}

				else if (line.indexOf("FATAL:script failed: shell command exited with error status", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: script exited with wrong status" , KVpncEnum::error);

					abort = true;
				}

				else if (line.indexOf("PASSWORD:Verification Failed: 'Auth'", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password verification failed!" , KVpncEnum::error);

					GlobalConfig->appendLogEntry(i18n("Authentication failed (%1)." ,  i18n("user password")) , KVpncEnum::error);

					abort = true;
				}

				else if (line.indexOf("FATAL:Cannot load CA certificate file", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry(i18n("OpenvpnManagementHandler: CA certificate file could not be loaded. Please check your CA certificate file.") , KVpncEnum::error);

					GlobalConfig->appendLogEntry(i18n("Certificate load failed (%1)." ,  i18n("CA certificate")) , KVpncEnum::error);

					abort = true;
				}

				else if (line.indexOf("FATAL:Message hash algorithm", 0, Qt::CaseInsensitive) > -1 && line.indexOf("not found", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 2)
						GlobalConfig->appendLogEntry(i18n("OpenvpnManagementHandler: Hash algorithm %1 could not be found. Please check your OpenVPN settings.", line.section(' ', 3, 3).remove('\'')) , KVpncEnum::error);

					GlobalConfig->appendLogEntry(i18n("Hash algorithm not found (%1)." , line.section(' ', 3, 3).remove('\'')) , KVpncEnum::error);

					abort = true;
				}

				else if (line.indexOf("PASSWORD:Need 'eToken token' password", 0, Qt::CaseInsensitive) > -1) {
					GlobalConfig->TmpPassword = "";
					QByteArray password;
					QString pass = "";

					QTextStream os(socket);
					//   os.setEncoding( QTextStream::UnicodeUTF8 );

					GlobalConfig->TmpPrivateKeyPass = "";
					EnterXauthInteractivePasscodeDialog dlg(0);
					dlg.setWindowTitle(i18n("Enter token pin"));
					dlg.main->DescriptionLabel->setText(i18n("Enter eToken pin for unlocking token \"%1\":" , GlobalConfig->currentProfile->getPkcs11Id()));
					dlg.main->LabelPassword->setText(i18n("eToken pin:"));
					dlg.main->SavePasswordCheckBox->hide();
					dlg.adjustSize();
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("[openvpn] " + i18n("eToken pin for unlocking token requested...\n"), KVpncEnum::debug);
					if (dlg.exec()) {

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

							if (GlobalConfig->KvpncDebugLevel > 1)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("token password got from user"), KVpncEnum::debug);


							GlobalConfig->TmpPrivateKeyPass = QString(pass);

							//             if ( GlobalConfig->KvpncDebugLevel > 5 )
							//     GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );


							if (GlobalConfig->KvpncDebugLevel > 2)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send token password..."), KVpncEnum::debug);
							GlobalConfig->appendLogEntry(i18n("Send token password..."), KVpncEnum::info);
							sendToServer("password  \"eToken token\" " + GlobalConfig->TmpPrivateKeyPass + "\n");
						} else {
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: token password empty, stop.", KVpncEnum::error);
							abort = true;
						}
					} else {
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and password empty, stop.", KVpncEnum::info);
						abort = true;
					}
				}

				else if (line.indexOf("SUCCESS: 'eToken token' password entered, but not yet verified", 0, Qt::CaseInsensitive) > -1) {
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("SUCCESS for 'eToken token' password")), KVpncEnum::debug);
				} else if (line.indexOf(">PASSWORD:Need '", 0, Qt::CaseInsensitive) > -1 && line.indexOf("token' password", 0, Qt::CaseInsensitive) > -1) {
					GlobalConfig->TmpPassword = "";
					QByteArray password;
					QString pass = "";
					QString TokenName = line.section('\'', 1, 1);
					if (GlobalConfig->KvpncDebugLevel > 4) {
						GlobalConfig->appendLogEntry("[openvpn] " + i18n("token name detected: %1\n" , TokenName), KVpncEnum::debug);
					}

					QTextStream os(socket);
					//                      os.setEncoding( QTextStream::UnicodeUTF8 );

					GlobalConfig->TmpPrivateKeyPass = "";
					EnterXauthInteractivePasscodeDialog dlg(0);
					dlg.setWindowTitle(i18n("Enter token pin"));
					dlg.main->DescriptionLabel->setText(i18n("Enter pin for unlocking token \"%1\":" , GlobalConfig->currentProfile->getPkcs11Id()));
					dlg.main->LabelPassword->setText(i18n("PIN:"));
					dlg.main->SavePasswordCheckBox->hide();
					dlg.adjustSize();
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("[openvpn] " + i18n("PIN for unlocking token requested...\n"), KVpncEnum::debug);
					if (dlg.exec()) {

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

							if (GlobalConfig->KvpncDebugLevel > 1)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("token password got from user"), KVpncEnum::debug);


							GlobalConfig->TmpPrivateKeyPass = QString(pass);

							//                                                                                              if ( GlobalConfig->KvpncDebugLevel > 5 )
							//                              GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password: " + GlobalConfig->TmpPrivateKeyPass, KVpncEnum::debug );


							if (GlobalConfig->KvpncDebugLevel > 2)
								GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Send token password..."), KVpncEnum::debug);
							GlobalConfig->appendLogEntry(i18n("Send token password..."), KVpncEnum::info);
							sendToServer("password  \"" + TokenName + "\" " + GlobalConfig->TmpPrivateKeyPass + "\n");
						} else {
							GlobalConfig->appendLogEntry("OpenvpnManagementHandler: token password empty, stop.", KVpncEnum::error);
							abort = true;
						}
					} else {
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: password dialog canceled and password empty, stop.", KVpncEnum::info);
						abort = true;
					}
				}

				else if (line.indexOf("SUCCESS: '", 0, Qt::CaseInsensitive) > -1  && line.indexOf("token' password entered, but not yet verified", 0, Qt::CaseInsensitive) > -1) {
					QString TokenName = line.section('\'', 1, 1);
					if (GlobalConfig->KvpncDebugLevel > 4) {
						GlobalConfig->appendLogEntry("[openvpn] " + i18n("token name detected: %1\n", TokenName), KVpncEnum::debug);
					}
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message", QString("SUCCESS for '%1' password").arg(TokenName)), KVpncEnum::debug);
				}

				else if (line.indexOf("SUCCESS: 'Auth' password entered, but not yet verified", 0, Qt::CaseInsensitive) > -1) {
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("SUCCESS for user password")), KVpncEnum::debug);
				}

				else if (line.indexOf("Need 'token-insertion-request'", 0, Qt::CaseInsensitive) > -1) {
	//     if ( GlobalConfig->KvpncDebugLevel > 1 )
					GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("token-insertion-request")), KVpncEnum::debug);
					KMessageBox::error(0, i18n("Token \"%1\" is not inserted.", GlobalConfig->currentProfile->getPkcs11Id()), i18n("Token missing"));
					abort = true;
				}

				else if (line.indexOf("SUCCESS: 'Private Key' password entered, but not yet verified", 0, Qt::CaseInsensitive) > -1) {

					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got %1 message" , QString("SUCCESS for 'Private Key' password")), KVpncEnum::debug);
				} else if (line.indexOf("external program fork failed", 0, Qt::CaseInsensitive) > -1) {

					GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("External program fork failed, need security parameter."), KVpncEnum::debug);
					GlobalConfig->OpenvpnNeedSecurityParameter = true;
					abort = true;
				}




				else {
					if (GlobalConfig->KvpncDebugLevel > 1)
						GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("got other management message: %1" , line), KVpncEnum::debug);
				}
			}
			if (abort) {
				disconnect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
				disconnect(socket, SIGNAL(connectionClosed()), this, SLOT(socketConnectionClosed()));
				disconnect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
				disconnect(socket, SIGNAL(error(int)), this, SLOT(socketError(int)));
				disconnect(socket, SIGNAL( hostFound() ), this, SLOT( hostFound() ) );
				
				socket->close();
				if (socket->state() == QTcpSocket::Closing) {
					// We have a delayed close.
					connect(socket, SIGNAL(disconnected()),
							SLOT(socketClosed()));
				} else {
					// The socket is closed.
					socketClosed();
					emit terminate_openvpn();
				}
			}
		}
	}
}

bool OpenvpnManagementHandler::isConnectedToManagementPort()
{
    return connectedToManagementPort;
}

bool OpenvpnManagementHandler::doConnect()
{


    socket = new QTcpSocket(this);
    connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
    connect(socket, SIGNAL(hostFound()), this, SLOT(hostFound()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));

    if (GlobalConfig->KvpncDebugLevel > 1) {
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Connecting to the OpenVPN manage port (%1)..." ,  QString().setNum(GlobalConfig->OpenvpnManagementPort)), KVpncEnum::debug);
    }

    socket->connectToHost("127.0.0.1", GlobalConfig->OpenvpnManagementPort);

//  for (int i=1;i <= 10;i++)
//  {
//   sleep(1);
//   if (!connectedToManagementPort)
//   {
//   if ( GlobalConfig->KvpncDebugLevel > 1 )
//    GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Connecting to the OpenVPN manage port (%1)..." , QString(QString().setNum( GlobalConfig->OpenvpnManagementPort ) )), KVpncEnum::debug);
//   }
//   else
//    return true;
//  }

//  return false;

    connect(greetingtimer, SIGNAL(timeout()), this, SLOT(greetingTimedOut()));
    greetingtimer->start(3 * 1000);

    if (GlobalConfig->KvpncDebugLevel > 2)
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler " + i18n("Management greeting timer started."), KVpncEnum::debug);

    return true;
}

void OpenvpnManagementHandler::hostFound()
{
//  KMessageBox::error ( 0, QString("bar"), QString("foo") );
    if (GlobalConfig->KvpncDebugLevel > 1) {
        GlobalConfig->appendLogEntry("OpenvpnManagementHandler: " + i18n("Connecting to the OpenVPN manage port (%1)... host found" ,  QString().setNum(GlobalConfig->OpenvpnManagementPort)), KVpncEnum::debug);
    }

}
