/***************************************************************************
*   Copyright (C) 2004 by Christoph Thielecke                             *
*   crissi99@gmx.de                                                       *
*   contains some code from openvpn-kde-dialogs.pl which is     *
*   written by  Alon Bar-Lev <alon.barlev@gmail.com>                *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
//BEGIN INCLUDES
#include "openvpnmanagementhandler.h"
#include <tqregexp.h>
#include <tqtextstream.h>
#include <kpassdlg.h>
#include <klocale.h>
#include <tqlabel.h>
#include <tqcheckbox.h>
#include <kmessagebox.h>
#include <kinputdialog.h>
#include "kvpncconfig.h"
#include "utils.h"
#include "enterxauthinteractivepasscodedialog.h"
//END INCLUDES

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

	if ( GlobalConfig->KvpncDebugLevel > 2 )
		GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: start", GlobalConfig->debug );

}

OpenvpnManagementHandler::~OpenvpnManagementHandler()
{}

void OpenvpnManagementHandler::closeConnection()
{
	if (socket)
	{
		//disconnect( socket, TQT_SIGNAL( connected() ), this, TQT_SLOT( socketConnected() ) );
		disconnect( socket, TQT_SIGNAL( connectionClosed() ), this, TQT_SLOT( socketConnectionClosed() ) );
		disconnect( socket, TQT_SIGNAL( readyRead() ), this, TQT_SLOT( socketReadyRead() ) );
		disconnect( socket, TQT_SIGNAL( error( int ) ), this, TQT_SLOT( socketError( int ) ) );
		disconnect( socket, TQT_SIGNAL( hostFound() ), this, TQT_SLOT( hostFound() ) );
		
		socket->clearPendingData();
		socket->close();
		if ( socket->state() == TQSocket::Closing )
		{
			// We have a delayed close.
			connect( socket, TQT_SIGNAL( delayedCloseFinished() ), this, TQT_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)." ).arg( TQString().setNum( GlobalConfig->OpenvpnManagementPort ) ), GlobalConfig->debug );
}

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

void OpenvpnManagementHandler::socketConnected()
{

	connect( socket, TQT_SIGNAL( connectionClosed() ), this, TQT_SLOT( socketConnectionClosed() ) );
	connect( socket, TQT_SIGNAL( readyRead() ), this, TQT_SLOT( socketReadyRead() ) );

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

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


	socketReadyRead();

}

void OpenvpnManagementHandler::socketError( int e )
{
	//         infoText->append( tr("Error number %1 occurred\n").arg(e) );
	if ( e != 0 )
		GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + TQString().setNum( e ) , GlobalConfig->error );
}

void OpenvpnManagementHandler::greetingTimedOut()
{
	disconnect ( &greetingtimer, TQT_SIGNAL ( timeout() ), this, TQT_SLOT ( greetingTimedOut() ) );
	greetingtimer.stop();

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


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

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

void OpenvpnManagementHandler::socketReadyRead()
{
	bool abort=false;
	if (socket)
	{
		if (socket->state() != TQSocket::Closing && socket->state() != TQSocket::Idle)
		{
			while ( !abort && socket->canReadLine() )
			{
				TQString line = socket->readLine();
	
				// 	{
				// 			TQCString s;
				// 					s.resize( socket->bytesAvailable() + 1 );
				// 					socket->readBlock( s.data(), socket->bytesAvailable() );
				// 					TQString line( s );
				// 					{
	
				if ( GlobalConfig->KvpncDebugLevel > 2 )
					GlobalConfig->appendLogEntry( "OpenvpnManagementHandler raw: " + line, GlobalConfig->debug );
	
	// 			if ( line.find( "NOOP", 0, FALSE ) > -1 )
	// 			{
	// 				// NOOP
	// 			}
				// 		else if ( line.find( ">HOLD:", 0, FALSE ) > -1 ) {
				//
				// 			if ( GlobalConfig->KvpncDebugLevel > 2 )
				// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message." ).arg("'hold'"), GlobalConfig->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." ), GlobalConfig->debug );
				//
				// 			socket->close();
				// 			fInHold = false;
				// 		}
	
	
				if ( line.find( "INFO:OpenVPN Management Interface", 0, FALSE ) > -1 )
				{
					gotGreeting=true;
					disconnect ( &greetingtimer, TQT_SIGNAL ( timeout() ), this, TQT_SLOT ( greetingTimedOut() ) );
					greetingtimer.stop ();
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n("Got greeting from management interface."), GlobalConfig->debug );
	
				}
				else if ( line.find( "> NEED - OK:", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("'need ok'"), GlobalConfig->debug );
	
					TQString req = line.section( TQRegExp( ".*'(.*)'. * MSG:( .* )" ), 0, 0 ); // $1;
					TQString msg = line.section( TQRegExp( ".*'(.*)'. * MSG:( .* )" ), 1, 1 ); // $2;
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( TQString("OpenvpnManagementHandler: req: ")+req+TQString(", msg: ")+msg , GlobalConfig->debug );
	
					//TODO: look for possible messages, msg2 is the translatable msg
					TQString msg2 = msg;
	
					int ret = KMessageBox::questionYesNo ( 0, msg2, i18n( "OpenVPN" ) );
	
	
					if ( ret == 0 )
					{
	
						if ( GlobalConfig->KvpncDebugLevel > 2 )
							GlobalConfig->appendLogEntry( TQString("OpenvpnManagementHandler: ") + TQString("'needok': ok") , GlobalConfig->debug );
	
						sendToServer( "needok \"" + req + "\" ok\n" );
					}
					else
					{
	
						if ( GlobalConfig->KvpncDebugLevel > 2 )
							GlobalConfig->appendLogEntry( TQString("OpenvpnManagementHandler: ") +TQString( "'needok': cancel") , GlobalConfig->debug );
	
						sendToServer( "needok \"" + req + "\" cancel\n" );
					}
					if (socket)
						socket->close();
					// if ( line.find( " >PASSWORD:", 0, FALSE ) > -1 ) {
					//
					// 			if ( GlobalConfig->KvpncDebugLevel > 2 )
					// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("'password'"), GlobalConfig->debug );
					//
					// 			TQString req = line.section( TQRegExp( ".*'(.*)'.*" ), 0, 0 ); // $1;
					// 			TQCString password;
					// 			TQString pass = "";
					// 			int result = KPasswordDialog::getPassword( password, TQString( req + i18n( " password:" ) ) );
					// 			TQTextStream os( socket );
					// 			//			os.setEncoding( TQTextStream::UnicodeUTF8 );
					// 			if ( result == KPasswordDialog::Accepted ) {
					// 				if ( GlobalConfig->KvpncDebugLevel > 2 )
					// 					GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "password got from user" ), GlobalConfig->debug );
					// 				pass = TQString( password );
					//
					// 				pass = pass.remove( '\r' );
					// 				pass = pass.remove( '\n' );
					// 			} else {
					// 				pass = "";
					// 			}
					// 			sendToServer( "password \"" + req + "\" \"" + pass + "\"\n" );
				}
				else if ( line.find( "PASSWORD:Need 'Auth' username/password", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("'need username/password'"), GlobalConfig->debug );
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send username..." ), GlobalConfig->debug );
					GlobalConfig->appendLogEntry( i18n( "Send username..." ), GlobalConfig->info );
	
					if ( !GlobalConfig->currentProfile->getUserName().isEmpty()       /* && !GlobalConfig->currentProfile->getDontSaveUsername() */ )
					{
						if ( GlobalConfig->KvpncDebugLevel > 2 )
							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: username: " + GlobalConfig->currentProfile->getUserName(), GlobalConfig->debug );
	
						sendToServer( "username Auth " + GlobalConfig->currentProfile->getUserName() + "\n" );
					}
					else
					{
						if ( GlobalConfig->TmpUsername.isEmpty() )
						{
							bool ok = false;
							TQString username = KInputDialog::getText ( i18n( "User name" ), i18n( "Enter username:" ), "", &ok );
							TQTextStream os( socket );
							os.setEncoding( TQTextStream::UnicodeUTF8 );
							if ( ok == true && !username.isEmpty() )
							{
								if ( GlobalConfig->KvpncDebugLevel > 2 )
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "username got from user" ), GlobalConfig->debug );
								GlobalConfig->TmpUsername = username;
	
								if ( GlobalConfig->KvpncDebugLevel > 5 )
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: username: " + GlobalConfig->TmpUsername, GlobalConfig->debug );
	
								sendToServer( "username Auth " + GlobalConfig->TmpUsername + "\n" );
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: username dialog canceled and username empty, stop.", GlobalConfig->info );
								abort = true;
							}
						}
						else
						{
							if ( GlobalConfig->KvpncDebugLevel > 5 )
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: username: " + GlobalConfig->TmpUsername, GlobalConfig->debug );
							sendToServer( "username Auth " + GlobalConfig->TmpUsername + "\n" );
						}
					}
				}
				else if ( line.find( "SUCCESS: 'Auth' username entered", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS: 'Auth' username entered"), GlobalConfig->debug );
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send password..." ), GlobalConfig->debug );
					GlobalConfig->appendLogEntry( i18n( "Send password..." ), GlobalConfig->info );
	
					if ( !GlobalConfig->currentProfile->getUserPassword().isEmpty()       /* && GlobalConfig->currentProfile->getSaveUserPassword()  */ )
					{
						// 				if ( GlobalConfig->KvpncDebugLevel > 5 )
						// 					GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: " +GlobalConfig->currentProfile->getUserPassword(), GlobalConfig->debug );
	
						sendToServer( "password Auth " + GlobalConfig->currentProfile->getUserPassword() + "\n" );
					}
					else
					{
						if ( GlobalConfig->TmpPassword.isEmpty() )
						{
							TQCString password;
							TQString pass = "";
							int result = KPasswordDialog::getPassword( password, TQString( i18n( " password:" ) ) );
							TQTextStream os( socket );
							//			os.setEncoding( TQTextStream::UnicodeUTF8 );
							if ( result == KPasswordDialog::Accepted )
							{
								if ( GlobalConfig->KvpncDebugLevel > 2 )
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "password got from user" ), GlobalConfig->debug );
								GlobalConfig->TmpPassword = TQString( password );
	
	
								// 						if ( GlobalConfig->KvpncDebugLevel > 5 )
								// 							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: "+GlobalConfig->TmpPassword, GlobalConfig->debug );
	
								sendToServer( "password Auth " + GlobalConfig->TmpPassword + "\n" );
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and password empty, stop.", GlobalConfig->info );
								abort = true;
							}
						}
						else
						{
							// 						if ( GlobalConfig->KvpncDebugLevel > 5 )
							// 							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: "+GlobalConfig->TmpPassword, GlobalConfig->debug );
							sendToServer( "password Auth " + GlobalConfig->TmpPassword + "\n" );
	
						}
					}
				}
	
				// 		else if ( line.find( "SUCCESS: 'Auth' username entered", 0, FALSE ) > -1 ) {
				//
				// 			if ( GlobalConfig->KvpncDebugLevel > 2 )
				// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message, 2. step" ).arg("'need username/password'"), GlobalConfig->debug );
				//
				// 			if ( GlobalConfig->KvpncDebugLevel > 2 )
				// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send password..." ), GlobalConfig->debug );
				//
				// 			if (  GlobalConfig->currentProfile->getUserPassword().isEmpty() )
				// 				sendToServer( "password Auth " + GlobalConfig->TmpPassword + "\"\n" );
				// 			else
				// 				sendToServer( "password Auth " + GlobalConfig->currentProfile->getUserPassword() + "\"\n" );
				//
				// 		}
	
				else if ( line.find( "PASSWORD:Need 'HTTP Proxy' username/password", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("'HTTP Proxy password'"), GlobalConfig->debug );
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send HTTP Proxy username..." ), GlobalConfig->debug );
					GlobalConfig->appendLogEntry( i18n( "Send HTTP Proxy username..." ), GlobalConfig->info );
	
					if ( !GlobalConfig->currentProfile->getHttpProxyUser().isEmpty() )
					{
						if ( GlobalConfig->KvpncDebugLevel > 5 )
							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: HTTP proxy user: " + GlobalConfig->currentProfile->getHttpProxyUser() , GlobalConfig->debug );
	
						sendToServer( "username  \"HTTP Proxy\"" + GlobalConfig->currentProfile->getHttpProxyUser() + "\n" );
					}
				}
	
				else if ( line.find( "SUCCESS: 'HTTP Proxy' username entered", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS: 'HTTP Proxy' username entered"), GlobalConfig->debug );
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send HTTP Proxy password..." ), GlobalConfig->debug );
					GlobalConfig->appendLogEntry( i18n( "Send HTTP Proxy password..." ), GlobalConfig->info );
	
					if ( !GlobalConfig->currentProfile->getHttpProxyPass().isEmpty() )
					{
						if ( GlobalConfig->KvpncDebugLevel > 5 )
							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->currentProfile->getHttpProxyPass(), GlobalConfig->debug );
						sendToServer( "password  \"HTTP Proxy\"" + GlobalConfig->currentProfile->getHttpProxyPass() + "\n" );
					}
					else
					{
						if ( GlobalConfig->TmpHttpProxyPassword.isEmpty() )
						{
							TQCString password;
							TQString pass = "";
	
							TQTextStream os( socket );
							os.setEncoding( TQTextStream::UnicodeUTF8 );
	
							GlobalConfig->TmpHttpProxyPassword = "";
							EnterXauthInteractivePasscodeDialog dlg( 0);
							dlg.setCaption(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" ), GlobalConfig->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" ), GlobalConfig->debug );
	
									if ( dlg.main->SavePasswordCheckBox->isChecked() )
									{
										// 								GlobalConfig->currentProfile->setSavePrivateKeyPassword(true);
										GlobalConfig->currentProfile->setHttpProxyPass ( TQString( pass ) );
									}
	
									GlobalConfig->TmpHttpProxyPassword = TQString( pass );
	
									if ( GlobalConfig->KvpncDebugLevel > 5 )
										GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->TmpHttpProxyPassword, GlobalConfig->debug );
	
									if ( GlobalConfig->KvpncDebugLevel > 2 )
										GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send HTTP proxy auth password..." ), GlobalConfig->debug );
	
									sendToServer( "password  \"HTTP Proxy\"" + GlobalConfig->TmpHttpProxyPassword + "\n" );
								}
								else
								{
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: HTTP proxy auth password empty, stop.", GlobalConfig->error );
									abort = true;
								}
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and HTTP proxy auth password empty, stop.", GlobalConfig->info );
								abort = true;
							}
						}
						else
						{
							sendToServer( "password  \"HTTP Proxy\"" + GlobalConfig->TmpHttpProxyPassword + "\n" );
							if ( GlobalConfig->KvpncDebugLevel > 5 )
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: HTTP proxy auth password: " + GlobalConfig->TmpHttpProxyPassword, GlobalConfig->debug );
								GlobalConfig->appendLogEntry( TQString( "OpenvpnManagementHandler: HTTP proxy auth password string: " ) + TQString( "password  \"HTTP Proxy\" " + GlobalConfig->TmpHttpProxyPassword + "\n" ), GlobalConfig->debug );
							}
						}
					}
				}
	
				else if ( line.find( "PASSWORD:Need 'Private Key' password", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("'private key password'"), GlobalConfig->debug );
	
					if ( !GlobalConfig->currentProfile->getPrivateKeyPass().isEmpty() )
					{
						// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
						// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send private key password..." ), GlobalConfig->debug );
					GlobalConfig->appendLogEntry( i18n( "Send private key password..." ), GlobalConfig->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 = "";
							TQCString password;
							TQString pass = "";
	
							TQTextStream os( socket );
							//			os.setEncoding( TQTextStream::UnicodeUTF8 );
	
							GlobalConfig->TmpPrivateKeyPass = "";
							EnterXauthInteractivePasscodeDialog dlg( 0);
							dlg.setCaption( 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" ), GlobalConfig->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" ), GlobalConfig->debug );
	
									if ( dlg.main->SavePasswordCheckBox->isChecked() )
									{
										GlobalConfig->currentProfile->setSavePrivateKeyPassword( true );
										GlobalConfig->currentProfile->setPrivateKeyPass( TQString( pass ) );
									}
	
									GlobalConfig->TmpPrivateKeyPass = TQString( pass );
	
									// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
									// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
	
									if ( GlobalConfig->KvpncDebugLevel > 2 )
										GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send private key password..." ), GlobalConfig->debug );
	
									sendToServer( "password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n" );
								}
								else
								{
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password empty, stop.", GlobalConfig->error );
									abort = true;
								}
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and password empty, stop.", GlobalConfig->info );
								abort = true;
							}
						}
						else
						{
							sendToServer( "password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n" );
							// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
							// 					{
							// 					GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
							// 					GlobalConfig->appendLogEntry( TQString("OpenvpnManagementHandler: private key password string: ") + TQString("password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n"),GlobalConfig->debug);
							// 					}
						}
					}
				}
	
				else if ( line.find( "PASSWORD:Verification Failed: 'Private Key'", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "wrong private key password" ), GlobalConfig->debug );
	
					GlobalConfig->TmpPassword = "";
					TQCString password;
					TQString pass = "";
	
					TQTextStream os( socket );
					//			os.setEncoding( TQTextStream::UnicodeUTF8 );
	
					GlobalConfig->TmpPrivateKeyPass = "";
					EnterXauthInteractivePasscodeDialog dlg( 0);
					dlg.setCaption(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" ), GlobalConfig->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" ), GlobalConfig->debug );
	
							if ( dlg.main->SavePasswordCheckBox->isChecked() )
							{
								GlobalConfig->currentProfile->setSavePrivateKeyPassword( true );
								GlobalConfig->currentProfile->setPrivateKeyPass( TQString( pass ) );
							}
	
							GlobalConfig->TmpPrivateKeyPass = TQString( pass );
	
							// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
							// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: private key password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
	
							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send private key password..." ), GlobalConfig->info );
	
							sendToServer( "password  \"Private Key\" " + GlobalConfig->TmpPrivateKeyPass + "\n" );
						}
						else
						{
							GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password empty, stop.", GlobalConfig->error );
							abort = true;
						}
					}
					else
					{
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and password empty, stop.", GlobalConfig->info );
						abort = true;
					}
				}
	
				else if ( line.find( "FATAL:script failed: shell command exited with error status", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: script exited with wrong status" , GlobalConfig->error );
	
					abort = true;
				}
	
				else if ( line.find( "PASSWORD:Verification Failed: 'Auth'", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password verification failed!" , GlobalConfig->error );
	
					GlobalConfig->appendLogEntry( i18n( "Authentication failed (%1)!" ).arg( i18n( "user password" ) ) , GlobalConfig->error );
	
					abort = true;
				}
	
				else if ( line.find( "FATAL:Cannot load CA certificate file", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( i18n("OpenvpnManagementHandler: CA certifcate file could not be loaded! Please check your CA certificate file.") , GlobalConfig->error );
	
					GlobalConfig->appendLogEntry( i18n( "Certificate load failed (%1)!" ).arg( i18n( "CA certificate" ) ) , GlobalConfig->error );
	
					abort = true;
				}
	
				else if ( line.find( "FATAL:Message hash algorithm", 0, FALSE ) > -1 && line.find( "not found", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 2 )
						GlobalConfig->appendLogEntry( i18n("OpenvpnManagementHandler: Hash algorithm %1 could not found! Please check your OpenVPN settings.").arg(line.section(' ',3,3).remove('\'')) , GlobalConfig->error );
	
					GlobalConfig->appendLogEntry( i18n( "Hash algorithm not found (%1)!" ).arg(line.section(' ',3,3).remove('\'') ) , GlobalConfig->error );
	
					abort = true;
				}
	
				else if ( line.find( "PASSWORD:Need 'eToken token' password", 0, FALSE ) > -1)
				{
							GlobalConfig->TmpPassword = "";
							TQCString password;
							TQString pass = "";
	
							TQTextStream os( socket );
							//			os.setEncoding( TQTextStream::UnicodeUTF8 );
	
							GlobalConfig->TmpPrivateKeyPass = "";
							EnterXauthInteractivePasscodeDialog dlg( 0);
							dlg.setCaption( i18n( "Enter token pin" ) );
							dlg.main->DescriptionLabel->setText( i18n( "Enter eToken pin for unlocking token \"%1\":" ).arg(GlobalConfig->currentProfile->getPkcs11Id()) );
							dlg.main->LabelPassword->setText( i18n( "eToken pin:" ) );
							dlg.main->SavePasswordCheckBox->hide();
							dlg.main->adjustSize();
							dlg.adjustSize();
							if ( GlobalConfig->KvpncDebugLevel > 1 )
								GlobalConfig->appendLogEntry ( "[openvpn] " + i18n( "eToken pin for unlocking token requested...\n" ), GlobalConfig->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" ), GlobalConfig->debug );
	
	
									GlobalConfig->TmpPrivateKeyPass = TQString( pass );
	
									// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
									// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
	
	
									if ( GlobalConfig->KvpncDebugLevel > 2 )
										GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send token password..." ), GlobalConfig->debug );
									GlobalConfig->appendLogEntry( i18n( "Send token password..." ), GlobalConfig->info );
									sendToServer( "password  \"eToken token\" " + GlobalConfig->TmpPrivateKeyPass + "\n" );
								}
								else
								{
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password empty, stop.", GlobalConfig->error );
									abort = true;
								}
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and password empty, stop.", GlobalConfig->info );
								abort = true;
							}
				}
	
				else if ( line.find( "SUCCESS: 'eToken token' password entered, but not yet verified", 0, FALSE ) > -1 )
				{
					if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS for 'eToken token' password"), GlobalConfig->debug );
				}
	
				else if ( line.find( ">PASSWORD:Need '", 0, FALSE) > -1 && line.find( "token' password", 0, FALSE ) > -1)
				{
							GlobalConfig->TmpPassword = "";
							TQCString password;
							TQString pass = "";
							TQString TokenName = line.section('\'',1,1);
							if ( GlobalConfig->KvpncDebugLevel > 4 )
							{
								GlobalConfig->appendLogEntry ( "[openvpn] " + i18n( "token name detected: %1\n" ).arg(TokenName), GlobalConfig->debug );
							}
	
							TQTextStream os( socket );
							//			os.setEncoding( TQTextStream::UnicodeUTF8 );
	
							GlobalConfig->TmpPrivateKeyPass = "";
							EnterXauthInteractivePasscodeDialog dlg( 0);
							dlg.setCaption( i18n( "Enter token pin" ) );
							dlg.main->DescriptionLabel->setText( i18n( "Enter pin for unlocking token \"%1\":" ).arg(GlobalConfig->currentProfile->getPkcs11Id()) );
							dlg.main->LabelPassword->setText( i18n( "PIN:" ) );
							dlg.main->SavePasswordCheckBox->hide();
							dlg.main->adjustSize();
							dlg.adjustSize();
							if ( GlobalConfig->KvpncDebugLevel > 1 )
								GlobalConfig->appendLogEntry ( "[openvpn] " + i18n( "PIN for unlocking token requested...\n" ), GlobalConfig->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" ), GlobalConfig->debug );
	
	
									GlobalConfig->TmpPrivateKeyPass = TQString( pass );
	
									// 												if ( GlobalConfig->KvpncDebugLevel > 5 )
									// 				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password: " + GlobalConfig->TmpPrivateKeyPass, GlobalConfig->debug );
	
	
									if ( GlobalConfig->KvpncDebugLevel > 2 )
										GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Send token password..." ), GlobalConfig->debug );
									GlobalConfig->appendLogEntry( i18n( "Send token password..." ), GlobalConfig->info );
									sendToServer( "password  \""+TokenName+"\" " + GlobalConfig->TmpPrivateKeyPass + "\n" );
								}
								else
								{
									GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: token password empty, stop.", GlobalConfig->error );
									abort = true;
								}
							}
							else
							{
								GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: password dialog canceled and password empty, stop.", GlobalConfig->info );
								abort = true;
							}
				}
	
				else if ( line.find( "SUCCESS: '", 0, FALSE ) > -1  && line.find( "token' password entered, but not yet verified", 0, FALSE ) > -1 )
				{
					TQString TokenName = line.section('\'',1,1);
					if ( GlobalConfig->KvpncDebugLevel > 4 )
					{
						GlobalConfig->appendLogEntry ( "[openvpn] " + i18n( "token name detected: %1\n" ).arg(TokenName), GlobalConfig->debug );
					}
					if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS for '%1' password").arg(TokenName), GlobalConfig->debug );
				}
	
				else if ( line.find( "SUCCESS: 'Auth' password entered, but not yet verified", 0, FALSE ) > -1 )
				{
					if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS for user password"), GlobalConfig->debug );
				}
	
				else if ( line.find( "Need 'token-insertion-request'", 0, FALSE ) > -1 )
				{
	// 				if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("token-insertion-request"), GlobalConfig->debug );
					KMessageBox::error ( 0, i18n("Token \"%1\" is not inserted!").arg(GlobalConfig->currentProfile->getPkcs11Id()), i18n("Token missing") );
					abort = true;
				}
	
				else if ( line.find( "SUCCESS: 'Private Key' password entered, but not yet verified", 0, FALSE ) > -1 )
				{
	
					if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got %1 message" ).arg("SUCCESS for 'Private Key' password"), GlobalConfig->debug );
				}
				else if ( line.find( "external program fork failed", 0, FALSE ) > -1 )
				{
	
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "External program fork failed, need security parameter." ), GlobalConfig->debug );
						GlobalConfig->OpenvpnNeedSecurityParameter=true;
						abort = true;
				}
				else
				{
					if ( GlobalConfig->KvpncDebugLevel > 1 )
						GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "got other management message: %1" ).arg(line), GlobalConfig->debug );
				}
				if (abort)
				{
					if (socket)
					{
						disconnect( socket, TQT_SIGNAL( connected() ), this, TQT_SLOT( socketConnected() ) );
						disconnect( socket, TQT_SIGNAL( connectionClosed() ), this, TQT_SLOT( socketConnectionClosed() ) );
						disconnect( socket, TQT_SIGNAL( readyRead() ), this, TQT_SLOT( socketReadyRead() ) );
						disconnect( socket, TQT_SIGNAL( error( int ) ), this, TQT_SLOT( socketError( int ) ) );
						disconnect( socket, TQT_SIGNAL( hostFound() ), this, TQT_SLOT( hostFound() ) );
						socket->close();
						if ( socket->state() == TQSocket::Closing )
						{
								// We have a delayed close.
								connect( socket, TQT_SIGNAL(delayedCloseFinished()), this, TQT_SLOT(socketClosed()) );
						}
						else
						{
								// The socket is closed.
								socketClosed();
								emit terminate_openvpn();
						}
					}
				}
			}
		}
		else
		{
			if ( GlobalConfig->KvpncDebugLevel > 4 )
			{
				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Socket state is strange: %1" ).arg( TQString().setNum( socket->state() ) ), GlobalConfig->debug );
			}
		}
	}
}

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

