/*****************************************************************************
 * Copyright (C) 2004-2009 Christoph Thielecke <crissi99@gmx.de>             *
 *                                                                           *
 * 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 "ciscocertificateenrollment.h"

#include <QtCore/QObject>
#include <QtGui/QCursor>

#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpassworddialog.h>
#include <kstandarddirs.h>
#include <kiconloader.h>

#include <unistd.h>

#include "utils.h"

#if defined(QWIZARD_QT4_PORT)
CiscoCertificateEnrollment::CiscoCertificateEnrollment(const QString &text,
                                                       KVpncConfig *GlobalConfig,
                                                       QWidget *parent)
    : QWizard(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;
    ciscoCertMgr = globalConfiguration->pathToCiscoCertMgr;

    setPage(Page_Intro, new IntroductionPage(globalConfiguration));
    setPage(Page_OnlineMethod, new OnlineMethodPage(globalConfiguration));
    setPage(Page_FileMethod, new FileMethodPage(globalConfiguration));
    setPage(Page_CertificateDetails, new CertificateDetailsPage(globalConfiguration));
    setPage(Page_Conclusion, new ConclusionPage(globalConfiguration));

    setStartId(Page_Intro);

#ifndef Q_WS_MAC
    setWizardStyle(ModernStyle);
#endif

    setPixmap(QWizard::LogoPixmap,
              QPixmap(KIconLoader::global()->loadIcon("kvpnc", KIconLoader::Dialog)));

    setWindowTitle(text);

    setDefaultProperty("KComboBox", "currentIndex", SIGNAL(currentIndexChanged(int)));
    setDefaultProperty("KUrlRequester", "text", SIGNAL(textChanged(QString)));
}

CiscoCertificateEnrollment::~CiscoCertificateEnrollment()
{
    delete ciscoCertMgrProcess;
}

void CiscoCertificateEnrollment::accept()
{
    ciscoCertMgrProcess = new QProcess(this);
    connect(ciscoCertMgrProcess, SIGNAL(readyReadStandardOutput()),
            this, SLOT(slotReadyReadStdout()));
    connect(ciscoCertMgrProcess, SIGNAL(readyReadStandardError()),
            this, SLOT(slotReadyReadStderr()));
    QStringList arguments;

    bool online = field("online").toBool();
    if (online) {
        /* enroll for a certificate over the network (SCEP) */
        arguments << "-U -op enroll"
                  << "-caurl" << field("caUrl").toString()
                  << "-cadn" << field("caDomain").toString();
    } else {
        /* generate an enrollment request file */
        arguments << "-U -op enroll_file"
                  << "-f" << field("fileName").toString()
                  << "-enc" << field("fileEncoding").toString();
    }

    QString commonName = field("commonName").toString();
    if (!commonName.isEmpty()) {
        arguments << "-cn" << field("commonName").toString();
    }

    QString organizationalUnit = field("organizationalUnit").toString();
    if (!organizationalUnit.isEmpty()) {
        arguments << "-ou" << organizationalUnit;
    }

    QString organization = field("organization").toString();
    if (!organization.isEmpty()) {
        arguments << "-o" << organization;
    }

    QString state = field("state").toString();
    if (!state.isEmpty()) {
        arguments << "-st" << state;
    }

    QString country = field("country").toString();
    if (!country.isEmpty()) {
        arguments << "-c" << country;
    }

    QString email = field("email").toString();
    if (!email.isEmpty()) {
        arguments << "-e" << email;
    }

    QString ipAddress = field("ipAddress").toString();
    if (!ipAddress.isEmpty()) {
        arguments << "-ip" << ipAddress;
    }

    QString domainName = field("domainName").toString();
    if (!domainName.isEmpty()) {
        arguments << "-dn" << domainName;
    }

    ciscoCertMgrProcess->start(ciscoCertMgr, arguments);
    if (ciscoCertMgrProcess->waitForFinished()) {
        QDialog::accept();
    }
}

void CiscoCertificateEnrollment::slotReadyReadStdout()
{
    stdoutbuf += ciscoCertMgrProcess->readAllStandardOutput();
    processStdOut();
}

void CiscoCertificateEnrollment::processStdOut()
{
    QStringList lineList;
    int pos;
    while ( (pos = stdoutbuf.indexOf('\n')) != -1) {
        if (pos > 0 && stdoutbuf.at(pos - 1) == '\r') {
            lineList << QString::fromLocal8Bit(stdoutbuf, pos - 1);
        } else {
            lineList << QString::fromLocal8Bit(stdoutbuf, pos);
        }
        stdoutbuf.remove(0, pos+1);
    }
}

void CiscoCertificateEnrollment::slotReadyReadStderr()
{
    stderrbuf += ciscoCertMgrProcess->readAllStandardError();
    processStdErr();
}

