diff options
-rw-r--r-- | client/main.cpp | 1 | ||||
-rw-r--r-- | client/mainwindow.cpp | 284 | ||||
-rw-r--r-- | client/mainwindow.h | 47 | ||||
-rw-r--r-- | client/mainwindow.ui | 73 | ||||
-rw-r--r-- | client/resources.qrc | 6 | ||||
-rw-r--r-- | client/restarter.pro | 8 | ||||
-rw-r--r-- | proto_lib/api_protocol.h | 1 | ||||
-rw-r--r-- | proto_lib/packet.cpp | 10 | ||||
-rw-r--r-- | restarter.workspace | 4 | ||||
-rw-r--r-- | server/server.cpp | 7 | ||||
-rw-r--r-- | server/service.cpp | 45 | ||||
-rw-r--r-- | server/service.h | 2 | ||||
-rw-r--r-- | server/session.cpp | 3 |
13 files changed, 231 insertions, 260 deletions
diff --git a/client/main.cpp b/client/main.cpp index 8692105..3ce6fdb 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -22,7 +22,6 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; - w.show(); return a.exec(); } diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 428d88b..943e04d 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -18,126 +18,167 @@ #include "mainwindow.h" #include "ui_mainwindow.h" + + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), - ui(new Ui::MainWindow) + ui(new Ui::MainWindow), + sock(NULL) { ui->setupUi(this); -#ifdef MINIMAL - ui->halt->hide(); - ui->reboot->hide(); - ui->reboot->hide(); - ui->restart_cups->hide(); - ui->restart_ppp->hide(); - ui->state_lbl->hide(); - this->setFixedSize(ui->restart_vbox_btn->geometry().width() +17, ui->restart_vbox_btn->geometry().height() +17); -#else + this->setWindowTitle(tr("Client")); this->setFixedSize(this->size()); -#endif + show(); + ui->state_lbl->setVisible(true); ui->state_lbl->setText(" "); + ui->state_lbl->setText(tr("Preparing..")); + get_socket(); + _connect(); + ui->state_lbl->setText(QString(" ")); } -QSslSocket *MainWindow::get_socket() +void MainWindow::get_socket() { - QSslSocket *s = new QSslSocket; - QFile in(":/res/ca.crt"); - in.open(QIODevice::ReadOnly); - QByteArray buf = in.readAll(); - in.close(); - QList<QSslCertificate> ca_list; - ca_list.push_back(QSslCertificate(buf)); - s->setCaCertificates(ca_list); - in.setFileName(":/res/client.crt"); - in.open(QIODevice::ReadOnly); - buf = in.readAll(); - in.close(); - QSslCertificate c(buf); - s->setLocalCertificate(c); - in.setFileName(":/res/client.key"); - in.open(QIODevice::ReadOnly); - buf = in.readAll(); - QSslKey key(buf, QSsl::Rsa); - s->setPrivateKey(key); - s->setPeerVerifyMode(QSslSocket::VerifyPeer); - s->setProtocol(QSsl::SslV3); - connect(s, SIGNAL(peerVerifyError(QSslError)), this, SLOT(ssl_verify_error_handler(QSslError))); - - return s; + if(!sock) + { + sock = new QSslSocket; + QFile in(":/ca.crt"); + in.open(QIODevice::ReadOnly); + QByteArray buf = in.readAll(); + in.close(); + QList<QSslCertificate> ca_list; + ca_list.push_back(QSslCertificate(buf)); + sock->setCaCertificates(ca_list); + in.setFileName(":/cli.crt"); + in.open(QIODevice::ReadOnly); + buf = in.readAll(); + in.close(); + QSslCertificate c(buf); + sock->setLocalCertificate(c); + in.setFileName(":/cli.key"); + in.open(QIODevice::ReadOnly); + buf = in.readAll(); + QSslKey key(buf, QSsl::Rsa); + sock->setPrivateKey(key); + sock->setPeerVerifyMode(QSslSocket::VerifyPeer); + sock->setProtocol(QSsl::SslV3); + connect(sock, SIGNAL(peerVerifyError(QSslError)), this, SLOT(ssl_verify_error_handler(QSslError))); + } } -void MainWindow::ssl_verify_error_handler(const QSslError error) +void MainWindow::_connect() { - switch(error.error()) + if(!sock) { - case QSslError::InvalidCaCertificate: case QSslError::NoPeerCertificate: case QSslError::UnspecifiedError: - case QSslError::AuthorityIssuerSerialNumberMismatch: - ui->state_lbl->setText(QString::fromUtf8("Ошибка соединения !")); - sock->abort(); + ui->state_lbl->setText(tr("Socket error..")); return; - default: - break; } - sock->ignoreSslErrors(); + ui->state_lbl->setText(tr("Connecting..")); + sock->connectToHostEncrypted(host, 1313); + connect(sock, SIGNAL(encrypted()), SLOT(connected())); + connect(sock, SIGNAL(readyRead()), SLOT(handle_data())); + connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); } - -MainWindow::~MainWindow() +void MainWindow::connected() { - delete ui; + packet *p = packet::cli_make_init_packet(); + unsigned char *b = p->buf(); + sock->write((char*)b, p->raw().size()); + delete [] b; + delete p; } -void MainWindow::enable_buttons(bool enable) +void MainWindow::handle_data() { - ui->restart_vbox_btn->setEnabled(enable); - ui->reboot->setEnabled(enable); - ui->halt->setEnabled(enable); - ui->restart_cups->setEnabled(enable); - ui->restart_ppp->setEnabled(enable); - ui->restart_vbox_btn->setEnabled(enable); -} + QByteArray a = sock->readAll(); + std::vector<unsigned char> v; + v.assign(a.data(), a.data() + a.size()); + packet p(v); + if(!p.is_good()) + { +#ifdef DEBUG + QMessageBox msg; + msg.setText("bad packet"); + msg.exec(); +#endif + return; + } + if(!p.is_server_packet()) + { +#ifdef DEBUG + QMessageBox msg; + msg.setText("not server packet"); + msg.exec(); +#endif + return; + } + switch(p.get_type()) + { + case TYPE_SERVICES: + { //TODO: controls positioning + services = packet::cli_extract_services(p); + for(std::list<service_s>::iterator i = services->begin(), end = services->end(); i != end; ++i) + { + service_ui *u = new service_ui; + u->group = new QGroupBox(i->service.c_str(), this); + u->group->show(); + for(std::list<service_s::cmd>::iterator ii = i->cmds.begin(), eend = i->cmds.end(); ii != eend; ++ii) + { + u->commands.push_back(new QPushButton(QString::fromUtf8(ii->command.c_str()), u->group)); + connect(u->commands.back(), SIGNAL(clicked()), SLOT(handle_button_click())); + u->commands.back()->setToolTip(QString::fromUtf8(ii->description.c_str())); + u->commands.back()->show(); + } + svc_ui_list.push_back(u); + } + } + break; + case TYPE_AUTH: + { + if(p.get_status() == STATUS_SUCCESS) + { + packet *p = packet::cli_make_request_services_packet(); + unsigned char *b = p->buf(); + sock->write((char*)b, p->raw().size()); + delete [] b; + delete p; + } + } + break; + default: break; -void MainWindow::on_restart_vbox_btn_clicked() -{ - ui->state_lbl->setText(QString::fromUtf8("Подготовка..")); - sock = get_socket(); - ui->state_lbl->setText(QString::fromUtf8("Соединение..")); - sock->connectToHostEncrypted(host, 1313); - connect(sock, SIGNAL(encrypted()), SLOT(restart_vbox_sock_connected())); - connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); + }; } -void MainWindow::restart_vbox_sock_connected() -{ - ui->state_lbl->setText(QString::fromUtf8("Выполнение..")); - enable_buttons(false); - sock->write("restart vbox\0"); -} -void MainWindow::reboot() +void MainWindow::handle_button_click() { - ui->state_lbl->setText(QString::fromUtf8("Выполнение..")); - enable_buttons(false); - sock->write("reboot now\0"); + //TODO + } -void MainWindow::halt() +void MainWindow::ssl_verify_error_handler(const QSslError error) { - ui->state_lbl->setText(QString::fromUtf8("Выполнение..")); - enable_buttons(false); - sock->write("halt now\0"); + switch(error.error()) + { + case QSslError::InvalidCaCertificate: case QSslError::NoPeerCertificate: case QSslError::UnspecifiedError: + case QSslError::AuthorityIssuerSerialNumberMismatch: + ui->state_lbl->setText(tr("Connection error")); + sock->abort(); + return; + default: + break; + } + sock->ignoreSslErrors(); } -void MainWindow::restart_cups() +MainWindow::~MainWindow() { - ui->state_lbl->setText(QString::fromUtf8("Выполнение..")); - enable_buttons(false); - sock->write("restart cups\0"); + delete ui; } -void MainWindow::restart_ppp() +void MainWindow::enable_buttons(bool enable) { - ui->state_lbl->setText(QString::fromUtf8("Выполнение..")); - enable_buttons(false); - sock->write("restart ppp\0"); } @@ -148,74 +189,3 @@ void MainWindow::disconnected() sock->deleteLater(); } -void MainWindow::on_reboot_clicked() -{ -#ifndef MINIMAL - QMessageBox msg; - msg.setText(QString::fromUtf8("Вы видели куда ткнули ?")); - msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - if(msg.exec() == QMessageBox::Yes) - { - QMessageBox msg; - msg.setText(QString::fromUtf8("Уверены что хотите перезагрузить сервер ?")); - msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - if(msg.exec() == QMessageBox::Yes) - { - ui->state_lbl->setText(QString::fromUtf8("Подготовка..")); - sock = get_socket(); - ui->state_lbl->setText(QString::fromUtf8("Соединение..")); - sock->connectToHostEncrypted(host, 1313); - connect(sock, SIGNAL(encrypted()), SLOT(reboot())); - connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); - } - } -#endif -} - -void MainWindow::on_halt_clicked() -{ -#ifndef MINIMAL - QMessageBox msg; - msg.setText(QString::fromUtf8("Вы видели куда ткнули ?")); - msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - if(msg.exec() == QMessageBox::Yes) - { - QMessageBox msg; - msg.setText(QString::fromUtf8("Уверены что хотите выключить сервер ?")); - msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - if(msg.exec() == QMessageBox::Yes) - { - ui->state_lbl->setText(QString::fromUtf8("Подготовка..")); - sock = get_socket(); - ui->state_lbl->setText(QString::fromUtf8("Соединение..")); - sock->connectToHostEncrypted(host, 1313); - connect(sock, SIGNAL(encrypted()), SLOT(halt())); - connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); - } - } -#endif -} - -void MainWindow::on_restart_cups_clicked() -{ -#ifndef MINIMAL - ui->state_lbl->setText(QString::fromUtf8("Подготовка..")); - sock = get_socket(); - ui->state_lbl->setText(QString::fromUtf8("Соединение..")); - sock->connectToHostEncrypted(host, 1313); - connect(sock, SIGNAL(encrypted()), SLOT(restart_cups())); - connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); -#endif -} - -void MainWindow::on_restart_ppp_clicked() -{ -#ifndef MINIMAL - ui->state_lbl->setText(QString::fromUtf8("Подготовка..")); - sock = get_socket(); - ui->state_lbl->setText(QString::fromUtf8("Соединение..")); - sock->connectToHostEncrypted(host, 1313); - connect(sock, SIGNAL(encrypted()), SLOT(restart_ppp())); - connect(sock, SIGNAL(disconnected()), SLOT(disconnected())); -#endif -} diff --git a/client/mainwindow.h b/client/mainwindow.h index 22f3222..98725a6 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -23,17 +23,33 @@ #include <QSslSocket> #include <QFile> #include <QSslKey> +#include <QGroupBox> +#include <QPushButton> +#include <api_protocol.h> -#ifdef MINIMAL -const QString host = "192.168.0.1"; -#else -const QString host = "gluzskaya.ru"; -#endif + +using namespace proto; + +const QString host = "127.0.0.1"; namespace Ui { class MainWindow; } +struct service_ui +{ + QGroupBox *group; + std::list<QPushButton*> commands; + ~service_ui() + { + delete group; + for(std::list<QPushButton*>::iterator i = commands.begin(), end = commands.end(); i != end; ++i) + delete *i; + } + + +}; + class MainWindow : public QMainWindow { Q_OBJECT @@ -46,27 +62,20 @@ protected slots: void ssl_verify_error_handler(const QSslError); private slots: - void on_restart_vbox_btn_clicked(); - void restart_vbox_sock_connected(); - void reboot(); - void halt(); - void restart_cups(); - void restart_ppp(); void disconnected(); + void connected(); + void handle_data(); + void handle_button_click(); - void on_reboot_clicked(); - - void on_halt_clicked(); - - void on_restart_cups_clicked(); - - void on_restart_ppp_clicked(); private: void enable_buttons(bool); - QSslSocket *get_socket(); + void get_socket(); + void _connect(); Ui::MainWindow *ui; QSslSocket *sock; + std::list<service_s> *services; + std::list<service_ui*> svc_ui_list; }; #endif // MAINWINDOW_H diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 5894198..b91bc22 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -11,81 +11,16 @@ </rect> </property> <property name="windowTitle"> - <string>Окно</string> + <string>Window</string> </property> <widget class="QWidget" name="centralWidget"> - <widget class="QPushButton" name="restart_vbox_btn"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>181</width> - <height>25</height> - </rect> - </property> - <property name="text"> - <string>Перезапустить vm (1c)</string> - </property> - </widget> - <widget class="QPushButton" name="reboot"> - <property name="geometry"> - <rect> - <x>520</x> - <y>320</y> - <width>161</width> - <height>25</height> - </rect> - </property> - <property name="text"> - <string>Перезагрузить сервер</string> - </property> - </widget> - <widget class="QPushButton" name="halt"> - <property name="geometry"> - <rect> - <x>520</x> - <y>350</y> - <width>161</width> - <height>25</height> - </rect> - </property> - <property name="text"> - <string>Выключить серверер</string> - </property> - </widget> - <widget class="QPushButton" name="restart_cups"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>231</width> - <height>25</height> - </rect> - </property> - <property name="text"> - <string>Перезапустить сервер печати</string> - </property> - </widget> - <widget class="QPushButton" name="restart_ppp"> - <property name="geometry"> - <rect> - <x>10</x> - <y>70</y> - <width>191</width> - <height>25</height> - </rect> - </property> - <property name="text"> - <string>Перезапустить интернет</string> - </property> - </widget> <widget class="QLabel" name="state_lbl"> <property name="geometry"> <rect> <x>10</x> - <y>370</y> - <width>491</width> - <height>16</height> + <y>315</y> + <width>661</width> + <height>71</height> </rect> </property> <property name="text"> diff --git a/client/resources.qrc b/client/resources.qrc index 34e2d9e..3c76c1e 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -1,7 +1,7 @@ <RCC> <qresource prefix="/"> - <file>res/ca.crt</file> - <file>res/client.key</file> - <file>res/client.crt</file> + <file>ca.crt</file> + <file>cli.crt</file> + <file>cli.key</file> </qresource> </RCC> diff --git a/client/restarter.pro b/client/restarter.pro index 31052b5..90adbf7 100644 --- a/client/restarter.pro +++ b/client/restarter.pro @@ -19,10 +19,16 @@ FORMS += mainwindow.ui #DEFINES += MINIMAL +INCLUDEPATH += ../proto_lib + +debug:DEFINES += DEBUG + QMAKE_CXXFLAGS += -Os -fomit-frame-pointer -std=gnu++0x QMAKE_CFLAGS += -Os -fomit-frame-pointer -std=gnu99 -LIBS += -Wl,-O1 + +debug:LIBS += -L../proto_lib/Debug +LIBS += -lproto -Wl,-O1 RESOURCES += \ resources.qrc diff --git a/proto_lib/api_protocol.h b/proto_lib/api_protocol.h index 9a82e31..ffd7e0f 100644 --- a/proto_lib/api_protocol.h +++ b/proto_lib/api_protocol.h @@ -49,6 +49,7 @@ class packet public: explicit packet(std::vector<unsigned char>&); const std::vector<unsigned char> &raw(); + unsigned char *buf(); packet_type get_type(); bool is_good(); status get_status(); //false on fail diff --git a/proto_lib/packet.cpp b/proto_lib/packet.cpp index 8dc1b12..c4c5da0 100644 --- a/proto_lib/packet.cpp +++ b/proto_lib/packet.cpp @@ -349,4 +349,14 @@ svc_cmd packet::serv_extract_command(packet& p) return c; } +unsigned char *packet::buf() +{ + if(data.empty()) + return NULL; + unsigned char *b = new unsigned char [data.size()]; + for(size_t i = 0; i < data.size(); i ++) + b[i] = data[i]; + return b; +} + }; diff --git a/restarter.workspace b/restarter.workspace index f6eaa5d..e96d265 100644 --- a/restarter.workspace +++ b/restarter.workspace @@ -9,6 +9,10 @@ + + + + ]]> </Environment> <Project Name="proto_test" Path="proto_test/proto_test.project" Active="No"/> diff --git a/server/server.cpp b/server/server.cpp index 7a13fe6..a44b764 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -24,9 +24,12 @@ io_service_(io_service), acceptor_(io_service, tcp::endpoint(boost::asio::ip::ad { context_.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); context_.set_password_callback(boost::bind(&server::get_password, this)); - context_.use_certificate_chain_file("/etc/restarter_server/serv.crt"); +/* context_.use_certificate_chain_file("/etc/restarter_server/serv.crt"); context_.use_rsa_private_key_file("/etc/restarter_server/serv.key", boost::asio::ssl::context::pem); - context_.load_verify_file("/etc/restarter_server/ca.crt"); + context_.load_verify_file("/etc/restarter_server/ca.crt"); */ + context_.use_certificate_chain_file("./serv.crt"); + context_.use_rsa_private_key_file("./serv.key", boost::asio::ssl::context::pem); + context_.load_verify_file("./ca.crt"); context_.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_client_once); start_accept(); } diff --git a/server/service.cpp b/server/service.cpp index b00406f..541f935 100644 --- a/server/service.cpp +++ b/server/service.cpp @@ -31,13 +31,13 @@ bool service_info::command::operator==(const std::string &command) return command == this->command; } -void handle_data(session *s, proto::packet &p) +bool handle_data(session *s, proto::packet &p) { using namespace proto; if(!p.is_good()) - { - delete s; - } + return false; + if(!p.is_client_packet()) + return false; switch(p.get_type()) { case TYPE_AUTH: @@ -47,15 +47,37 @@ void handle_data(session *s, proto::packet &p) packet *r = packet::serv_make_status_packet(TYPE_AUTH, STATUS_FAILURE); s->write_w_close(r->raw()); delete r; - return; + return false; } else { packet *r = packet::serv_make_status_packet(TYPE_AUTH, STATUS_SUCCESS); s->write_w_response(r->raw()); delete r; - return; + return true; + } + } + break; + case TYPE_SERVICES: + { //TODO: rewrite + std::list<service_s> svcs; + for(std::list<service_info>::iterator i = installed_services.begin(), end = installed_services.end(); i != end; ++i) + { + service_s s; + s.service = i->name; + for(std::list<service_info::command>::iterator ii = i->predefined.begin(), eend = i->predefined.end(); ii != eend; ++ii) + { + service_s::cmd c; + c.command = ii->command; + c.description = ii->description; + s.cmds.push_back(c); + } + svcs.push_back(s); } + packet *r = packet::serv_make_services_packet(svcs); + s->write_w_response(r->raw()); + delete r; + return true; } break; case TYPE_COMMAND: @@ -86,6 +108,7 @@ void handle_data(session *s, proto::packet &p) packet *p = packet::serv_make_command_reply_packet(str, STATUS_SUCCESS); s->write_w_response(p->raw()); delete p; + return true; } break; case RET_FLOAT_PTR: @@ -98,6 +121,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete ret; + return true; } break; case RET_INT_PTR: @@ -110,6 +134,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete ret; + return true; } break; case RET_NONE: @@ -119,6 +144,7 @@ void handle_data(session *s, proto::packet &p) packet *p = packet::serv_make_status_packet(TYPE_COMMAND, STATUS_SUCCESS); s->write_w_response(p->raw()); delete p; + return true; } break; case RET_STD_STRING_PTR: @@ -129,6 +155,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete str; + return true; } break; case RET_VOID_PTR: @@ -176,6 +203,7 @@ void handle_data(session *s, proto::packet &p) delete [] data; s->write_w_response(p->raw()); delete p; + return true; } break; case RET_FLOAT_PTR: @@ -187,6 +215,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete ret; + return true; } break; case RET_INT_PTR: @@ -198,6 +227,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete ret; + return true; } break; case RET_NONE: @@ -206,6 +236,7 @@ void handle_data(session *s, proto::packet &p) packet *p = packet::serv_make_status_packet(TYPE_AUTH, STATUS_SUCCESS); s->write_w_response(p->raw()); delete p; + return true; } break; case RET_STD_STRING_PTR: @@ -215,6 +246,7 @@ void handle_data(session *s, proto::packet &p) s->write_w_response(p->raw()); delete p; delete str; + return true; } break; case RET_VOID_PTR: @@ -228,6 +260,7 @@ void handle_data(session *s, proto::packet &p) } break; } + return false; } }; diff --git a/server/service.h b/server/service.h index 2ba9ee6..bb01554 100644 --- a/server/service.h +++ b/server/service.h @@ -22,7 +22,7 @@ namespace service { extern std::list<service_info> installed_services; - void handle_data(session *s, proto::packet &p); + bool handle_data(session *s, proto::packet &p); }; #endif diff --git a/server/session.cpp b/server/session.cpp index bb6ffd4..f86e7f1 100644 --- a/server/session.cpp +++ b/server/session.cpp @@ -43,7 +43,8 @@ void session::handle_read(const boost::system::error_code& error, size_t bytes_t delete [] recv_data; packet p(v); v.clear(); - handle_data(this, p); + if(!handle_data(this, p)) + delete this; } } |