summaryrefslogtreecommitdiff
path: root/server/session.cpp
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-12 21:34:09 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-12 21:34:09 +0200
commit85a13d70cc5249e2f583bb16f0914646aefe4fe6 (patch)
tree3c83832a146120a8ec8f026ab97af2698936e72c /server/session.cpp
parent1d41574c6e8e7bbf3705645feb429df6281ccb83 (diff)
server and shell exec module should work now
TODO: implement basic protocol support in client
Diffstat (limited to 'server/session.cpp')
-rw-r--r--server/session.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/server/session.cpp b/server/session.cpp
new file mode 100644
index 0000000..6bbf107
--- /dev/null
+++ b/server/session.cpp
@@ -0,0 +1,296 @@
+// Copyright © 2013 sss
+//.
+// 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 program 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 program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#include "headers.h"
+
+using namespace proto;
+using namespace service;
+
+void session::handle_handshake(const boost::system::error_code& error)
+{
+ if (!error)
+ {
+ recv_data = new char [32];
+ socket_.async_read_some(boost::asio::buffer(recv_data, 32), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+}
+
+void session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ if (!error)
+ {
+// std::cout<<"recieved: "<<recv_data<<"\n";
+ std::vector<unsigned char> v;
+ v.assign(recv_data, recv_data + bytes_transferred);
+ delete [] recv_data;
+ packet p(v);
+ v.clear();
+ if(!p.is_good())
+ {
+ delete this;
+ }
+ switch(p.get_type())
+ {
+ case TYPE_AUTH_REQUEST:
+ {
+ if(!packet::serv_validate_client_proto(p))
+ {
+ packet *r = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_FAILURE);
+ write_w_close(r->raw());
+ delete r;
+ return;
+ }
+ else
+ {
+ packet *r = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS);
+ write_w_response(r->raw());
+ delete r;
+ return;
+ }
+ }
+ break;
+ case TYPE_COMMAND_REQUEST:
+ {
+ svc_cmd c = packet::serv_extract_command(p);
+ if(c.service.empty())
+ break;
+ std::list<service_info>::iterator i = std::find(installed_services.begin(), installed_services.end(), c.service);
+ if(!c.command.empty())
+ {
+ if(i != installed_services.end())
+ {
+ std::list<service_info::command>::iterator ii = std::find(i->predefined.begin(), i->predefined.end(), c.command);
+ if(ii != i->predefined.end())
+ {
+ switch(i->acc)
+ {
+ case ACC_CHAR_PTR:
+ {
+ switch(i->ret)
+ {
+ case RET_CHAR_PTR:
+ {
+ char *arg = strdup(c.command.c_str());
+ char *data = (char*)i->exec((void*)arg);
+ std::string s(data);
+ delete [] data;
+ packet *p = packet::serv_make_command_reply_packet(s, STATUS_SUCCESS);
+ delete [] data;
+ write_w_response(p->raw());
+ delete p;
+ }
+ break;
+ case RET_FLOAT_PTR:
+ {
+ char *arg = strdup(c.command.c_str());
+ float *ret = (float*)i->exec((void*)arg);
+ //todo pack float to unsigned char vector
+ std::vector<unsigned char> v;
+ packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete ret;
+ }
+ break;
+ case RET_INT_PTR:
+ {
+ char *arg = strdup(c.command.c_str());
+ int *ret = (int*)i->exec((void*)arg);
+ //todo pack float to unsigned char vector
+ std::vector<unsigned char> v;
+ packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete ret;
+ }
+ break;
+ case RET_NONE:
+ {
+ char *arg = strdup(c.command.c_str());
+ i->exec((void*)arg);
+ packet *p = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ }
+ break;
+ case RET_STD_STRING_PTR:
+ {
+ char *arg = strdup(c.command.c_str());
+ std::string *str = (std::string*)i->exec((void*)arg);
+ packet *p = packet::serv_make_command_reply_packet(*str, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete str;
+ }
+ break;
+ case RET_VOID_PTR:
+ {
+ //TODO
+ }
+ break;
+ };
+ }
+ break;
+ case ACC_FLOAT_PTR:
+ {
+ }
+ break;
+ case ACC_INT_PTR:
+ {
+ }
+ break;
+ case ACC_STD_STRING_PTR:
+ {
+ }
+ break;
+ case ACC_VOID_PTR:
+ {
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(i->acc == ACC_NONE)
+ {
+ switch(i->ret)
+ {
+ case RET_CHAR_PTR:
+ {
+ char *data = (char*)i->exec((void*)NULL);
+ std::string s(data);
+ delete [] data;
+ packet *p = packet::serv_make_command_reply_packet(s, STATUS_SUCCESS);
+ delete [] data;
+ write_w_response(p->raw());
+ delete p;
+ }
+ break;
+ case RET_FLOAT_PTR:
+ {
+ float *ret = (float*)i->exec((void*)NULL);
+ //todo pack float to unsigned char vector
+ std::vector<unsigned char> v;
+ packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete ret;
+ }
+ break;
+ case RET_INT_PTR:
+ {
+ int *ret = (int*)i->exec((void*)NULL);
+ //todo pack float to unsigned char vector
+ std::vector<unsigned char> v;
+ packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete ret;
+ }
+ break;
+ case RET_NONE:
+ {
+ i->exec((void*)NULL);
+ packet *p = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ }
+ break;
+ case RET_STD_STRING_PTR:
+ {
+ std::string *str = (std::string*)i->exec((void*)NULL);
+ packet *p = packet::serv_make_command_reply_packet(*str, STATUS_SUCCESS);
+ write_w_response(p->raw());
+ delete p;
+ delete str;
+ }
+ break;
+ case RET_VOID_PTR:
+ {
+ //TODO
+ }
+ break;
+ };
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+void session::handle_write(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ delete [] snd_data;
+ if(error)
+ {
+
+ delete this;
+ return; //?
+ }
+ recv_data = (char*)new unsigned char[128];
+ socket_.async_read_some(boost::asio::buffer(recv_data, 128), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+}
+
+void session::write_w_close(const std::vector<unsigned char>& data)
+{
+ snd_data = (char*)new unsigned char[data.size() + 1];
+ memset(snd_data, 0, data.size() + 1);
+ for(int i = 0; i < data.size(); i++)
+ snd_data[i] = data[i];
+ socket_.async_write_some(boost::asio::buffer(snd_data, data.size() + 1), boost::bind(&session::handle_write_close, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+}
+
+void session::write_w_response(const std::vector<unsigned char>& data)
+{
+ pack_buffer(data);
+ socket_.async_write_some(boost::asio::buffer(snd_data, data.size()+1), boost::bind(&session::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+}
+
+void session::write_wo_response(const std::vector<unsigned char>& data)
+{
+ pack_buffer(data);
+ socket_.async_write_some(boost::asio::buffer(snd_data, data.size() +1), boost::bind(&session::handle_operation, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+}
+
+
+void session::handle_write_close(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ delete [] snd_data;
+ delete this;
+}
+
+void session::handle_operation(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ delete [] snd_data;
+}
+
+void session::pack_buffer(const std::vector<unsigned char>& data)
+{
+ snd_data = (char*)new unsigned char[data.size()+1];
+ memset(snd_data, 0, data.size()+1);
+ for(int i = 0; i < data.size(); i++)
+ snd_data[i] = data[i];
+}