void CiscoCertificateEnrollment::processStdErr()
{
    QStringList lineList;
    int pos;
    while ( (pos = stderrbuf.indexOf('\n')) != -1) {
        if (pos > 0 && stderrbuf.at(pos - 1) == '\r') {
            lineList << QString::fromLocal8Bit(stderrbuf, pos - 1);
        } else {
            lineList << QString::fromLocal8Bit(stderrbuf, pos);
        }
        stderrbuf.remove(0, pos+1);
    }
}

IntroductionPage::IntroductionPage(KVpncConfig *GlobalConfig, QWidget *parent)
    : QWizardPage(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;

    setTitle(i18n("Introduction"));
    setPixmap(QWizard::WatermarkPixmap,
              QPixmap(KStandardDirs::locate("data", "kvpnc/newprofilewizard.png")));

    topLabel = new QLabel(i18n("This wizard will help you to enroll your Cisco certificate.\n\n"
                               "Please select your enrollment method:"));
    topLabel->setWordWrap(true);

    onlineRadioButton = new QRadioButton(i18n("&Online"));
    onlineRadioButton->setChecked(true);

    fileRadioButton = new QRadioButton("Fi&le");

    registerField("online", onlineRadioButton);
    registerField("file", fileRadioButton);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(topLabel);
    layout->addWidget(onlineRadioButton);
    layout->addWidget(fileRadioButton);
    setLayout(layout);
}

int IntroductionPage::nextId() const
{
    if (onlineRadioButton->isChecked()) {
        return CiscoCertificateEnrollment::Page_OnlineMethod;
    } else {
        return CiscoCertificateEnrollment::Page_FileMethod;
    }
}

OnlineMethodPage::OnlineMethodPage(KVpncConfig *GlobalConfig, QWidget *parent)
    : QWizardPage(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;

    setTitle(i18n("Online Enrollment Method"));
    setSubTitle(i18n("Enter your online enrollment method details"));

    caLabel = new QLabel(i18n("Certificate authority"));
    caComboBox = new KComboBox();

    caUrlLabel = new QLabel(i18n("CA URL"));
    caUrlLineEdit = new KLineEdit();

    caDomainLabel = new QLabel(i18n("CA domain"));
    caDomainLineEdit = new KLineEdit();

    caChallengePhraseLabel = new QLabel(i18n("Challenge phrase"));
    caChallengePhraseLineEdit = new KLineEdit();
    caChallengePhraseLineEdit->setPasswordMode(true);

    registerField("ca", caComboBox);
    registerField("caUrl*", caUrlLineEdit);
    registerField("caDomain*", caDomainLineEdit);
    registerField("caChallengehrase*", caChallengePhraseLineEdit);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(caLabel, 0, 0);
    layout->addWidget(caComboBox, 0, 1);
    layout->addWidget(caUrlLabel, 1, 0);
    layout->addWidget(caUrlLineEdit, 1, 1);
    layout->addWidget(caDomainLabel, 2, 0);
    layout->addWidget(caDomainLineEdit, 2, 1);
    layout->addWidget(caChallengePhraseLabel, 3, 0);
    layout->addWidget(caChallengePhraseLineEdit, 3, 1);
    setLayout(layout);
}

int OnlineMethodPage::nextId() const
{
    return CiscoCertificateEnrollment::Page_CertificateDetails;
}

FileMethodPage::FileMethodPage(KVpncConfig *GlobalConfig, QWidget *parent)
    : QWizardPage(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;

    setTitle(i18n("File Enrollment Method"));
    setSubTitle(i18n("Enter your file enrollment method details"));

    fileEncodingLabel = new QLabel(i18n("File encoding"));
    QStringList fileEncodingList;
    fileEncodingList << "base64" << "binary";
    fileEncodingComboBox = new KComboBox();
    fileEncodingComboBox->insertItems(0, fileEncodingList);
	fileEncodingComboBox->model()->sort(0);
    fileNameLabel = new QLabel(i18n("File name"));
    fileNameUrlRequester = new KUrlRequester();

    newPasswordLabel = new QLabel(i18n("New password"));
    newPasswordLineEdit = new KLineEdit();

    registerField("fileEncoding", fileEncodingComboBox);
    registerField("fileName", fileNameUrlRequester);
    registerField("newPassword*", newPasswordLineEdit);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(fileEncodingLabel, 0, 0);
    layout->addWidget(fileEncodingComboBox, 0, 1);
    layout->addWidget(fileNameLabel, 1, 0);
    layout->addWidget(fileNameUrlRequester, 1, 1);
    layout->addWidget(newPasswordLabel, 2, 0);
    layout->addWidget(newPasswordLineEdit, 2, 1);
    setLayout(layout);
}

int FileMethodPage::nextId() const
{
    return CiscoCertificateEnrollment::Page_CertificateDetails;
}

