From c7323aafac1769cb809da3f1d7ddd05383ace641 Mon Sep 17 00:00:00 2001 From: me_desk Date: Sun, 22 Jul 2012 12:00:06 +0000 Subject: 1) Automatic account registration implemented; 2) All openssl command line tools invocations moved to new class OpenSSLTool git-svn-id: svn://localhost/project_picapica/trunk@150 fb96df88-216d-11de-830c-f3023f12d8ac --- pica-client/accountswindow.cpp | 73 +++++++------- pica-client/accountswindow.h | 1 + pica-client/dialogs/registeraccountdialog.cpp | 116 +++++++++++++++++++++- pica-client/dialogs/registeraccountdialog.h | 16 ++++ pica-client/dialogs/viewcertdialog.cpp | 22 +---- pica-client/openssltool.cpp | 133 ++++++++++++++++++++++++++ pica-client/openssltool.h | 26 +++++ pica-client/pica-client.pro | 8 +- pica-client/skynet.cpp | 25 +---- 9 files changed, 333 insertions(+), 87 deletions(-) create mode 100644 pica-client/openssltool.cpp create mode 100644 pica-client/openssltool.h (limited to 'pica-client') diff --git a/pica-client/accountswindow.cpp b/pica-client/accountswindow.cpp index afd84a3..b38b5c0 100644 --- a/pica-client/accountswindow.cpp +++ b/pica-client/accountswindow.cpp @@ -6,7 +6,7 @@ #include "dialogs/registeraccountdialog.h" #include "../PICA_client.h" #include "skynet.h" -#include +#include "openssltool.h" #include #include @@ -106,49 +106,18 @@ void AccountsWindow::login_click() } -void AccountsWindow::register_click() +void AccountsWindow::CreateAccount(QString CertFilename, QString PkeyFilename, bool copyfiles) { - RegisterAccountDialog d; - d.exec(); -} - -void AccountsWindow::add_click() -{ - AddAccountDialog d; - d.exec(); - - if (d.result()) - { quint32 id; - PICA_get_id_from_cert(d.GetCertFilename().toUtf8().constData(),&id); - - // - QProcess openssl; - - openssl.start("openssl",QStringList()<<"x509"<<"-in"< L; void LoadAccounts(); + void CreateAccount(QString CertFilename, QString PkeyFilename, bool copyfiles); void closeEvent(QCloseEvent *); diff --git a/pica-client/dialogs/registeraccountdialog.cpp b/pica-client/dialogs/registeraccountdialog.cpp index b091a5f..1ce1cdb 100644 --- a/pica-client/dialogs/registeraccountdialog.cpp +++ b/pica-client/dialogs/registeraccountdialog.cpp @@ -1,5 +1,9 @@ #include "registeraccountdialog.h" +#include "globals.h" #include +#include +#include + RegisterAccountDialog::RegisterAccountDialog(QWidget *parent) : QDialog(parent) @@ -9,9 +13,16 @@ RegisterAccountDialog::RegisterAccountDialog(QWidget *parent) : QLabel *lbNickname = new QLabel(tr("Name:")); nickname = new QLineEdit(); btRegister = new QPushButton(tr("Register")); - lbStatus = new QLabel(); + lbStatus = new QLabel(tr("Enter your name and press\n \"Register\" to get certificate")); btOK = new QPushButton(tr("OK")); + { + QFont f; + f= lbStatus->font(); + f.setBold(true); + lbStatus->setFont(f); + } + layout->addWidget(lbNickname); layout->addWidget(nickname); layout->addWidget(btRegister); @@ -20,16 +31,119 @@ RegisterAccountDialog::RegisterAccountDialog(QWidget *parent) : setLayout(layout); + vld = new QRegExpValidator(QRegExp("[^\\#/=\"\'\\$]+"), this); + nickname->setValidator(vld); + connect(btOK, SIGNAL(clicked()), this, SLOT(OK())); connect(btRegister, SIGNAL(clicked()), this, SLOT(Register())); } void RegisterAccountDialog::OK() { + done(0); } void RegisterAccountDialog::Register() { + //check name + QString name = nickname->text(); + + if (name.toUtf8().size() > 52) //64bytes -field size in x509 certificate, - 10 for number, -1 for #, 1 for terminating zero + { + QMessageBox mbx; + mbx.setText(tr("Name is too long")); + mbx.exec(); + return; + } + + //1 + lbStatus->setText(tr("1) generating RSA keypair...")); + + nickname->setEnabled(false); + btRegister->setEnabled(false); + + ost.GenRSAKeySignal(4096, config_dir + QDir::separator() + "privkey.pem", this, SLOT(stageGenCSR(int, QProcess::ExitStatus))); +} + +void RegisterAccountDialog::stageGenCSR(int retval, QProcess::ExitStatus) +{ + if (retval != 0) + { + lbStatus->setText(tr("Error:\n") + ost.ReadStdErr()); + return; + } + + lbStatus->setText(tr("2) Generating CSR...")); + + ost.GenCSRSignal(config_dir + QDir::separator() + "csr.pem", + config_dir + QDir::separator() + "privkey.pem", + nickname->text(), + this, + SLOT(stageConnect(int,QProcess::ExitStatus))); +} + +void RegisterAccountDialog::stageConnect(int retval,QProcess::ExitStatus) +{ + static const char *registrar_hosts[] = {"registrar.picapica.im","registrar.picapica.ge"}; + static unsigned char registrar_index; + + if (retval != 0) + { + lbStatus->setText(tr("Error:\n") + ost.ReadStdErr()); + return; + } + + lbStatus->setText(tr("3) Connecting to server...")); + + sock.connectToHost(registrar_hosts[(registrar_index++)%(sizeof(registrar_hosts)/sizeof(char*))], 2299); + + connect(&sock, SIGNAL(connected()), this, SLOT(stageGetCert())); +} + +void RegisterAccountDialog::stageGetCert() +{ + lbStatus->setText(tr("4) Connected. Waiting for certificate...")); + + QFile csr(config_dir + QDir::separator() + "csr.pem"); + csr.open(QIODevice::ReadOnly); + + QByteArray buf; + + buf = csr.readAll(); + + sock.write(buf.data(), buf.size()); + connect(&sock, SIGNAL(readyRead()), this, SLOT(stageReadCert())); + + cert_buf.clear(); +} + +void RegisterAccountDialog::stageReadCert() +{ + cert_buf.append(sock.readAll()); + + if (cert_buf.contains("-----END CERTIFICATE-----") || cert_buf.contains("-----END X509 CERTIFICATE-----")) + { + QFile cert(config_dir + QDir::separator() + "cert.pem"); + cert.open(QIODevice::WriteOnly | QIODevice::Truncate); + cert.write(cert_buf.data(),cert_buf.size()); + cert.close(); + + QFile::remove(config_dir + QDir::separator() + "csr.pem"); + + CertFilename_ = config_dir + QDir::separator() + "cert.pem"; + PkeyFilename_ = config_dir + QDir::separator() + "privkey.pem"; + + done(1); + } +} + +QString RegisterAccountDialog::GetCertFilename() +{ + return CertFilename_; +} +QString RegisterAccountDialog::GetPkeyFilename() +{ + return PkeyFilename_; } diff --git a/pica-client/dialogs/registeraccountdialog.h b/pica-client/dialogs/registeraccountdialog.h index e1a8fd5..696f1ee 100644 --- a/pica-client/dialogs/registeraccountdialog.h +++ b/pica-client/dialogs/registeraccountdialog.h @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include +#include "openssltool.h" class RegisterAccountDialog : public QDialog { @@ -20,11 +24,23 @@ private: QLineEdit *nickname; QLabel *lbStatus; + QRegExpValidator *vld; + OpenSSLTool ost; + QTcpSocket sock; + QByteArray cert_buf; + + QString CertFilename_; + QString PkeyFilename_; signals: public slots: void OK(); void Register(); + + void stageGenCSR(int,QProcess::ExitStatus); + void stageConnect(int,QProcess::ExitStatus); + void stageGetCert(); + void stageReadCert(); }; #endif // REGISTERACCOUNTDIALOG_H diff --git a/pica-client/dialogs/viewcertdialog.cpp b/pica-client/dialogs/viewcertdialog.cpp index 8b096c2..7f4e24a 100644 --- a/pica-client/dialogs/viewcertdialog.cpp +++ b/pica-client/dialogs/viewcertdialog.cpp @@ -1,7 +1,6 @@ #include "viewcertdialog.h" +#include "openssltool.h" #include -#include - #include #include @@ -42,24 +41,7 @@ ViewCertDialog::ViewCertDialog(QWidget *parent) : void ViewCertDialog::SetCert(QString cert_pem) { - QProcess openssl(this); - qint64 ret; - char *data; - QByteArray ba; - - openssl.start("openssl", QStringList()<<"x509"<<"-noout"<<"-text"<<"-nameopt"<<"multiline,-esc_msb,utf8"); - - if (!openssl.waitForStarted()) - return; - - ba = cert_pem.toAscii(); - ret = openssl.write(data = (char*)ba.constData()); - openssl.closeWriteChannel(); - - if (!openssl.waitForFinished()) - return; - - cert_text->setPlainText(QString::fromUtf8(openssl.readAllStandardOutput().constData())); + cert_text->setPlainText(OpenSSLTool::CertTextFromString(cert_pem)); } void ViewCertDialog::OK() diff --git a/pica-client/openssltool.cpp b/pica-client/openssltool.cpp new file mode 100644 index 0000000..29cb3b7 --- /dev/null +++ b/pica-client/openssltool.cpp @@ -0,0 +1,133 @@ +#include "openssltool.h" +#include +#include +#include + +OpenSSLTool::OpenSSLTool() +{ +} + +QString OpenSSLTool::NameFromCertFile(QString cert_file) +{ + // + QProcess openssl; + + openssl.start("openssl",QStringList()<<"x509"<<"-in"< +#include + +class OpenSSLTool +{ +public: + OpenSSLTool(); + + static QString NameFromCertFile(QString cert_file); + static QString NameFromCertString(QString cert_pem); + static QString CertTextFromString(QString cert_pem); + + bool GenRSAKeySignal(quint32 numbits, QString keyfile, QObject *receiver, const char *finished_slot); + bool GenCSRSignal(QString csr_file, QString keyfile, QString subject, QObject *receiver, const char *finished_slot); + + QString ReadStdErr(); + QString ReadStdOut(); + +private: + QProcess openssl_; +}; + +#endif // OPENSSLTOOL_H diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro index 4b431d2..f9549d6 100644 --- a/pica-client/pica-client.pro +++ b/pica-client/pica-client.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core gui sql +QT += core gui sql network TARGET = pica-client TEMPLATE = app @@ -29,7 +29,8 @@ SOURCES += main.cpp\ picaactioncenter.cpp \ dialogs/viewcertdialog.cpp \ dialogs/forgedcertdialog.cpp \ - dialogs/registeraccountdialog.cpp + dialogs/registeraccountdialog.cpp \ + openssltool.cpp HEADERS += mainwindow.h \ chatwindow.h \ @@ -52,7 +53,8 @@ HEADERS += mainwindow.h \ dialogs/forgedcertdialog.h \ ../PICA_common.h \ ../PICA_proto.h \ - dialogs/registeraccountdialog.h + dialogs/registeraccountdialog.h \ + openssltool.h DEFINES = PICA_MULTITHREADED diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 0d2ad08..44f0101 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -3,6 +3,7 @@ #include //#include "dialogs/viewcertdialog.h" #include "contacts.h" +#include "openssltool.h" //#include //debug //#include "dialogs/forgedcertdialog.h" #include @@ -98,30 +99,8 @@ void SkyNet::verify_peer_cert(quint32 peer_id, QString cert_pem, bool *verified) { cnt.SetContactCert(peer_id, cert_pem); - // -- move to OpenSSL class - QProcess openssl; + QString name = OpenSSLTool::NameFromCertString(cert_pem); - openssl.start("openssl",QStringList()<<"x509"<<"-subject"<<"-nameopt"<<"oneline,-esc_msb,utf8"<<"-noout"); - if (!openssl.waitForStarted()) - return; - - openssl.write(cert_pem.toAscii()); - - if (!openssl.waitForFinished()) - return; - - QByteArray result = openssl.readAll(); - QRegExp rx("CN = [0-9]+\\#([^\\s\\#]+)"); - - - QString name=QString::fromUtf8( result.constData()); - - if (name.contains(rx)) - { - name=rx.cap(1); - } - - // cnt.SetContactName(peer_id, name); } else -- cgit v1.2.1