Add simple XML-RPC access control

Also add --xmlrpc-list switch
pull/2/head
Stelios Bounanos 2008-09-23 21:10:41 +01:00
rodzic 84b1052300
commit 3c560ae5aa
5 zmienionych plików z 73 dodań i 8 usunięć

Wyświetl plik

@ -232,6 +232,8 @@ struct configuration {
// XMLRPC parameters
string xmlrpc_address;
string xmlrpc_port;
string xmlrpc_allow;
string xmlrpc_deny;
public:
void writeDefaultsXML();

Wyświetl plik

@ -1,6 +1,8 @@
#ifndef XMLRPC_H
#define XMLRPC_H
#include <iosfwd>
class Socket;
class XML_RPC_Server
@ -8,12 +10,13 @@ class XML_RPC_Server
public:
static void start(const char* node, const char* service);
static void stop(void);
static std::ostream& list_methods(std::ostream& out);
private:
XML_RPC_Server();
~XML_RPC_Server();
XML_RPC_Server(const XML_RPC_Server&);
XML_RPC_Server operator=(const XML_RPC_Server&);
void add_methods(void);
static void add_methods(void);
static void* thread_func(void*);
private:

Wyświetl plik

@ -334,6 +334,12 @@ void generate_option_help(void) {
<< " --xmlrpc-server-port PORT\n"
<< " Set the XML-RPC server port\n"
<< " The default is: " << progdefaults.xmlrpc_port << "\n\n"
<< " --xmlrpc-allow REGEX\n"
<< " Allow only the methods whose names match REGEX\n\n"
<< " --xmlrpc-deny REGEX\n"
<< " Allow only the methods whose names don't match REGEX\n\n"
<< " --xmlrpc-list\n"
<< " List all available methods\n\n"
#endif
<< " --debug-level LEVEL\n"
@ -423,6 +429,7 @@ int parse_args(int argc, char **argv, int& idx)
OPT_CONFIG_DIR, OPT_EXPERIMENTAL, OPT_ARQ_ADDRESS, OPT_ARQ_PORT,
#if USE_XMLRPC
OPT_CONFIG_XMLRPC, OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT,
OPT_CONFIG_XMLRPC_ALLOW, OPT_CONFIG_XMLRPC_DENY, OPT_CONFIG_XMLRPC_LIST,
#endif
OPT_FONT, OPT_WFALL_WIDTH, OPT_WFALL_HEIGHT,
OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT,
@ -451,6 +458,9 @@ int parse_args(int argc, char **argv, int& idx)
{ "xmlrpc-server", 0, 0, OPT_CONFIG_XMLRPC },
{ "xmlrpc-server-address", 1, 0, OPT_CONFIG_XMLRPC_ADDRESS },
{ "xmlrpc-server-port", 1, 0, OPT_CONFIG_XMLRPC_PORT },
{ "xmlrpc-allow", 1, 0, OPT_CONFIG_XMLRPC_ALLOW },
{ "xmlrpc-deny", 1, 0, OPT_CONFIG_XMLRPC_DENY },
{ "xmlrpc-list", 0, 0, OPT_CONFIG_XMLRPC_LIST },
#endif
{ "font", 1, 0, OPT_FONT },
@ -526,6 +536,21 @@ int parse_args(int argc, char **argv, int& idx)
case OPT_CONFIG_XMLRPC_PORT:
progdefaults.xmlrpc_port = optarg;
break;
case OPT_CONFIG_XMLRPC_ALLOW:
progdefaults.xmlrpc_allow = optarg;
break;
case OPT_CONFIG_XMLRPC_DENY:
if (!progdefaults.xmlrpc_allow.empty())
cerr << "W: --" << longopts[longindex].name
<< " cannot be used together with --"
<< longopts[OPT_CONFIG_XMLRPC_ALLOW-1].name
<< " and will be ignored\n";
else
progdefaults.xmlrpc_deny = optarg;
break;
case OPT_CONFIG_XMLRPC_LIST:
XML_RPC_Server::list_methods(cout);
exit(EXIT_SUCCESS);
#endif
case OPT_FONT:

Wyświetl plik

@ -266,6 +266,8 @@ configuration progdefaults = {
15, // int VIEWERtimeout
"127.0.0.1", // string xmlrpc_address
"7362", // string xmlrpc_port
"", // string xmlrpc_allow
"" // string xmlrpc_deny
};
const char *szBaudRates[] = {

Wyświetl plik

@ -24,8 +24,11 @@
#include "xmlrpc.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <exception>
#include <cstdlib>
@ -54,6 +57,7 @@
#include "rigMEM.h"
#include "rigio.h"
#include "debug.h"
#include "re.h"
using namespace std;
@ -64,7 +68,8 @@ struct rpc_method
xmlrpc_c::methodPtr method;
const char* name;
};
vector<rpc_method>* methods;
typedef list<rpc_method> methods_t;
methods_t* methods = 0;
static Fl_Thread* server_thread;
@ -73,7 +78,6 @@ XML_RPC_Server* XML_RPC_Server::inst = 0;
XML_RPC_Server::XML_RPC_Server()
{
server_socket = new Socket;
methods = new vector<rpc_method>;
add_methods();
server_thread = new Fl_Thread;
@ -85,6 +89,7 @@ XML_RPC_Server::~XML_RPC_Server()
pthread_join(*server_thread, NULL);
delete server_thread;
delete methods;
methods = 0;
}
@ -119,10 +124,9 @@ void* XML_RPC_Server::thread_func(void*)
SET_THREAD_ID(XMLRPC_TID);
xmlrpc_c::registry reg;
for (vector<rpc_method>::iterator i = methods->begin(); i != methods->end(); i++)
for (methods_t::iterator i = methods->begin(); i != methods->end(); ++i)
reg.addMethod(i->name, i->method);
xmlrpc_c::serverAbyss server(xmlrpc_c::serverAbyss::constrOpt()
.registryP(&reg)
#ifndef NDEBUG
@ -160,6 +164,17 @@ ret:
return NULL;
}
ostream& XML_RPC_Server::list_methods(ostream& out)
{
add_methods();
ios_base::fmtflags f = out.flags(ios::left);
for (methods_t::const_iterator i = methods->begin(); i != methods->end(); ++i)
out << setw(32) << i->name << setw(8) << i->method->signature()
<< i->method->help() << '\n';
return out << setiosflags(f);
}
// =============================================================================
// helper functions
@ -198,7 +213,7 @@ public:
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
vector<xmlrpc_c::value> help;
for (vector<rpc_method>::const_iterator i = methods->begin(); i != methods->end(); i++) {
for (methods_t::const_iterator i = methods->begin(); i != methods->end(); ++i) {
map<string, xmlrpc_c::value> item;
item["name"] = xmlrpc_c::value_string(i->name);
item["signature"] = xmlrpc_c::value_string(i->method->signature());
@ -1449,10 +1464,23 @@ public:
// End XML-RPC interface
struct rm_pred
{
re_t filter;
bool allow;
rm_pred(const char* re, bool allow_)
: filter(re, REG_EXTENDED | REG_NOSUB), allow(allow_) { }
bool operator()(const methods_t::value_type& v)
{
return filter.match(v.name) ^ allow && !strstr(v.name, "fldigi.");
}
};
void XML_RPC_Server::add_methods(void)
{
methods->clear();
methods->reserve(72);
if (methods)
return;
methods = new methods_t;
methods->push_back(rpc_method(new Fldigi_list, "fldigi.list"));
methods->push_back(rpc_method(new Fldigi_name, "fldigi.name"));
@ -1543,4 +1571,9 @@ void XML_RPC_Server::add_methods(void)
methods->push_back(rpc_method(new Text_add_tx, "text.add_tx"));
methods->push_back(rpc_method(new Text_add_tx_bytes, "text.add_tx_bytes"));
methods->push_back(rpc_method(new Text_clear_tx, "text.clear_tx"));
if (!progdefaults.xmlrpc_deny.empty())
methods->remove_if(rm_pred(progdefaults.xmlrpc_deny.c_str(), false));
else if (!progdefaults.xmlrpc_allow.empty())
methods->remove_if(rm_pred(progdefaults.xmlrpc_allow.c_str(), true));
}