CertificateDetailsPage::CertificateDetailsPage(KVpncConfig *GlobalConfig, QWidget *parent)
    : QWizardPage(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;

    setTitle(i18n("Certificate Details"));
    setSubTitle(i18n("Enter your certificate details"));

    commonNameLabel = new QLabel(i18n("Common name (CN)"));
    commonNameLineEdit = new KLineEdit();
    organizationalUnitLabel = new QLabel(i18n("Organizational unit (OU)"));
    organizationalUnitLineEdit = new KLineEdit();
    organizationLabel = new QLabel(i18n("Organization (O)"));
    organizationLineEdit = new KLineEdit();
    stateLabel = new QLabel(i18n("State (ST)"));
    stateLineEdit = new KLineEdit();
    countryLabel = new QLabel(i18n("Country (C)"));
    countryLineEdit = new KLineEdit();
    emailLabel = new QLabel(i18n("Email (E)"));
    emailLineEdit = new KLineEdit();
    ipAddressLabel = new QLabel(i18n("IP address (IP)"));
    ipAddressLineEdit = new KLineEdit();
    domainNameLabel = new QLabel(i18n("Domain name (DN)"));
    domainNameLineEdit = new KLineEdit();

    registerField("commonName*", commonNameLineEdit);
    registerField("organizationalUnit", organizationalUnitLineEdit);
    registerField("organization", organizationLineEdit);
    registerField("state", stateLineEdit);
    registerField("country", countryLineEdit);
    registerField("email", emailLineEdit);
    registerField("ipAddress", ipAddressLineEdit);
    registerField("domainName", domainNameLineEdit);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(commonNameLabel, 0, 0);
    layout->addWidget(commonNameLineEdit, 0, 1);
    layout->addWidget(organizationalUnitLabel, 1, 0);
    layout->addWidget(organizationalUnitLineEdit, 1, 1);
    layout->addWidget(organizationLabel, 2, 0);
    layout->addWidget(organizationLineEdit, 2, 1);
    layout->addWidget(stateLabel, 3, 0);
    layout->addWidget(stateLineEdit, 3, 1);
    layout->addWidget(countryLabel, 4, 0);
    layout->addWidget(countryLineEdit, 4, 1);
    layout->addWidget(emailLabel, 5, 0);
    layout->addWidget(emailLineEdit, 5, 1);
    layout->addWidget(ipAddressLabel, 6, 0);
    layout->addWidget(ipAddressLineEdit, 6, 1);
    layout->addWidget(domainNameLabel, 7, 0);
    layout->addWidget(domainNameLineEdit, 7, 1);
    setLayout(layout);
}

int CertificateDetailsPage::nextId() const
{
    return CiscoCertificateEnrollment::Page_Conclusion;
}

