diff options
author | 2016-02-15 03:12:29 -0500 | |
---|---|---|
committer | 2016-02-15 07:11:26 -0500 | |
commit | ec369cd722a400130b9b754c2c965ec60beb9d56 (patch) | |
tree | 0b6f3bcaaa957983fd148548f09bd1ae4b900cfd /src/rpc-server | |
parent | 1f60016f591ebd2e260e501c8c5da10c11d0c7ad (diff) |
many bugs uncovered by the PCAP injection:
1. NamedTuple constructor
2. Scappy
3. zlib for server
Diffstat (limited to 'src/rpc-server')
-rw-r--r-- | src/rpc-server/trex_rpc_req_resp_server.cpp | 55 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_req_resp_server.h | 4 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_zip.cpp | 124 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_zip.h | 60 |
4 files changed, 231 insertions, 12 deletions
diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp index 1e8e177d..da7e8c55 100644 --- a/src/rpc-server/trex_rpc_req_resp_server.cpp +++ b/src/rpc-server/trex_rpc_req_resp_server.cpp @@ -22,6 +22,7 @@ limitations under the License. #include <trex_rpc_server_api.h> #include <trex_rpc_req_resp_server.h> #include <trex_rpc_jsonrpc_v2_parser.h> +#include <trex_rpc_zip.h> #include <unistd.h> #include <sstream> @@ -138,20 +139,33 @@ void TrexRpcServerReqRes::_stop_rpc_thread() { * respondes to the request */ void TrexRpcServerReqRes::handle_request(const std::string &request) { - std::string response_str = process_request(request); - zmq_send(m_socket, response_str.c_str(), response_str.size(), 0); + std::string response; + + process_request(request, response); + + zmq_send(m_socket, response.c_str(), response.size(), 0); +} + +void TrexRpcServerReqRes::process_request(const std::string &request, std::string &response) { + + if (TrexRpcZip::is_compressed(request)) { + process_zipped_request(request, response); + } else { + process_request_raw(request, response); + } + } /** * main processing of the request * */ -std::string TrexRpcServerReqRes::process_request(const std::string &request) { +void TrexRpcServerReqRes::process_request_raw(const std::string &request, std::string &response) { std::vector<TrexJsonRpcV2ParsedObject *> commands; Json::FastWriter writer; - Json::Value response; + Json::Value response_json; /* first parse the request using JSON RPC V2 parser */ TrexJsonRpcV2Parser rpc_request(request); @@ -171,7 +185,7 @@ std::string TrexRpcServerReqRes::process_request(const std::string &request) { command->execute(single_response); delete command; - response[index++] = single_response; + response_json[index++] = single_response; } @@ -181,17 +195,32 @@ std::string TrexRpcServerReqRes::process_request(const std::string &request) { } /* write the JSON to string and sever on ZMQ */ - std::string response_str; if (response.size() == 1) { - response_str = writer.write(response[0]); + response = writer.write(response_json[0]); } else { - response_str = writer.write(response); + response = writer.write(response_json); } - verbose_json("Server Replied: ", response_str); + verbose_json("Server Replied: ", response); + +} + +void TrexRpcServerReqRes::process_zipped_request(const std::string &request, std::string &response) { + std::string unzipped; + + /* try to uncomrpess - if fails, last shot is the JSON RPC */ + bool rc = TrexRpcZip::uncompress(request, unzipped); + if (!rc) { + return process_request_raw(request, response); + } + + /* process the request */ + std::string raw_response; + process_request_raw(unzipped, raw_response); + + TrexRpcZip::compress(raw_response, response); - return response_str; } /** @@ -218,7 +247,11 @@ TrexRpcServerReqRes::handle_server_error(const std::string &specific_err) { std::string TrexRpcServerReqRes::test_inject_request(const std::string &req) { - return process_request(req); + std::string response; + + process_request(req, response); + + return response; } diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h index 97efbe08..979bf9af 100644 --- a/src/rpc-server/trex_rpc_req_resp_server.h +++ b/src/rpc-server/trex_rpc_req_resp_server.h @@ -45,7 +45,9 @@ protected: bool fetch_one_request(std::string &msg); void handle_request(const std::string &request); - std::string process_request(const std::string &request); + void process_request(const std::string &request, std::string &response); + void process_request_raw(const std::string &request, std::string &response); + void process_zipped_request(const std::string &request, std::string &response); void handle_server_error(const std::string &specific_err); diff --git a/src/rpc-server/trex_rpc_zip.cpp b/src/rpc-server/trex_rpc_zip.cpp new file mode 100644 index 00000000..ef5c4834 --- /dev/null +++ b/src/rpc-server/trex_rpc_zip.cpp @@ -0,0 +1,124 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "trex_rpc_zip.h" +#include <zlib.h> +#include <arpa/inet.h> +#include <iostream> + +bool +TrexRpcZip::is_compressed(const std::string &input) { + /* check for minimum size */ + if (input.size() < sizeof(header_st)) { + return false; + } + + /* cast */ + const header_st *header = (header_st *)input.c_str(); + + /* check magic */ + uint32_t magic = ntohl(header->magic); + if (magic != G_HEADER_MAGIC) { + return false; + } + + return true; +} + +bool +TrexRpcZip::uncompress(const std::string &input, std::string &output) { + + /* sanity check first */ + if (!is_compressed(input)) { + return false; + } + + /* cast */ + const header_st *header = (header_st *)input.c_str(); + + /* original size */ + uint32_t uncmp_size = ntohl(header->uncmp_size); + + /* alocate dynamic space for the uncomrpessed buffer */ + Bytef *u_buffer = new Bytef[uncmp_size]; + if (!u_buffer) { + return false; + } + + /* set the target buffer size */ + uLongf dest_len = uncmp_size; + + /* try to uncompress */ + int z_err = ::uncompress(u_buffer, + &dest_len, + (const Bytef *)header->data, + (uLong)input.size() - sizeof(header_st)); + + if (z_err != Z_OK) { + delete [] u_buffer; + return false; + } + + output.append((const char *)u_buffer, dest_len); + + delete [] u_buffer; + return true; +} + + +bool +TrexRpcZip::compress(const std::string &input, std::string &output) { + + /* get a bound */ + int bound_size = compressBound((uLong)input.size()) + sizeof(header_st); + + /* alocate dynamic space for the uncomrpessed buffer */ + char *buffer = new char[bound_size]; + if (!buffer) { + return false; + } + + header_st *header = (header_st *)buffer; + uLongf destLen = bound_size; + + int z_err = ::compress((Bytef *)header->data, + &destLen, + (const Bytef *)input.c_str(), + (uLong)input.size()); + + if (z_err != Z_OK) { + delete [] buffer; + return false; + } + + /* terminate string */ + header->data[destLen] = 0; + + /* add the header */ + header->magic = htonl(G_HEADER_MAGIC); + header->uncmp_size = htonl(input.size()); + + output.append((const char *)header, bound_size); + + delete [] buffer; + + return true; +} diff --git a/src/rpc-server/trex_rpc_zip.h b/src/rpc-server/trex_rpc_zip.h new file mode 100644 index 00000000..4b9930b4 --- /dev/null +++ b/src/rpc-server/trex_rpc_zip.h @@ -0,0 +1,60 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include <string> + +class TrexRpcZip { +public: + + /** + * return true if message is compressed + * + */ + static bool is_compressed(const std::string &input); + + /** + * uncompress an 'input' to 'output' + * on success return true else returns false + */ + static bool uncompress(const std::string &input, std::string &output); + + /** + * compress 'input' to 'output' + * on success return true else returns false + */ + static bool compress(const std::string &input, std::string &output); + +private: + + /** + * packed header for reading binary compressed messages + * + * @author imarom (15-Feb-16) + */ + struct header_st { + uint32_t magic; + uint32_t uncmp_size; + char data[0]; + } __attribute__((packed)); + + + static const uint32_t G_HEADER_MAGIC = 0xABE85CEA; +}; + |