diff options
| author | me_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac> | 2012-07-22 12:00:06 +0000 |
|---|---|---|
| committer | me_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac> | 2012-07-22 12:00:06 +0000 |
| commit | c7323aafac1769cb809da3f1d7ddd05383ace641 (patch) | |
| tree | ddd736fbbe600d6eacc1f324d98a3c3064244b89 | |
| parent | f190872a4ab94577d1d9db343c0ca7643f40eae6 (diff) | |
| download | pica-pica-c7323aafac1769cb809da3f1d7ddd05383ace641.tar.gz pica-pica-c7323aafac1769cb809da3f1d7ddd05383ace641.zip | |
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
| -rw-r--r-- | pica-client/accountswindow.cpp | 73 | ||||
| -rw-r--r-- | pica-client/accountswindow.h | 1 | ||||
| -rw-r--r-- | pica-client/dialogs/registeraccountdialog.cpp | 116 | ||||
| -rw-r--r-- | pica-client/dialogs/registeraccountdialog.h | 16 | ||||
| -rw-r--r-- | pica-client/dialogs/viewcertdialog.cpp | 22 | ||||
| -rw-r--r-- | pica-client/openssltool.cpp | 133 | ||||
| -rw-r--r-- | pica-client/openssltool.h | 26 | ||||
| -rw-r--r-- | pica-client/pica-client.pro | 8 | ||||
| -rw-r--r-- | pica-client/skynet.cpp | 25 | ||||
| -rwxr-xr-x | tests/ca/serial | 2 | ||||
| -rwxr-xr-x | tests/ca/serial.old | 2 | ||||
| -rwxr-xr-x | tests/ca/testnet_cert_index_db.txt | 2 | ||||
| -rwxr-xr-x | tests/ca/testnet_cert_index_db.txt.old | 2 |
13 files changed, 339 insertions, 89 deletions
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 <QRegExp> +#include "openssltool.h" #include <QMessageBox> #include <QApplication> @@ -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"<<d.GetCertFilename()<<"-subject"<<"-nameopt"<<"oneline,-esc_msb,utf8"<<"-noout"); - if (!openssl.waitForStarted()) - return; - - if (!openssl.waitForFinished()) - return; - - QByteArray result = openssl.readAll(); - QRegExp rx("CN = [0-9]+\\#([^\\s\\#]+)"); - + PICA_get_id_from_cert(CertFilename.toUtf8().constData(),&id); - QString name=QString::fromUtf8( result.constData()); - - if (name.contains(rx)) - { - name=rx.cap(1); - } + QString name = OpenSSLTool::NameFromCertFile(CertFilename); - // Accounts::AccountRecord rec; QString certfilename,pkeyfilename; - if (d.isCopyFilesChecked()) + if (copyfiles) { QDir dir(config_dir); dir.mkdir(QString::number(id)); @@ -157,13 +126,13 @@ void AccountsWindow::add_click() certfilename=dir.absolutePath()+"/"+QString::number(id)+"_cert.pem"; pkeyfilename=dir.absolutePath()+"/"+QString::number(id)+"_pkey.pem"; - QFile::copy(d.GetCertFilename(),certfilename); - QFile::copy(d.GetPkeyFilename(),pkeyfilename); + QFile::copy(CertFilename,certfilename); + QFile::copy(PkeyFilename,pkeyfilename); } else { - certfilename = d.GetCertFilename(); - pkeyfilename = d.GetPkeyFilename(); + certfilename = CertFilename; + pkeyfilename = PkeyFilename; } rec.id=id; @@ -181,6 +150,30 @@ void AccountsWindow::add_click() mbx.exec(); } LoadAccounts(); +} + +void AccountsWindow::register_click() +{ + RegisterAccountDialog d; + d.exec(); + + if (d.result()) + { + CreateAccount(d.GetCertFilename(), d.GetPkeyFilename(), true); + + QFile::remove(d.GetCertFilename()); + QFile::remove(d.GetPkeyFilename()); + } +} + +void AccountsWindow::add_click() +{ + AddAccountDialog d; + d.exec(); + + if (d.result()) + { + CreateAccount(d.GetCertFilename(), d.GetPkeyFilename(), d.isCopyFilesChecked()); } } diff --git a/pica-client/accountswindow.h b/pica-client/accountswindow.h index 30e3c0d..1a6175b 100644 --- a/pica-client/accountswindow.h +++ b/pica-client/accountswindow.h @@ -24,6 +24,7 @@ private: QList<Accounts::AccountRecord> 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 <QVBoxLayout> +#include <QDir> +#include <QMessageBox> + 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 <QPushButton> #include <QLineEdit> #include <QLabel> +#include <QRegExpValidator> +#include <QtNetwork> +#include <QTcpSocket> +#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 <QVBoxLayout> -#include <QProcess> - #include <QMessageBox> #include <unistd.h> @@ -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 <QProcess> +#include <QRegExp> +#include <QMessageBox> + +OpenSSLTool::OpenSSLTool() +{ +} + +QString OpenSSLTool::NameFromCertFile(QString cert_file) +{ + // + QProcess openssl; + + openssl.start("openssl",QStringList()<<"x509"<<"-in"<<cert_file<<"-subject"<<"-nameopt"<<"oneline,-esc_msb,utf8"<<"-noout"); + if (!openssl.waitForStarted()) + return QString(); + + if (!openssl.waitForFinished()) + return QString(); + + QByteArray result = openssl.readAll(); + QRegExp rx("CN = [0-9]+\\#([^\\s\\#]+)"); + + + QString name=QString::fromUtf8( result.constData()); + + if (name.contains(rx)) + { + name=rx.cap(1); + } + + // +return name; +} + +QString OpenSSLTool::NameFromCertString(QString cert_pem) +{ + QProcess openssl; + + openssl.start("openssl",QStringList()<<"x509"<<"-subject"<<"-nameopt"<<"oneline,-esc_msb,utf8"<<"-noout"); + if (!openssl.waitForStarted()) + return QString(); + + openssl.write(cert_pem.toAscii()); + + if (!openssl.waitForFinished()) + return QString(); + + QByteArray result = openssl.readAll(); + QRegExp rx("CN = [0-9]+\\#([^\\s\\#]+)"); + + + QString name=QString::fromUtf8( result.constData()); + + if (name.contains(rx)) + { + name=rx.cap(1); + } + + // +return name; +} + +QString OpenSSLTool::CertTextFromString(QString cert_pem) +{ + QProcess openssl; + qint64 ret; + char *data; + QByteArray ba; + + openssl.start("openssl", QStringList()<<"x509"<<"-noout"<<"-text"<<"-nameopt"<<"multiline,-esc_msb,utf8"); + + if (!openssl.waitForStarted()) + return QString(); + + ba = cert_pem.toAscii(); + ret = openssl.write(data = (char*)ba.constData()); + openssl.closeWriteChannel(); + + if (!openssl.waitForFinished()) + return QString(); + + return QString::fromUtf8(openssl.readAllStandardOutput().constData()); +} + +bool OpenSSLTool::GenRSAKeySignal(quint32 numbits, QString keyfile, QObject *receiver, const char *finished_slot) +{ + openssl_.start("openssl", QStringList()<<"genrsa"<<"-out"<<keyfile<<QString::number(numbits)); + + if (!openssl_.waitForStarted()) + return false; + + openssl_.disconnect(&openssl_, SIGNAL(finished(int,QProcess::ExitStatus)), 0, 0); + openssl_.connect(&openssl_, SIGNAL(finished(int,QProcess::ExitStatus)),receiver, finished_slot); + + return true; +} + +bool OpenSSLTool::GenCSRSignal(QString csr_file, QString keyfile, QString subject, QObject *receiver, const char *finished_slot) +{ + openssl_.start("openssl", + QStringList() + <<"req" + <<"-out"<<csr_file + <<"-key"<<keyfile + <<"-subj"<<"/CN=" + subject + <<"-new" + <<"-days"<<"3680" + <<"-utf8" + <<"-batch"); + + if (!openssl_.waitForStarted()) + return false; + + openssl_.disconnect(&openssl_, SIGNAL(finished(int,QProcess::ExitStatus)), 0, 0); + openssl_.connect(&openssl_, SIGNAL(finished(int,QProcess::ExitStatus)),receiver, finished_slot); + + return true; +} + +QString OpenSSLTool::ReadStdErr() +{ + return QString::fromUtf8(openssl_.readAllStandardError().constData()); +} + +QString OpenSSLTool::ReadStdOut() +{ + return QString::fromUtf8(openssl_.readAllStandardOutput().constData()); +} + + + diff --git a/pica-client/openssltool.h b/pica-client/openssltool.h new file mode 100644 index 0000000..cf98786 --- /dev/null +++ b/pica-client/openssltool.h @@ -0,0 +1,26 @@ +#ifndef OPENSSLTOOL_H +#define OPENSSLTOOL_H + +#include <QString> +#include <QProcess> + +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 <QMutex> //#include "dialogs/viewcertdialog.h" #include "contacts.h" +#include "openssltool.h" //#include <QMessageBox> //debug //#include "dialogs/forgedcertdialog.h" #include <QDebug> @@ -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 diff --git a/tests/ca/serial b/tests/ca/serial index 5265f75..71b0bad 100755 --- a/tests/ca/serial +++ b/tests/ca/serial @@ -1 +1 @@ -0346 +0348 diff --git a/tests/ca/serial.old b/tests/ca/serial.old index 5f43550..b6ca773 100755 --- a/tests/ca/serial.old +++ b/tests/ca/serial.old @@ -1 +1 @@ -0345 +0347 diff --git a/tests/ca/testnet_cert_index_db.txt b/tests/ca/testnet_cert_index_db.txt index cd743af..00a0d6c 100755 --- a/tests/ca/testnet_cert_index_db.txt +++ b/tests/ca/testnet_cert_index_db.txt @@ -13,3 +13,5 @@ V 220810192705Z 0342 unknown /CN=123#tester V 220810192754Z 0343 unknown /CN=123#tester V 220821074303Z 0344 unknown /CN=30000#tester V 220821074335Z 0345 unknown /CN=30001#tester +V 220824115339Z 0346 unknown /CN=30000#tester +V 220824115407Z 0347 unknown /CN=30001#tester diff --git a/tests/ca/testnet_cert_index_db.txt.old b/tests/ca/testnet_cert_index_db.txt.old index babcc3a..35f4b50 100755 --- a/tests/ca/testnet_cert_index_db.txt.old +++ b/tests/ca/testnet_cert_index_db.txt.old @@ -12,3 +12,5 @@ V 220810112929Z 0341 unknown /CN=16#sixteen V 220810192705Z 0342 unknown /CN=123#tester V 220810192754Z 0343 unknown /CN=123#tester V 220821074303Z 0344 unknown /CN=30000#tester +V 220821074335Z 0345 unknown /CN=30001#tester +V 220824115339Z 0346 unknown /CN=30000#tester |