ConclusionPage::ConclusionPage(KVpncConfig *GlobalConfig, QWidget *parent)
    : QWizardPage(parent)
{
    globalConfiguration = GlobalConfig;
    debugLevel = globalConfiguration->KvpncDebugLevel;

    setTitle(i18n("Conclusion"));
    setPixmap(QWizard::WatermarkPixmap,
              QPixmap(KStandardDirs::locate("data", "kvpnc/newprofilewizard_final.png")));

    label = new QLabel();
    label->setWordWrap(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(label);
    setLayout(layout);
}

void ConclusionPage::initializePage()
{
    QString finishText = wizard()->buttonText(QWizard::FinishButton);
    finishText.remove('&');
    label->setText(i18n("Click %1 to enroll your Cisco certificate.").arg(finishText));
}
#else
CiscoCertificateEnrollment::CiscoCertificateEnrollment(const QString &text, KVpncConfig *GlobalConfig, QWidget *parent)
    : Q3Wizard(parent)
{
    this->GlobalConfig = GlobalConfig;
    valuesOk = true;
    type = "";
    CA = "";
    CaUrl = "";
    ChallengePassword = "";
    CaDomain = "";
    FileEncoding = "";
    FilenameURL = "";
    Ip = "";
    State = "";
    Department = "";
    Company = "";
    Domain = "";
    Name = "";
    Email = "";
    Country = "";

    success = 0;
    successmsg = "";
    EnrollmentProcess = 0;
    GlobalConfig->appPointer->setOverrideCursor(QCursor(Qt::WaitCursor));
    setupPages();
    GlobalConfig->appPointer->restoreOverrideCursor();
}

CiscoCertificateEnrollment::~CiscoCertificateEnrollment()
{
    delete selectionpage;
    delete datapage;
}

void CiscoCertificateEnrollment::accept()
{
    finished = true;
    Q3Wizard::accept();
}

void CiscoCertificateEnrollment::canAccept()
{
    QDialog::accept();
}

void CiscoCertificateEnrollment::reject()
{
    if (GlobalConfig->KvpncDebugLevel > 2)
        GlobalConfig->appendLogEntry(i18n("Enrollment break requested, user cancelled."), KVpncEnum::debug);

    if (EnrollmentProcess != 0 && DeleteProcess->state() == QProcess::Running) {
        EnrollmentProcess->terminate();
        QTimer::singleShot(2000, EnrollmentProcess, SLOT(kill()));

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Process %1 killed." ,  QString("cisco_cert_mgr")), KVpncEnum::debug);
    }
    finished = false;
    Q3Wizard::reject();
}

void CiscoCertificateEnrollment::setupPages()
{
    selectionpage = new CiscoCertificateEnrollmentWidget(this);

//  selectionpage->main->sizeHint();
    addPage((QWidget *)selectionpage, "<b>" + i18n("Select enrollment type...") + "</b>");

    connect(selectionpage->main->FileEnrollementRadioButton, SIGNAL(toggled(bool)), this, SLOT(enrollmentToggled(bool)));
    connect(selectionpage->main->OnlineEnrollementRadioButton, SIGNAL(toggled(bool)), this, SLOT(enrollmentToggled(bool)));

    int CiscoCaCertIdx = 0;
    GlobalConfig->slotStatusMsg(i18n("Collecting cisco CA certs from Cisco certificate store..."), ID_STATUS_MSG);
    if (GlobalConfig->KvpncDebugLevel > 2)
        GlobalConfig->appendLogEntry(i18n("Looking for CA certs in Cisco certificate store..."), KVpncEnum::debug);
    QStringList CiscoCaCerts ;// = Utils(GlobalConfig).getCertsFromCiscoCertStore("ca");
    if (GlobalConfig->KvpncDebugLevel > 2)
        GlobalConfig->appendLogEntry(i18n("Done."), KVpncEnum::debug);
    GlobalConfig->slotStatusMsg(i18n("Done."), ID_FLASH_MSG);
    GlobalConfig->slotStatusMsg(i18n("Ready."), ID_STATUS_MSG);
    for (QStringList::Iterator it = CiscoCaCerts.begin(); it != CiscoCaCerts.end(); ++it) {
        selectionpage->main->CAComboBox->insertItem(CiscoCaCertIdx, QString(*it));
        CiscoCaCertIdx++;
    }
    selectionpage->main->CAComboBox->model()->sort(0);

    datapage = new CiscoCertificateEnrollmentDataDialog(0, "datapage", GlobalConfig);
//  datapage->sizeHint();
    addPage((QWidget *)datapage, "<b>" + i18n("Enter certificate data...") + "</b>");

    finishpage = new CiscoCertificateEnrollmentFinishWidget(this);

//  finishpage->main->sizeHint();
    addPage((QWidget *)finishpage, "<b>" + i18n("Finish") + "</b>");
	resize(800,600);
}

void CiscoCertificateEnrollment::next()
{
    // called at each finish of a page
    bool ok = true;
    QString msg = i18n("Please fill in all fields.");
    msg = i18n("These fields must be filled in:\n");
    if (currentpage == (QWidget *)selectionpage) {
        if (selectionpage->main->FileEnrollementRadioButton->isChecked()) {
            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("Enrollment type: %1" ,   i18n("File")), KVpncEnum::debug);
            type = "file";

            if (selectionpage->main->FilenameURLRequester->url().isEmpty()) {
                ok = false;
                msg += "- " + i18n("Filename") + "\n";
                GlobalConfig->appendLogEntry(i18n("Filename is empty."), KVpncEnum::error);
            } else {
                if (GlobalConfig->KvpncDebugLevel > 2)
                    GlobalConfig->appendLogEntry(i18n("Filename: %1" ,   selectionpage->main->FilenameURLRequester->url().toLocalFile()), KVpncEnum::debug);
                FilenameURL = selectionpage->main->FilenameURLRequester->url().toLocalFile();
            }

            if (selectionpage->main->NewPasswordPasswordEdit->text().isEmpty()) {
                ok = false;
                msg += "- " + i18n("Password") + "\n";
                GlobalConfig->appendLogEntry(i18n("Password is empty."), KVpncEnum::error);
            } else {
                if (GlobalConfig->KvpncDebugLevel > 2 && GlobalConfig->KvpncDebugLevel < 4)
                    GlobalConfig->appendLogEntry(i18n("Password: %1" ,   QString("******")), KVpncEnum::debug);

                else if (GlobalConfig->KvpncDebugLevel > 4)
                    GlobalConfig->appendLogEntry(i18nc("cleartext means the password is visible", "Password (cleartext): %1" ,   selectionpage->main->NewPasswordPasswordEdit->text()), KVpncEnum::debug);
                ChallengePassword = QString(selectionpage->main->NewPasswordPasswordEdit->text());
            }

            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("File encoding: %1" ,   selectionpage->main->FileEncodingComboBox->currentText()), KVpncEnum::debug);
            FileEncoding = selectionpage->main->FileEncodingComboBox->currentText();
        }
        if (selectionpage->main->OnlineEnrollementRadioButton->isChecked()) {
            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("Enrollment type: %1" ,   i18n("Online")), KVpncEnum::debug);
            type = "online";

            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("CA: %1" ,   selectionpage->main->CAComboBox->currentText()), KVpncEnum::debug);
            CA = selectionpage->main->CAComboBox->currentText();

            if (selectionpage->main->CaUrlLineEdit->text().isEmpty()) {
                ok = false;
                msg += "- " + i18n("CA URL") + "\n";
                GlobalConfig->appendLogEntry(i18n("CA URL is empty."), KVpncEnum::error);
            } else {
                if (GlobalConfig->KvpncDebugLevel > 2)
                    GlobalConfig->appendLogEntry(i18n("CA URL: %1" ,   selectionpage->main->CaUrlLineEdit->text()), KVpncEnum::debug);
                CaUrl = selectionpage->main->CaUrlLineEdit->text();
            }

            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("CA domain: %1" ,   selectionpage->main->CaDomainLineEdit->text()), KVpncEnum::debug);
            CaDomain = selectionpage->main->CaDomainLineEdit->text();

            if (selectionpage->main->ChallengePasswordPasswordEdit->text().isEmpty()) {
                ok = false;
                msg += "- " + i18n("Challenge password") + "\n";
                GlobalConfig->appendLogEntry(i18n("Challenge password is empty."), KVpncEnum::error);
            } else {
                if (GlobalConfig->KvpncDebugLevel > 2  && GlobalConfig->KvpncDebugLevel < 4)
                    GlobalConfig->appendLogEntry(i18n("Challenge password: %1" ,  QString("*****")), KVpncEnum::debug);

                else if (GlobalConfig->KvpncDebugLevel > 4)
                    GlobalConfig->appendLogEntry(i18nc("cleartext means the password is visible", "Challenge password (cleartext): %1" ,   selectionpage->main->ChallengePasswordPasswordEdit->text()), KVpncEnum::debug);
                ChallengePassword = QString(selectionpage->main->ChallengePasswordPasswordEdit->text());
            }
        }
    }

    if (currentpage == (QWidget *)datapage) {
        if (datapage->main->NameLineEdit->text().isEmpty()) {
            ok = false;
            msg += "- " + i18n("Name") + "\n";
            GlobalConfig->appendLogEntry(i18n("Name is empty."), KVpncEnum::error);
        } else {
            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("Name: %1" ,   datapage->main->NameLineEdit->text()), KVpncEnum::debug);
            Name = datapage->main->NameLineEdit->text();
        }

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("IP address: %1" ,   datapage->main->IpLineEdit->text()), KVpncEnum::debug);
        Ip = datapage->main->IpLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("State: %1" ,   datapage->main->StateLineEdit->text()), KVpncEnum::debug);
        State = datapage->main->StateLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Department: %1" ,   datapage->main->DepartmentLineEdit->text()), KVpncEnum::debug);
        Department = datapage->main->DepartmentLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Company: %1" ,   datapage->main->CompanyLineEdit->text()), KVpncEnum::debug);
        Company = datapage->main->CompanyLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Domain: %1" ,   datapage->main->DomainLineEdit->text()), KVpncEnum::debug);
        Domain = datapage->main->DomainLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Email: %1" ,   datapage->main->EmailLineEdit->text()), KVpncEnum::debug);
        Email = datapage->main->EmailLineEdit->text();

        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Country: %1" ,   datapage->main->CountryLineEdit->text()), KVpncEnum::debug);
        Country = datapage->main->CountryLineEdit->text();

        // now do the work
        successmsg = i18n("Enrollment was successful.");
        success = 0;
        QString bin = "cisco_cert_mgr";

        if (!GlobalConfig->ToolList->isEmpty()) {
            for (int toolIdx = 0; toolIdx < GlobalConfig->ToolList->size(); ++toolIdx) {
                if (bin == GlobalConfig->ToolList->at(toolIdx)->Name) {
                    if (GlobalConfig->ToolList->at(toolIdx)->PathToExec.section('/', -1) != bin) {
                        // program is NOT installed
                        KMessageBox::information(this, i18n("The required tool (%1) is not installed, please install it before you are connecting and restart kvpnc." ,   bin), i18n("Tool Missing"));
                        GlobalConfig->appPointer->restoreOverrideCursor();
                        return;
                    }
                    break;
                }
            }
        }

        GlobalConfig->appPointer->setOverrideCursor(QCursor(Qt::WaitCursor));

        env = new QStringList();
        *env << "LC_ALL=C" << "LANG=C" << "PATH=/bin:/usr/bin:/usr/sbin:/sbin";

        EnrollmentProcess = new QProcess(this);
        QString proc = GlobalConfig->pathToCiscoCertMgr;
        QStringList args;

        if (type == "file") {
            args.append("-U");
            args.append("-op");
            args.append("enroll_file");
            args.append("-f");
            args.append(FilenameURL);
            args.append("-cn");
            args.append(Name);
            args.append("-enc");
            args.append(FileEncoding);
        }

        if (type == "online") {
            args.append("-U");
            args.append("-op");
            args.append("enroll");
            args.append("-cn");
            args.append(Name);
            args.append("-caurl");
            args.append(CaUrl);
            args.append("-cadn");
            args.append(CaDomain);

            if (!Department.isEmpty()) {
                args.append("-ou");
                args.append(Department);
            }

            if (!State.isEmpty()) {
                args.append("-st");
                args.append(State);
            }
            if (!Company.isEmpty()) {
                args.append("-o");
                args.append(Company);
            }
            if (!Domain.isEmpty()) {
                args.append("-dn");
                args.append(Domain);
            }
            if (!Email.isEmpty()) {
                args.append("-e");
                args.append(Email);
            }
            if (!Country.isEmpty()) {
                args.append("-c");
                args.append(Country);
            }
            if (!Ip.isEmpty()) {
                args.append("-ip");
                args.append(Ip);
            }
        }

        connect(EnrollmentProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()));
        connect(EnrollmentProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr()));
        connect(EnrollmentProcess, SIGNAL(finished(int, QProcess::ExitStatus)) , this, SLOT(enrollmentProcessFinished(int, QProcess::ExitStatus)));

        if (GlobalConfig->KvpncDebugLevel > 3)
            GlobalConfig->appendLogEntry(i18n("EnrollmentProcess args: ") + args.join(" "), KVpncEnum::debug);

        EnrollmentProcess->setEnvironment(*env);
        EnrollmentProcess->start(proc, args);
        if (!EnrollmentProcess->waitForStarted()) {
            KMessageBox::sorry(this, i18n("Unable to start process (%1)." ,   QString("cisco_cert_mgr")));
            GlobalConfig->appendLogEntry(i18n("Unable to start process (%1)." ,   QString("cisco_cert_mgr")), KVpncEnum::error);
            GlobalConfig->appPointer->restoreOverrideCursor();
            return;
        } else {
            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("Process %1 started." ,   QString("cisco_cert_mgr")), KVpncEnum::debug);

            ProgressDlg = new KProgressDialog((QWidget *)0, i18n("Enrollment progress"), i18n("Certificate enrollment..."));
            ProgressDlg->progressBar()->setMinimum(0);
            ProgressDlg->progressBar()->setMaximum(100);
            ProgressDlg->setAllowCancel(true);
            ProgressDlg->show();
            ProgressDlg->resize(ProgressDlg->width() + 100, ProgressDlg->height());

            connect(&CheckEnrollmentTimer, SIGNAL(timeout()), this, SLOT(checkProgress()));
            CheckEnrollmentTimer.setSingleShot(false);
            CheckEnrollmentTimer.start(500);

            if (ProgressDlg != 0)
                ProgressDlg->progressBar()->setValue(33);

        }
    }

    if (currentpage == (QWidget *)finishpage) {
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Enrollment finished: %1." ,   successmsg), KVpncEnum::debug);
    }

    if (ok) {
        previouspage = currentpage;
        Q3Wizard::next();
    } else {
        KMessageBox::error(this, msg);
    }
}

