security token is now part of the JsonAdapter class. new version "(14) Köln-Gremberg"
parent
278c2df800
commit
de410a8125
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue