security token is now part of the JsonAdapter class. new version "(14) Köln-Gremberg"

as-a-library
Roker 2016-08-02 18:49:21 +02:00
parent 278c2df800
commit de410a8125
7 changed files with 49 additions and 35 deletions

View File

@ -56,7 +56,8 @@ const std::string server_version =
// "(10) Kreuz Köln-West"; // More fields in JavaScript for "message", 1-element identity list to support message->to attribute
// "(11) Köln-Klettenberg"; // support for identity_list as output parameter, as needed by import_key() now. Fix some issue with identity.lang
// "(12) Kreuz Köln Süd"; // support for attachments, so encrypt_message() works now! :-) but we have memory corruption, hence the FIXME in pep-types.cc :-(
"(13) Köln-Poll"; // refactoring to avoid copying of parameters. Fixes the memory corruption. Some other clean-ups
// "(13) Köln-Poll"; // refactoring to avoid copying of parameters. Fixes the memory corruption. Some other clean-ups
"(!4) Köln-Gremberg"; // refactoring to use JSON-Adapter as a library
PEP_SESSION createSession()
@ -282,7 +283,7 @@ void OnGetFunctions(evhttp_request* req, void*)
}
void OnApiRequest(evhttp_request* req, void*)
void OnApiRequest(evhttp_request* req, void* obj)
{
evbuffer* inbuf = evhttp_request_get_input_buffer(req);
const size_t length = evbuffer_get_length(inbuf);
@ -294,6 +295,8 @@ void OnApiRequest(evhttp_request* req, void*)
try
{
const JsonAdapter* ja = static_cast<const JsonAdapter*>(obj);
std::vector<char> data(length);
ssize_t nr = evbuffer_copyout(inbuf, data.data(), data.size());
const std::string data_string(data.data(), data.data() + nr );
@ -304,7 +307,7 @@ void OnApiRequest(evhttp_request* req, void*)
if(p.type() == js::obj_type)
{
const js::Object& request = p.get_obj();
answer = call( functions, request );
answer = call( functions, request, ja->sec_token() );
}else{
answer = make_error( JSON_RPC::PARSE_ERROR, "evbuffer_copyout does not return a JSON string. b=" + std::to_string(b), js::Value{data_string}, 42 );
}
@ -428,6 +431,8 @@ struct JsonAdapter::Internal
std::unique_ptr<event_base, decltype(&event_base_free)> eventBase = {nullptr, &event_base_free};
std::unique_ptr<evhttp, decltype(&evhttp_free)> evHttp = {nullptr, &evhttp_free};
std::string address;
std::string token;
unsigned start_port = 0;
unsigned end_port = 0;
unsigned port = 0;
@ -473,10 +478,10 @@ try
{
std::cerr << " +++ Thread starts: isRun=" << i->running << ", id=" << std::this_thread::get_id() << ". +++\n";
evhttp_set_cb(i->evHttp.get(), ApiRequestUrl.c_str() , OnApiRequest , nullptr);
evhttp_set_cb(i->evHttp.get(), CreateSessionUrl.c_str() , OnCreateSession , nullptr);
evhttp_set_cb(i->evHttp.get(), GetAllSessionsUrl.c_str(), OnGetAllSessions, nullptr);
evhttp_set_cb(i->evHttp.get(), "/pep_functions.js" , OnGetFunctions , nullptr);
evhttp_set_cb(i->evHttp.get(), ApiRequestUrl.c_str() , OnApiRequest , this);
evhttp_set_cb(i->evHttp.get(), CreateSessionUrl.c_str() , OnCreateSession , this);
evhttp_set_cb(i->evHttp.get(), GetAllSessionsUrl.c_str(), OnGetAllSessions, this);
evhttp_set_cb(i->evHttp.get(), "/pep_functions.js" , OnGetFunctions , this);
evhttp_set_gencb(i->evHttp.get(), OnOtherRequest, nullptr);
if (i->sock == -1) // no port bound, yet
@ -504,7 +509,9 @@ try_next_port:
throw std::runtime_error("Failed to get server socket for next instance.");
i->port = i->start_port + port_ofs;
create_security_token(i->address, i->port, BaseUrl);
i->token = create_security_token(i->address, i->port, BaseUrl);
std::cout << "Bound to port " << i->port << ", sec_token=\"" << i->token << "\"\n";
}
else
{
@ -564,3 +571,19 @@ void JsonAdapter::shutdown(timeval* t)
}
}
const std::string& JsonAdapter::sec_token() const
{
return i->token;
}
// returns 'true' if 's' is the security token created by the function above.
bool JsonAdapter::verify_security_token(const std::string& s) const
{
if(s!=i->token)
{
std::cerr << "sec_token=\"" << i->token << "\" is unequal to \"" << s << "\"!\n";
}
return s == i->token;
}

View File

@ -36,6 +36,11 @@ public:
unsigned request_count() const;
// returns 'true' if 's' is the security token created by the function above.
bool verify_security_token(const std::string& s) const;
const std::string& sec_token() const;
static
unsigned apiVersion();

View File

@ -45,7 +45,7 @@ namespace
using json_spirit::find_value;
js::Object call(const FunctionMap& fm, const js::Object& request)
js::Object call(const FunctionMap& fm, const js::Object& request, const std::string& sec_token_orig)
{
int request_id = -1;
try
@ -57,7 +57,7 @@ js::Object call(const FunctionMap& fm, const js::Object& request)
}
const auto sec_token = find_value(request, "security_token");
if(sec_token.type()!=js::str_type || verify_security_token(sec_token.get_str()) == false)
if(sec_token.type()!=js::str_type || (sec_token.get_str()!=sec_token_orig) == false)
{
return make_error(JSON_RPC::INVALID_REQUEST, "Invalid request: Wrong security token.", request, request_id);
}

View File

@ -19,7 +19,7 @@ enum class JSON_RPC
// parse the JSON-RPC 2.0 compatible "request", call the function
// and create an appropiate "response" object (containing a result or an error)
js::Object call(const FunctionMap& fm, const js::Object& request);
js::Object call(const FunctionMap& fm, const js::Object& request, const std::string& sec_token_orig);
// create a JSON-RPC 2.0 compatible result response object
js::Object make_result(const js::Value& result, int id);

View File

@ -2,7 +2,7 @@
#include <iostream>
std::string address = "0.0.0.0";
std::string address = "127.0.0.1";
unsigned start_port = 4223;
unsigned end_port = 9999;
@ -21,10 +21,11 @@ try
}while(input != 'q' && input != 'Q');
ja.shutdown(nullptr);
std::cout << "Good bye. :-)" << std::endl;
}
catch (std::exception const &e)
{
std::cerr << "Exception catched in main(): \"" << e.what() << "\"" << std::endl;
return 1;
}