void CiscoCertificateEnrollment::back()
{
    Q3Wizard::back();
}

void CiscoCertificateEnrollment::showPage(QWidget* page)
{
    currentpage = page;
    Q3Wizard::showPage(page);

    // FIXME set currentpage at back()
    //backButton()->setEnabled(false);

    helpButton() ->setEnabled(false);

    if (page == (QWidget *)finishpage) {
        finishpage->main->successTextLabel->setText(successmsg);
    }
}

void CiscoCertificateEnrollment::enrollmentProcessFinished(int, QProcess::ExitStatus)
{
    disconnect(EnrollmentProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()));
    disconnect(EnrollmentProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr()));
    disconnect(EnrollmentProcess, SIGNAL(finished(int, QProcess::ExitStatus)) , this, SLOT(cancelProcessFinished(int, QProcess::ExitStatus)));

    if (ProgressDlg != 0)
        ProgressDlg->progressBar()->setValue(100);

    GlobalConfig->appPointer->restoreOverrideCursor();
    finishpage->main->successTextLabel->setText(successmsg);
    finishButton() ->setEnabled(true);
    finishButton() ->setFocus();
    ProgressDlg->hide();
//  delete ProgressDlg;
//  delete EnrollmentProcess;
}

void CiscoCertificateEnrollment::enrollmentToggled(bool)
{
    if (selectionpage->main->FileEnrollementRadioButton->isChecked()) {
        selectionpage->main->CaTextLabel->setEnabled(false);
        selectionpage->main->CAComboBox->setEnabled(false);
        selectionpage->main->CaUrlLineEdit->setEnabled(false);
        selectionpage->main->CaUrlTextLabel->setEnabled(false);
        selectionpage->main->ChallengePasswordTextLabel->setEnabled(false);
        selectionpage->main->ChallengePasswordPasswordEdit->setEnabled(false);
        selectionpage->main->CaDomainTextLabel->setEnabled(false);
        selectionpage->main->CaDomainLineEdit->setEnabled(false);

        selectionpage->main->FilenameTextLabel->setEnabled(true);
        selectionpage->main->FilenameURLRequester->setEnabled(true);
        selectionpage->main->FileEncodingComboBox->setEnabled(true);
        selectionpage->main->FileEncodingTextLabel->setEnabled(true);
        selectionpage->main->FileEncodingComboBox->setEnabled(true);
        selectionpage->main->NewPasswordTextLabel->setEnabled(true);
        selectionpage->main->NewPasswordPasswordEdit->setEnabled(true);
    }
    if (selectionpage->main->OnlineEnrollementRadioButton->isChecked()) {
        selectionpage->main->CaTextLabel->setEnabled(true);
        selectionpage->main->CAComboBox->setEnabled(true);
        selectionpage->main->CaUrlTextLabel->setEnabled(true);
        selectionpage->main->CaUrlLineEdit->setEnabled(true);
        selectionpage->main->ChallengePasswordTextLabel->setEnabled(true);
        selectionpage->main->ChallengePasswordPasswordEdit->setEnabled(true);
        selectionpage->main->CaDomainTextLabel->setEnabled(true);
        selectionpage->main->CaDomainLineEdit->setEnabled(true);

        selectionpage->main->FileEncodingComboBox->setEnabled(false);
        selectionpage->main->FilenameTextLabel->setEnabled(false);
        selectionpage->main->FilenameURLRequester->setEnabled(false);
        selectionpage->main->FileEncodingTextLabel->setEnabled(false);
        selectionpage->main->FileEncodingComboBox->setEnabled(false);
        selectionpage->main->NewPasswordTextLabel->setEnabled(false);
        selectionpage->main->NewPasswordPasswordEdit->setEnabled(false);
    }
}