bool OpenvpnManagementHandler::doConnect()
{

	socket = 0L;
	socket = new TQSocket( this );
	if (socket)
	{
		connect( socket, TQT_SIGNAL( connected() ), this, TQT_SLOT( socketConnected() ) );
		connect( socket, TQT_SIGNAL( hostFound() ), this, TQT_SLOT( hostFound() ) );
		connect( socket, TQT_SIGNAL( error( int ) ), this, TQT_SLOT( socketError( int ) ) );
	

		if ( socket->state() == TQSocket::Idle )
		{
			if ( GlobalConfig->KvpncDebugLevel > 1 )
			{
				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler: " + i18n( "Connecting to the OpenVPN manage port (%1)..." ).arg( TQString().setNum( GlobalConfig->OpenvpnManagementPort ) ), GlobalConfig->debug );
			}
			socket->connectToHost( "127.0.0.1", GlobalConfig->OpenvpnManagementPort );
			
			connect ( &greetingtimer, TQT_SIGNAL ( timeout() ), this, TQT_SLOT ( greetingTimedOut() ) );
			greetingtimer.start ( 3 * 1000, TRUE );
		
			if ( GlobalConfig->KvpncDebugLevel > 2 )
				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler " + i18n("Management greeting timer started."), GlobalConfig->debug );
		
			return true;
		}
		else
		{
			if ( GlobalConfig->KvpncDebugLevel > 2 )
				GlobalConfig->appendLogEntry( "OpenvpnManagementHandler " + i18n("connection already in progress, skipping connect"), GlobalConfig->debug );
		
			return false;
		}
	}
	else
	{
		return false;
	 }
}

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

}
