summaryrefslogtreecommitdiff
path: root/server/main.cpp
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2012-09-04 12:01:53 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2012-09-04 12:01:53 +0300
commit614b78470c5ed3c701abdd32bc65412f363a6fc2 (patch)
tree288d7967378bb980544c2ca74fd6bf04e4efd590 /server/main.cpp
parent3ab3d03b8b603f210d878d352b56442eec14f6af (diff)
added restarter project (code wcreated to restart critical services on server without root access)
Diffstat (limited to 'server/main.cpp')
-rw-r--r--server/main.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/server/main.cpp b/server/main.cpp
new file mode 100644
index 0000000..240ee22
--- /dev/null
+++ b/server/main.cpp
@@ -0,0 +1,305 @@
+//
+// async_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <cstdlib>
+
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <fstream>
+#include <boost/bind.hpp>
+#include <boost/asio.hpp>
+#include <boost/asio/ssl.hpp>
+
+using boost::asio::ip::tcp;
+typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
+
+class session
+{
+public:
+ session(boost::asio::io_service& io_service,
+ boost::asio::ssl::context& context)
+ : socket_(io_service, context) {
+ }
+
+ ssl_socket::lowest_layer_type& socket()
+ {
+ return socket_.lowest_layer();
+ }
+
+ void handle_handshake(const boost::system::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(boost::asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+ void start()
+ {
+ socket_.async_handshake(boost::asio::ssl::stream_base::server,
+ boost::bind(&session::handle_handshake, this,
+ boost::asio::placeholders::error));
+ }
+
+private:
+ void handle_read(const boost::system::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+// std::cout<<"recieved: "<<data_<<"\n";
+ if(strstr(data_, "restart vbox"))
+ {
+ FILE *f = popen("/sbin/runscript /etc/init.d/vbox_headles restart --nodeps","r");
+ if(f != NULL)
+ {
+ char buf[128];
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ int s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ }
+ else if(strstr(data_, "reboot now"))
+ {
+ FILE *f = popen("reboot","r");
+ if(f != NULL)
+ {
+ char buf[128];
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ int s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ }
+ else if(strstr(data_, "halt now"))
+ {
+ FILE *f = popen("halt","r");
+ if(f != NULL)
+ {
+ char buf[128];
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ int s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ }
+ else if(strstr(data_, "restart cups"))
+ {
+ FILE *f = popen("/sbin/runscript /etc/init.d/cupsd restart --nodeps","r");
+ if(f != NULL)
+ {
+ char buf[128];
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ int s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ }
+ else if(strstr(data_, "restart ppp"))
+ {
+ FILE *f = popen("/sbin/runscript /etc/init.d/net.ppp0 stop --nodeps","r");
+ char buf[128];
+ int s = 0;
+ if(f != NULL)
+ {
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ sleep(3);
+ f = popen("killall pppd","r");
+ if(f == NULL)
+ {
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ sleep(1);
+ f = popen("/sbin/runscript /etc/init.d/net.ppp0 start --nodeps","r");
+ if(f == NULL)
+ {
+ while(fgets(buf, 128, f) != NULL)
+ ; //TODO: do something with output
+ s = pclose(f); // TODO: handle exit status
+ }
+ else
+ ; //TODO: handle fail
+ }
+/* boost::asio::async_write(socket_,
+ boost::asio::buffer(data_, bytes_transferred),
+ boost::bind(&session::handle_write, this,
+ boost::asio::placeholders::error)); */
+ }
+ delete this;
+ }
+
+/* void handle_write(const boost::system::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(boost::asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+ }*/
+
+ ssl_socket socket_;
+ enum { max_length = 32 };
+ char data_[max_length];
+};
+
+class server
+{
+public:
+/* server(boost::asio::io_service& io_service, short port)
+ : io_service_(io_service),
+ acceptor_(io_service, tcp::endpoint(boost::asio::ip::address_v4::from_string("192.168.0.1"), port)),
+ context_(boost::asio::ssl::context::sslv23) */
+ server(boost::asio::io_service& io_service, short port)
+ : io_service_(io_service),
+ acceptor_(io_service, tcp::endpoint(boost::asio::ip::address_v4(), port)),
+ context_(boost::asio::ssl::context::sslv23)
+ {
+ 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_rsa_private_key_file("/etc/restarter_server/serv.key", boost::asio::ssl::context::pem);
+ context_.load_verify_file("/etc/restarter_server/ca.crt");
+ context_.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_client_once);
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ session* new_session = new session(io_service_, context_);
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ boost::asio::placeholders::error));
+ }
+ std::string get_password() const
+ {
+ return "";
+ }
+
+ void handle_accept(session* new_session,
+ const boost::system::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+ else
+ {
+ delete new_session;
+ }
+
+ start_accept();
+ }
+
+ boost::asio::io_service& io_service_;
+ boost::asio::ip::tcp::acceptor acceptor_;
+ boost::asio::ssl::context context_;
+};
+
+extern "C" void handle_term(int i)
+{
+ remove("/var/run/restarter_server.pid");
+ exit(1);
+}
+
+int main(int argc, char* argv[])
+{
+ if(geteuid())
+ {
+ std::cout<<"Program must be runned with root privilegies\n";
+ exit(EXIT_FAILURE);
+ }
+ {
+ std::ifstream in_pid;
+ in_pid.open("/var/run/restarter_server.pid");
+ if(in_pid.is_open() && in_pid.good())
+ {
+ char szpid[16];
+ in_pid.read(szpid, 16);
+ if(!strcmp(szpid, "0"))
+ remove("/var/run/restarter_server.pid");
+ else
+ {
+ std::string cmd = "kill ";
+ for(int i = 0; i < 16 && szpid[i] != '\n' && szpid[i] != '\0'; i++)
+ cmd.push_back(szpid[i]);
+ system(cmd.c_str());
+ remove("/var/run/restarter_server.pid");
+ }
+ }
+ }
+ pid_t pid;
+ pid = fork();
+ if(pid < 0)
+ {
+ std::cerr<<"Failed to fork\n";
+ exit(EXIT_FAILURE);
+ }
+ if(pid > 0)
+ {
+ std::cerr<<"Successfuly forked\n";
+ std::ofstream out;
+ out.open("/var/run/restarter_server.pid");
+ char szpid[16];
+ snprintf(szpid, 15, "%d", pid);
+ out<<pid<<"\n";
+ out.close();
+ exit(EXIT_SUCCESS);
+ }
+ signal (SIGTERM, handle_term);
+
+ try
+ {
+
+ boost::asio::io_service io_service;
+
+ server s(io_service, 1313);
+
+ io_service.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+} \ No newline at end of file