void CiscoCertificateEnrollment::readFromStdout()
{

    QStringList msg_list = QString(EnrollmentProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString line = msg_list.at(i);
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry("[cisco_cert_mgr raw] " + line, KVpncEnum::debug);

        if (line.indexOf("Password:" , 0) > -1) {
            if (GlobalConfig->KvpncDebugLevel > 0)
                GlobalConfig->appendLogEntry(i18n("Certificate enrollment: %1 was requested, send it..." ,   i18n(" challenge password")), KVpncEnum::debug);

            EnrollmentProcess->write(QString(ChallengePassword + "\n").toUtf8());
            if (GlobalConfig->KvpncDebugLevel > 4)
                GlobalConfig->appendLogEntry(i18n("Send challenge password: %1" ,   ChallengePassword), KVpncEnum::debug);
        }

        if (line.indexOf("Request Pending." , 0) > -1) {
            if (ProgressDlg != 0)
                ProgressDlg->progressBar()->setValue(66);
            GlobalConfig->appendLogEntry(i18n("Certificate enrollment: request sent to CA, waiting for grant...") , KVpncEnum::info);
        }
        if (line.indexOf("contacting certificate authority." , 0) > -1) {
            GlobalConfig->appendLogEntry(i18n("Certificate enrollment: contacting CA...") , KVpncEnum::info);
        }

        if (line.indexOf("Success: certificate enrollment completed with no errors." , 0) > -1) {
            if (ProgressDlg != 0)
                ProgressDlg->progressBar()->setValue(99);
            if (success == 0) {
                GlobalConfig->appendLogEntry(i18n("Certificate enrollment: enrollment was successful.") , KVpncEnum::info);
                success = 0;
                successmsg = "The enrollment was successful. The CA has granted the request. The user and CA certificates are imported.";
            }
        }
    }
}

