summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proto_lib/api_protocol.h1
-rw-r--r--proto_lib/packet.cpp17
-rw-r--r--restarter.workspace1
-rw-r--r--server/api_service.h4
-rw-r--r--server/service.h27
-rw-r--r--server/session.cpp296
-rw-r--r--server/session.h53
-rw-r--r--services/unix_exec_service/main.cpp23
8 files changed, 411 insertions, 11 deletions
diff --git a/proto_lib/api_protocol.h b/proto_lib/api_protocol.h
index 2e42d42..b18d2e7 100644
--- a/proto_lib/api_protocol.h
+++ b/proto_lib/api_protocol.h
@@ -64,6 +64,7 @@ public:
static bool serv_validate_client_proto(packet&); //false on fail
static packet *serv_make_services_packet(std::list<service_s>&);
static packet *serv_make_command_reply_packet(std::string&, status s);
+ static packet *serv_make_command_reply_packet(std::vector<unsigned char>&, status s);
static svc_cmd serv_extract_command(packet&);
//generic
diff --git a/proto_lib/packet.cpp b/proto_lib/packet.cpp
index 0ed3150..92272a8 100644
--- a/proto_lib/packet.cpp
+++ b/proto_lib/packet.cpp
@@ -271,11 +271,18 @@ packet *packet::serv_make_command_reply_packet(std::string &str, status s)
pack_serv_header(v);
pack_buffer(type_command, sizeof(type_command), v);
v.push_back(s);
- if(!str.empty())
- {
- for(size_t i = 0; i < str.length(); i++)
- v.push_back(str[i]);
- }
+ pack_buffer(str, v);
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+packet *packet::serv_make_command_reply_packet(std::vector<unsigned char>& data, status s)
+{
+ std::vector<unsigned char> v;
+ pack_serv_header(v);
+ pack_buffer(type_command, sizeof(type_command), v);
+ v.push_back(s);
+ pack_buffer(data, v);
pack_buffer(proto_footer, sizeof(proto_footer), v);
return new packet(v);
}
diff --git a/restarter.workspace b/restarter.workspace
index 79a199e..5c304ff 100644
--- a/restarter.workspace
+++ b/restarter.workspace
@@ -17,6 +17,7 @@
</BuildMatrix>
<Environment>
<![CDATA[
+
]]>
</Environment>
</CodeLite_Workspace>
diff --git a/server/api_service.h b/server/api_service.h
index 4f5a183..ddfdc8f 100644
--- a/server/api_service.h
+++ b/server/api_service.h
@@ -21,8 +21,8 @@ namespace service
{
-enum service_return {RET_NONE = 2, RET_VOID_PTR = 4, RET_CHAR_PTR = 8, RET_STD_STRING = 16, RET_INT, RET_FLOAT = 32};
-enum service_accept {ACC_NONE = 2, ACC_VOID_PTR = 4, ACC_CHAR_PTR = 8, ACC_STD_STRING = 16, ACC_INT, ACC_FLOAT = 32};
+enum service_return {RET_NONE = 2, RET_VOID_PTR = 4, RET_CHAR_PTR = 8, RET_STD_STRING_PTR = 16, RET_INT_PTR, RET_FLOAT_PTR = 32};
+enum service_accept {ACC_NONE = 2, ACC_VOID_PTR = 4, ACC_CHAR_PTR = 8, ACC_STD_STRING_PTR = 16, ACC_INT_PTR, ACC_FLOAT_PTR = 32};
//service may have predefined command set
diff --git a/server/service.h b/server/service.h
new file mode 100644
index 0000000..d27f8f3
--- /dev/null
+++ b/server/service.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef SERVICE_H
+#define SERVICE_H
+
+#include "headers.h"
+
+namespace service {
+
+extern std::list<service_info> installed_services;
+
+};
+#endif
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];
+}
diff --git a/server/session.h b/server/session.h
new file mode 100644
index 0000000..6e3bb1b
--- /dev/null
+++ b/server/session.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef SESSION_H
+#define SESSION_H
+
+
+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);
+ void start()
+ {
+ socket_.async_handshake(boost::asio::ssl::stream_base::server, boost::bind(&session::handle_handshake, this, boost::asio::placeholders::error));
+ }
+
+private:
+ void write_w_close(const std::vector<unsigned char>& data);
+ void write_w_response(const std::vector<unsigned char>& data);
+ void write_wo_response(const std::vector<unsigned char>& data);
+ void handle_read(const boost::system::error_code& error, size_t bytes_transferred);
+ void handle_write(const boost::system::error_code& error, size_t bytes_transferred);
+ void handle_write_close(const boost::system::error_code& error, size_t bytes_transferred);
+ void handle_operation(const boost::system::error_code& error, size_t bytes_transferred);
+ void pack_buffer(const std::vector<unsigned char>& data);
+ ssl_socket socket_;
+ char *snd_data, *recv_data;
+};
+
+
+#endif
diff --git a/services/unix_exec_service/main.cpp b/services/unix_exec_service/main.cpp
index ad7da1f..331c98f 100644
--- a/services/unix_exec_service/main.cpp
+++ b/services/unix_exec_service/main.cpp
@@ -58,8 +58,21 @@ void * shell_exec(void * t)
cmd = c;
if(!cmd.empty())
{
+ FILE *f = popen(cmd.c_str(), "r");
+ if(f)
+ {
+ std::string *ret = new std::string;
+ char buf[128];
+ while(fgets(buf, 128, f))
+ ret->append(buf);
+ return (void*)ret;
+ }
+ else
+ {
+ //TODO: handle fail (need to extend service api ?)
+ }
}
- return NULL;
+ return (void*)new std::string;
}
void load_cmds()
@@ -99,15 +112,17 @@ void load_cmds()
p1++;
descr = str.substr(p1);
}
+ service_info::command c;
if(!_alias.empty())
{
alias a;
a._alias = _alias;
a.cmd = cmd;
+ c.command = _alias;
aliases.push_back(a);
}
- service_info::command c;
- c.command = cmd;
+ else
+ c.command = cmd;
c.description = descr;
cmds.push_back(c);
// printf("%s | %s | %s\n", _alias.c_str(), cmd.c_str(), descr.c_str());
@@ -123,7 +138,7 @@ services(get_services)
{
service_info shell_exec_service;
shell_exec_service.acc = ACC_CHAR_PTR;
- shell_exec_service.ret = RET_STD_STRING;
+ shell_exec_service.ret = RET_STD_STRING_PTR;
shell_exec_service.name = "Shell exec";
shell_exec_service.description = "Run shell command and return output";
shell_exec_service.exec = &shell_exec;