View File

@ -13,8 +13,6 @@
namespace
{
std::string sec_token;
// 36 alphanumeric characters
static const char token_alphabet[] = "qaywsxedcrfvtgbzhnujmikolp1234567890POIUZTREWQASDFGHJKLMNBVCXY";
@ -22,8 +20,7 @@ namespace
{
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis( 0, 32 );
// static std::uniform_int_distribution<> dis( 0, sizeof(token_alphabet)-1 );
static std::uniform_int_distribution<> dis( 0, sizeof(token_alphabet)-1 );
const unsigned left_len = length/2;
const unsigned right_len = length-left_len;
@ -50,7 +47,7 @@ std::string get_token_filename()
}
// creates a file with restrictive access rights that contains a security token.
void create_security_token(const std::string& server_address, unsigned port_nr, const std::string& path)
std::string create_security_token(const std::string& server_address, unsigned port_nr, const std::string& path)
{
const std::string filename = get_token_filename();
int fd = creat( filename.c_str(), S_IRUSR | S_IWUSR );
@ -59,7 +56,7 @@ void create_security_token(const std::string& server_address, unsigned port_nr,
throw std::runtime_error("Cannot create security token file \"" + filename + "\": " + std::to_string(errno) );
}
sec_token = create_random_token();
const std::string sec_token = create_random_token();
js::Object o;
o.emplace_back("address", server_address);
@ -70,16 +67,7 @@ void create_security_token(const std::string& server_address, unsigned port_nr,
const std::string content = js::write( o, js::pretty_print | js::raw_utf8 ) + '\n';
write(fd, content.data(), content.size());
close(fd);
}
// returns 'true' if 's' is the security token created by the function above.
bool verify_security_token(const std::string& s)
{
if(s!=sec_token)
{
std::cerr << "sec_token=\"" << sec_token << "\" is unequal to \"" << s << "\"!\n";
}
return s == sec_token;
return sec_token;
}

View File

@ -3,10 +3,7 @@
#include <string>
// creates a file with restrictive access rights that contains a security token.
void create_security_token(const std::string& server_address, unsigned port_nr, const std::string& path);
// returns 'true' if 's' is the security token created by the function above.
bool verify_security_token(const std::string& s);
// creates a file with restrictive access rights that contains a security token and returns that token, too
std::string create_security_token(const std::string& server_address, unsigned port_nr, const std::string& path);
#endif