void CiscoCertificateEnrollment::readFromStderr()
{
    QStringList msg_list = QString(EnrollmentProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString line = msg_list.at(i);
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry("[cisco_cert_mgr err raw] " + line, KVpncEnum::debug);

        if (line.indexOf("certificate enrollment failed." , 0) > -1) {

            KMessageBox::error(0, i18n("Certificate enrollment: enrollment has been failed."), i18n("Enrollment failed"));
            GlobalConfig->appendLogEntry(i18n("Certificate enrollment: enrollment has been failed."), KVpncEnum::error);
            success = -1;
            successmsg = i18n("Enrollment has failed.");
//    GlobalConfig->appPointer->restoreOverrideCursor();
        }
    }
//  success=-1;
}

void CiscoCertificateEnrollment::checkProgress()
{
    if (GlobalConfig->KvpncDebugLevel > 6)
        GlobalConfig->appendLogEntry(i18n("Enrollment timer event"), KVpncEnum::debug);

    if (ProgressDlg->wasCancelled()) {
        // user has canceled the dlg, so we have to stop here
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry(i18n("Enrollment break requested, user cancelled."), KVpncEnum::debug);

        CheckEnrollmentTimer.stop();

        // kill process
        disconnect(EnrollmentProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()));
        disconnect(EnrollmentProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr()));
        if (DeleteProcess->state() == QProcess::Running) {
            EnrollmentProcess->terminate();
            QTimer::singleShot(2000, EnrollmentProcess, SLOT(kill()));

            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("Process %1 killed." ,   QString("cisco_cert_mgr")), KVpncEnum::debug);
        }

        QStringList CiscoCertRequests  = Utils(GlobalConfig).getCertsFromCiscoCertStore("enrollment");
        if (!CiscoCertRequests.isEmpty()) {
            if (GlobalConfig->KvpncDebugLevel > 2)
                GlobalConfig->appendLogEntry(i18n("removing pending enrollment requests: %1" ,   CiscoCertRequests.join(", ")), KVpncEnum::debug);

            for (int i = 0; i < (int) CiscoCertRequests.count();i++) {
                if (GlobalConfig->KvpncDebugLevel > 2)
                    GlobalConfig->appendLogEntry(i18n("delete enrollment request..."), KVpncEnum::debug);

                DeleteProcess = new QProcess(0);
                QString proc = GlobalConfig->pathToCiscoCertMgr;
                QStringList args;
                args.append("-E");
                args.append("-op");
                args.append("delete");
                args.append("-ct");
                args.append(0);
                connect(DeleteProcess, SIGNAL(finished(int, QProcess::ExitStatus)) , this, SLOT(cancelProcessFinished(int, QProcess::ExitStatus)));
                connect(DeleteProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout_cancel()));
                connect(DeleteProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr_cancel()));

                DeleteProcess->setEnvironment(*env);
                DeleteProcess->start(proc, args);
                if (!DeleteProcess->waitForStarted()) {
                    GlobalConfig->appendLogEntry(i18n("Process (%1) could not started." ,   QString("cisco_cert_mgr")), KVpncEnum::error);
//      KMessageBox::sorry ( this, i18n ( "Unable to start process (%1)." )QString ( "cisco_cert_mgr" ) );
                } else {
                    if (GlobalConfig->KvpncDebugLevel > 2)
                        GlobalConfig->appendLogEntry(i18n("Process (%1) started." ,   QString("cisco_cert_mgr: delete")), KVpncEnum::debug);

                    DeleteProcess->write(QString(ChallengePassword + "\n").toUtf8());
                    if (GlobalConfig->KvpncDebugLevel > 4)
                        GlobalConfig->appendLogEntry(i18n("Send challenge password: %1" ,   ChallengePassword), KVpncEnum::debug);

                    while (DeleteProcess->state() == QProcess::Running) {
                        sleep(1);
                    }
                }
                disconnect(DeleteProcess, SIGNAL(finished(int, QProcess::ExitStatus)) , this, SLOT(cancelProcessFinished(int, QProcess::ExitStatus)));
                disconnect(DeleteProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout_cancel()));
                disconnect(DeleteProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr_cancel()));
                delete DeleteProcess;
                DeleteProcess = 0L;

            }
        }
    } else {
        // nothing to do...
    }
}

void CiscoCertificateEnrollment::cancelProcessFinished(int, QProcess::ExitStatus)
{
    if (GlobalConfig->KvpncDebugLevel > 2) {
        GlobalConfig->appendLogEntry(i18n("Process (cisco_cert_mgr: delete) finished."),
                                     KVpncEnum::debug);
    }
//  delete DeleteProcess;
    successmsg = i18n("Request canceled.");
    success = -1;
    finishpage->main->successTextLabel->setText(successmsg);
}

void CiscoCertificateEnrollment::readFromStdout_cancel()
{
    QStringList msg_list = QString(DeleteProcess->readAllStandardOutput()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString line = msg_list.at(i);
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry("[cisco_cert_mgr raw] " + line, KVpncEnum::debug);
    }
}

void CiscoCertificateEnrollment::readFromStderr_cancel()
{
    QStringList msg_list = QString(DeleteProcess->readAllStandardError()).split('\n');
    for (int i = 0; i < msg_list.size(); ++i) {
        QString line = msg_list.at(i);
        if (GlobalConfig->KvpncDebugLevel > 2)
            GlobalConfig->appendLogEntry("[cisco_cert_mgr err raw] " + line, KVpncEnum::debug);
    }

//  success=-1;
}
#endif
