mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-11 07:17:58 +00:00
Merge pull request #243 from kanoi/master
define, implement and document API option --api-groups
This commit is contained in:
commit
4c5d41a8dd
42
API-README
42
API-README
@ -19,8 +19,9 @@ IP addresses are automatically padded with extra '.0's as needed
|
|||||||
Without a /prefix is the same as specifying /32
|
Without a /prefix is the same as specifying /32
|
||||||
0/0 means all IP addresses.
|
0/0 means all IP addresses.
|
||||||
The 'W:' on the front gives that address/subnet privileged access to commands
|
The 'W:' on the front gives that address/subnet privileged access to commands
|
||||||
that modify cgminer.
|
that modify cgminer (thus all API commands)
|
||||||
Without it those commands return an access denied status.
|
Without it those commands return an access denied status.
|
||||||
|
See --api-groups below to define other groups like W:
|
||||||
Privileged access is checked in the order the IP addresses were supplied to
|
Privileged access is checked in the order the IP addresses were supplied to
|
||||||
"--api-allow"
|
"--api-allow"
|
||||||
The first match determines the privilege level.
|
The first match determines the privilege level.
|
||||||
@ -28,6 +29,26 @@ Using the "--api-allow" option overides the "--api-network" option if they
|
|||||||
are both specified
|
are both specified
|
||||||
With "--api-allow", 127.0.0.1 is not by default given access unless specified
|
With "--api-allow", 127.0.0.1 is not by default given access unless specified
|
||||||
|
|
||||||
|
More groups (like the privileged group W:) can be defined using the
|
||||||
|
--api-groups command
|
||||||
|
Valid groups are only the letters A-Z (except R & W are predefined) and are
|
||||||
|
not case sensitive
|
||||||
|
The R: group is the same as not privileged access
|
||||||
|
The W: group is (as stated) privileged access (thus all API commands)
|
||||||
|
To give an IP address/subnet access to a group you use the group letter
|
||||||
|
in front of the IP address instead of W: e.g. P:192.168.0/32
|
||||||
|
An IP address/subnet can only be a member of one group
|
||||||
|
A sample API group would be:
|
||||||
|
--api-groups P:switchpool:enablepool:addpool:disablepool:removepool:*
|
||||||
|
This would create a group 'P' that can do all current pool commands and all
|
||||||
|
non-priviliged commands - the '*' means all non-priviledged commands
|
||||||
|
Without the '*' the group would only have access to the pool commands
|
||||||
|
Defining multiple groups example:
|
||||||
|
--api-groups Q:quit:restart:*,S:save
|
||||||
|
This would define 2 groups:
|
||||||
|
Q: that can 'quit' and 'restart' as well as all non-priviledged commands
|
||||||
|
S: that can only 'save' and no other commands
|
||||||
|
|
||||||
The RPC API request can be either simple text or JSON.
|
The RPC API request can be either simple text or JSON.
|
||||||
|
|
||||||
If the request is JSON (starts with '{'), it will reply with a JSON formatted
|
If the request is JSON (starts with '{'), it will reply with a JSON formatted
|
||||||
@ -86,8 +107,8 @@ The list of requests - a (*) means it requires privileged access - and replies a
|
|||||||
|
|
||||||
Request Reply Section Details
|
Request Reply Section Details
|
||||||
------- ------------- -------
|
------- ------------- -------
|
||||||
version VERSION CGMiner=cgminer version
|
version VERSION CGMiner=cgminer, version
|
||||||
API=API version
|
API=API| version
|
||||||
|
|
||||||
config CONFIG Some miner configuration information:
|
config CONFIG Some miner configuration information:
|
||||||
GPU Count=N, <- the number of GPUs
|
GPU Count=N, <- the number of GPUs
|
||||||
@ -243,6 +264,9 @@ The list of requests - a (*) means it requires privileged access - and replies a
|
|||||||
Device drivers are also able to add stats to the
|
Device drivers are also able to add stats to the
|
||||||
end of the details returned
|
end of the details returned
|
||||||
|
|
||||||
|
check|cmd COMMAND Exists=Y/N, <- 'cmd' exists in this version
|
||||||
|
Access=Y/N| <- you have access to use 'cmd'
|
||||||
|
|
||||||
When you enable, disable or restart a GPU or PGA, you will also get Thread messages
|
When you enable, disable or restart a GPU or PGA, you will also get Thread messages
|
||||||
in the cgminer status window
|
in the cgminer status window
|
||||||
|
|
||||||
@ -285,7 +309,17 @@ miner.php - an example web page to access the API
|
|||||||
Feature Changelog for external applications using the API:
|
Feature Changelog for external applications using the API:
|
||||||
|
|
||||||
|
|
||||||
API V1.12
|
API V1.13
|
||||||
|
|
||||||
|
Added API commands:
|
||||||
|
'check'
|
||||||
|
|
||||||
|
Support was added to cgminer for API access groups with the --api-groups option
|
||||||
|
It's 100% backwards compatible with previous --api-access commands
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
API V1.12 (cgminer v2.4.3)
|
||||||
|
|
||||||
Modified API commands:
|
Modified API commands:
|
||||||
'stats' - more pool stats added
|
'stats' - more pool stats added
|
||||||
|
2
README
2
README
@ -119,6 +119,8 @@ Options for both config file and command line:
|
|||||||
This overrides --api-network and you must specify 127.0.0.1 if it is required
|
This overrides --api-network and you must specify 127.0.0.1 if it is required
|
||||||
W: in front of the IP address gives that address privileged access to all api commands
|
W: in front of the IP address gives that address privileged access to all api commands
|
||||||
--api-description Description placed in the API status header (default: cgminer version)
|
--api-description Description placed in the API status header (default: cgminer version)
|
||||||
|
--api-groups API one letter groups G:cmd:cmd[,P:cmd:*...]
|
||||||
|
See API-README for usage
|
||||||
--api-listen Listen for API requests (default: disabled)
|
--api-listen Listen for API requests (default: disabled)
|
||||||
By default any command that does not just display data returns access denied
|
By default any command that does not just display data returns access denied
|
||||||
See --api-allow to overcome this
|
See --api-allow to overcome this
|
||||||
|
320
api.c
320
api.c
@ -158,6 +158,7 @@ static char *msg_buffer = NULL;
|
|||||||
static SOCKETTYPE sock = INVSOCK;
|
static SOCKETTYPE sock = INVSOCK;
|
||||||
|
|
||||||
static const char *UNAVAILABLE = " - API will not be available";
|
static const char *UNAVAILABLE = " - API will not be available";
|
||||||
|
static const char *GROUPDIS = " - groups will be disabled";
|
||||||
|
|
||||||
static const char *BLANK = "";
|
static const char *BLANK = "";
|
||||||
static const char *COMMA = ",";
|
static const char *COMMA = ",";
|
||||||
@ -165,7 +166,7 @@ static const char SEPARATOR = '|';
|
|||||||
#define SEPSTR "|"
|
#define SEPSTR "|"
|
||||||
static const char GPUSEP = ',';
|
static const char GPUSEP = ',';
|
||||||
|
|
||||||
static const char *APIVERSION = "1.12";
|
static const char *APIVERSION = "1.13";
|
||||||
static const char *DEAD = "Dead";
|
static const char *DEAD = "Dead";
|
||||||
static const char *SICK = "Sick";
|
static const char *SICK = "Sick";
|
||||||
static const char *NOSTART = "NoStart";
|
static const char *NOSTART = "NoStart";
|
||||||
@ -243,6 +244,7 @@ static const char *OSINFO =
|
|||||||
#define _BYE "BYE"
|
#define _BYE "BYE"
|
||||||
#define _RESTART "RESTART"
|
#define _RESTART "RESTART"
|
||||||
#define _MINESTATS "STATS"
|
#define _MINESTATS "STATS"
|
||||||
|
#define _CHECK "CHECK"
|
||||||
|
|
||||||
static const char ISJSON = '{';
|
static const char ISJSON = '{';
|
||||||
#define JSON0 "{"
|
#define JSON0 "{"
|
||||||
@ -277,6 +279,7 @@ static const char ISJSON = '{';
|
|||||||
#define JSON_RESTART JSON1 _RESTART JSON1
|
#define JSON_RESTART JSON1 _RESTART JSON1
|
||||||
#define JSON_CLOSE JSON3
|
#define JSON_CLOSE JSON3
|
||||||
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
|
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
|
||||||
|
#define JSON_CHECK JSON1 _CHECK JSON2
|
||||||
#define JSON_END JSON4
|
#define JSON_END JSON4
|
||||||
|
|
||||||
static const char *JSON_COMMAND = "command";
|
static const char *JSON_COMMAND = "command";
|
||||||
@ -364,6 +367,8 @@ static const char *JSON_PARAMETER = "parameter";
|
|||||||
#define MSG_REMPOOL 68
|
#define MSG_REMPOOL 68
|
||||||
#define MSG_DEVDETAILS 69
|
#define MSG_DEVDETAILS 69
|
||||||
#define MSG_MINESTATS 70
|
#define MSG_MINESTATS 70
|
||||||
|
#define MSG_MISCHK 71
|
||||||
|
#define MSG_CHECK 72
|
||||||
|
|
||||||
enum code_severity {
|
enum code_severity {
|
||||||
SEVERITY_ERR,
|
SEVERITY_ERR,
|
||||||
@ -507,6 +512,8 @@ struct CODES {
|
|||||||
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
|
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
|
||||||
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
|
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
|
||||||
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "CGMiner stats" },
|
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "CGMiner stats" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" },
|
||||||
|
{ SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" },
|
||||||
{ SEVERITY_FAIL, 0, 0, NULL }
|
{ SEVERITY_FAIL, 0, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -525,9 +532,25 @@ static time_t when = 0; // when the request occurred
|
|||||||
struct IP4ACCESS {
|
struct IP4ACCESS {
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
in_addr_t mask;
|
in_addr_t mask;
|
||||||
bool writemode;
|
char group;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GROUP(g) (toupper(g))
|
||||||
|
#define PRIVGROUP GROUP('W')
|
||||||
|
#define NOPRIVGROUP GROUP('R')
|
||||||
|
#define ISPRIVGROUP(g) (GROUP(g) == PRIVGROUP)
|
||||||
|
#define GROUPOFFSET(g) (GROUP(g) - GROUP('A'))
|
||||||
|
#define VALIDGROUP(g) (GROUP(g) >= GROUP('A') && GROUP(g) <= GROUP('Z'))
|
||||||
|
#define COMMANDS(g) (apigroups[GROUPOFFSET(g)].commands)
|
||||||
|
#define DEFINEDGROUP(g) (ISPRIVGROUP(g) || COMMANDS(g) != NULL)
|
||||||
|
|
||||||
|
struct APIGROUPS {
|
||||||
|
// This becomes a string like: "|cmd1|cmd2|cmd3|" so it's quick to search
|
||||||
|
char *commands;
|
||||||
|
} apigroups['Z' - 'A' + 1]; // only A=0 to Z=25 (R: noprivs, W: allprivs)
|
||||||
|
|
||||||
|
static bool groups_enabled = false;
|
||||||
|
|
||||||
static struct IP4ACCESS *ipaccess = NULL;
|
static struct IP4ACCESS *ipaccess = NULL;
|
||||||
static int ips = 0;
|
static int ips = 0;
|
||||||
|
|
||||||
@ -796,7 +819,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
|
|||||||
return msg_buffer;
|
return msg_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
sprintf(io_buffer, isjson
|
sprintf(io_buffer, isjson
|
||||||
? "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE
|
? "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE
|
||||||
@ -805,7 +828,7 @@ static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|||||||
VERSION, APIVERSION);
|
VERSION, APIVERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
int gpucount = 0;
|
int gpucount = 0;
|
||||||
@ -1003,7 +1026,7 @@ static void cpustatus(int cpu, bool isjson)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int devcount = 0;
|
int devcount = 0;
|
||||||
int numgpu = 0;
|
int numgpu = 0;
|
||||||
@ -1069,7 +1092,7 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
#ifdef HAVE_OPENCL
|
||||||
static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -1103,7 +1126,7 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_AN_FPGA
|
#ifdef HAVE_AN_FPGA
|
||||||
static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int numpga = numpgas();
|
int numpga = numpgas();
|
||||||
int id;
|
int id;
|
||||||
@ -1137,7 +1160,7 @@ static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcat(io_buffer, JSON_CLOSE);
|
strcat(io_buffer, JSON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int numpga = numpgas();
|
int numpga = numpgas();
|
||||||
struct thr_info *thr;
|
struct thr_info *thr;
|
||||||
@ -1193,7 +1216,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_PGAENA, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_PGAENA, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int numpga = numpgas();
|
int numpga = numpgas();
|
||||||
int id;
|
int id;
|
||||||
@ -1234,7 +1257,7 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WANT_CPUMINE
|
#ifdef WANT_CPUMINE
|
||||||
static void cpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void cpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -1268,7 +1291,7 @@ static void cpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
char *status, *lp;
|
char *status, *lp;
|
||||||
@ -1345,7 +1368,7 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|||||||
strcat(io_buffer, JSON_CLOSE);
|
strcat(io_buffer, JSON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
double utility, mhs;
|
double utility, mhs;
|
||||||
|
|
||||||
@ -1379,7 +1402,7 @@ static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef HAVE_OPENCL
|
#ifdef HAVE_OPENCL
|
||||||
static void gpuenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void gpuenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
struct thr_info *thr;
|
struct thr_info *thr;
|
||||||
int gpu;
|
int gpu;
|
||||||
@ -1425,7 +1448,7 @@ static void gpuenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_GPUREN, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_GPUREN, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpudisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void gpudisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -1455,7 +1478,7 @@ static void gpudisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_GPUDIS, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_GPUDIS, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpurestart(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void gpurestart(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -1480,7 +1503,7 @@ static void gpurestart(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_GPUREI, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_GPUREI, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
int numgpu = 0;
|
int numgpu = 0;
|
||||||
@ -1499,8 +1522,7 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
|
|||||||
strcat(io_buffer, buf);
|
strcat(io_buffer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -1519,7 +1541,7 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
|
|||||||
strcat(io_buffer, buf);
|
strcat(io_buffer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -1538,7 +1560,7 @@ static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
|
|||||||
strcat(io_buffer, buf);
|
strcat(io_buffer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switchpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void switchpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
int id;
|
int id;
|
||||||
@ -1619,7 +1641,7 @@ exitsama:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char *url, *user, *pass;
|
char *url, *user, *pass;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -1647,7 +1669,7 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
int id;
|
int id;
|
||||||
@ -1681,7 +1703,7 @@ static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_ENAPOOL, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_ENAPOOL, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
int id;
|
int id;
|
||||||
@ -1720,7 +1742,7 @@ static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_DISPOOL, id, NULL, isjson));
|
strcpy(io_buffer, message(MSG_DISPOOL, id, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void removepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
char *rpc_url;
|
char *rpc_url;
|
||||||
@ -1806,7 +1828,7 @@ static bool splitgpuvalue(char *param, int *gpu, char **value, bool isjson)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static void gpuintensity(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
static void gpuintensity(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
char *value;
|
char *value;
|
||||||
@ -1835,7 +1857,7 @@ static void gpuintensity(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
|||||||
strcpy(io_buffer, message(MSG_GPUINT, id, intensitystr, isjson));
|
strcpy(io_buffer, message(MSG_GPUINT, id, intensitystr, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpumem(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void gpumem(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
int id;
|
int id;
|
||||||
@ -1856,7 +1878,7 @@ static void gpumem(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpuengine(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void gpuengine(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
int id;
|
int id;
|
||||||
@ -1877,7 +1899,7 @@ static void gpuengine(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpufan(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void gpufan(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
int id;
|
int id;
|
||||||
@ -1898,7 +1920,7 @@ static void gpufan(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
int id;
|
int id;
|
||||||
@ -1919,7 +1941,7 @@ static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
if (isjson)
|
if (isjson)
|
||||||
strcpy(io_buffer, JSON_START JSON_BYE);
|
strcpy(io_buffer, JSON_START JSON_BYE);
|
||||||
@ -1930,7 +1952,7 @@ void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson
|
|||||||
do_a_quit = true;
|
do_a_quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dorestart(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
void dorestart(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
if (isjson)
|
if (isjson)
|
||||||
strcpy(io_buffer, JSON_START JSON_RESTART);
|
strcpy(io_buffer, JSON_START JSON_RESTART);
|
||||||
@ -1941,12 +1963,12 @@ void dorestart(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isj
|
|||||||
do_a_restart = true;
|
do_a_restart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
strcpy(io_buffer, message(MSG_ACCOK, 0, NULL, isjson));
|
strcpy(io_buffer, message(MSG_ACCOK, 0, NULL, isjson));
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifystatus(int device, struct cgpu_info *cgpu, bool isjson)
|
void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
char *reason;
|
char *reason;
|
||||||
@ -2000,7 +2022,7 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson)
|
|||||||
strcat(io_buffer, buf);
|
strcat(io_buffer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2017,13 +2039,13 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < total_devices; i++)
|
for (i = 0; i < total_devices; i++)
|
||||||
notifystatus(i, devices[i], isjson);
|
notifystatus(i, devices[i], isjson, group);
|
||||||
|
|
||||||
if (isjson)
|
if (isjson)
|
||||||
strcat(io_buffer, JSON_CLOSE);
|
strcat(io_buffer, JSON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
struct cgpu_info *cgpu;
|
struct cgpu_info *cgpu;
|
||||||
@ -2059,7 +2081,7 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|||||||
strcat(io_buffer, JSON_CLOSE);
|
strcat(io_buffer, JSON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
FILE *fcfg;
|
FILE *fcfg;
|
||||||
@ -2135,7 +2157,8 @@ static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgmine
|
|||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
|
|
||||||
|
static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char extra[TMPBUFSIZ];
|
char extra[TMPBUFSIZ];
|
||||||
char id[20];
|
char id[20];
|
||||||
@ -2174,10 +2197,12 @@ static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|||||||
strcat(io_buffer, JSON_CLOSE);
|
strcat(io_buffer, JSON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group);
|
||||||
|
|
||||||
struct CMDS {
|
struct CMDS {
|
||||||
char *name;
|
char *name;
|
||||||
void (*func)(SOCKETTYPE, char *, bool);
|
void (*func)(SOCKETTYPE, char *, bool, char);
|
||||||
bool requires_writemode;
|
bool iswritemode;
|
||||||
} cmds[] = {
|
} cmds[] = {
|
||||||
{ "version", apiversion, false },
|
{ "version", apiversion, false },
|
||||||
{ "config", minerconfig, false },
|
{ "config", minerconfig, false },
|
||||||
@ -2220,9 +2245,47 @@ struct CMDS {
|
|||||||
{ "devdetails", devdetails, false },
|
{ "devdetails", devdetails, false },
|
||||||
{ "restart", dorestart, true },
|
{ "restart", dorestart, true },
|
||||||
{ "stats", minerstats, false },
|
{ "stats", minerstats, false },
|
||||||
|
{ "check", checkcommand, false },
|
||||||
{ NULL, NULL, false }
|
{ NULL, NULL, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group)
|
||||||
|
{
|
||||||
|
char buf[TMPBUFSIZ];
|
||||||
|
char cmdbuf[100];
|
||||||
|
bool found, access;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (param == NULL || *param == '\0') {
|
||||||
|
strcpy(io_buffer, message(MSG_MISCHK, 0, NULL, isjson));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
found = false;
|
||||||
|
access = false;
|
||||||
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
|
if (strcmp(cmds[i].name, param) == 0) {
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
sprintf(cmdbuf, "|%s|", param);
|
||||||
|
if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf))
|
||||||
|
access = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(io_buffer, message(MSG_CHECK, 0, NULL, isjson));
|
||||||
|
|
||||||
|
sprintf(buf, isjson
|
||||||
|
? "," JSON_CHECK "{\"Exists\":\"%s\",\"Access\":\"%s\"}" JSON_CLOSE
|
||||||
|
: _CHECK ",Exists=%s,Access=%s" SEPSTR,
|
||||||
|
found ? YES : NO,
|
||||||
|
access ? YES : NO);
|
||||||
|
|
||||||
|
strcat(io_buffer, buf);
|
||||||
|
}
|
||||||
|
|
||||||
static void send_result(SOCKETTYPE c, bool isjson)
|
static void send_result(SOCKETTYPE c, bool isjson)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -2277,7 +2340,154 @@ static void tidyup(__maybe_unused void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interpret [R|W:]IP[/Prefix][,[R|W:]IP2[/Prefix2][,...]] --api-allow option
|
* Interpret --api-groups G:cmd1:cmd2:cmd3,P:cmd4,*,...
|
||||||
|
*/
|
||||||
|
static void setup_groups()
|
||||||
|
{
|
||||||
|
char *buf, *ptr, *next, *colon;
|
||||||
|
char group;
|
||||||
|
char commands[TMPBUFSIZ];
|
||||||
|
char cmdbuf[100];
|
||||||
|
char *cmd;
|
||||||
|
bool addstar, did;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
buf = malloc(strlen(opt_api_groups) + 1);
|
||||||
|
if (unlikely(!buf))
|
||||||
|
quit(1, "Failed to malloc ipgroups buf");
|
||||||
|
|
||||||
|
strcpy(buf, opt_api_groups);
|
||||||
|
|
||||||
|
next = buf;
|
||||||
|
// for each group defined
|
||||||
|
while (next && *next) {
|
||||||
|
ptr = next;
|
||||||
|
next = strchr(ptr, ',');
|
||||||
|
if (next)
|
||||||
|
*(next++) = '\0';
|
||||||
|
|
||||||
|
// Validate the group
|
||||||
|
if (*(ptr+1) != ':') {
|
||||||
|
colon = strchr(ptr, ':');
|
||||||
|
if (colon)
|
||||||
|
*colon = '\0';
|
||||||
|
applog(LOG_WARNING, "API invalid group name '%s'%s", ptr, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
|
||||||
|
group = GROUP(*ptr);
|
||||||
|
if (!VALIDGROUP(group)) {
|
||||||
|
applog(LOG_WARNING, "API invalid group name '%c'%s", *ptr, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group == PRIVGROUP) {
|
||||||
|
applog(LOG_WARNING, "API group name can't be '%c'%s", PRIVGROUP, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group == NOPRIVGROUP) {
|
||||||
|
applog(LOG_WARNING, "API group name can't be '%c'%s", NOPRIVGROUP, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apigroups[GROUPOFFSET(group)].commands != NULL) {
|
||||||
|
applog(LOG_WARNING, "API duplicate group name '%c'%s", *ptr, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
|
// Validate the command list (and handle '*')
|
||||||
|
cmd = &(commands[0]);
|
||||||
|
*(cmd++) = SEPARATOR;
|
||||||
|
*cmd = '\0';
|
||||||
|
addstar = false;
|
||||||
|
while (ptr && *ptr) {
|
||||||
|
colon = strchr(ptr, ':');
|
||||||
|
if (colon)
|
||||||
|
*(colon++) = '\0';
|
||||||
|
|
||||||
|
if (strcmp(ptr, "*") == 0)
|
||||||
|
addstar = true;
|
||||||
|
else {
|
||||||
|
did = false;
|
||||||
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
|
if (strcasecmp(ptr, cmds[i].name) == 0) {
|
||||||
|
did = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (did) {
|
||||||
|
// skip duplicates
|
||||||
|
sprintf(cmdbuf, "|%s|", cmds[i].name);
|
||||||
|
if (strstr(commands, cmdbuf) == NULL) {
|
||||||
|
strcpy(cmd, cmds[i].name);
|
||||||
|
cmd += strlen(cmds[i].name);
|
||||||
|
*(cmd++) = SEPARATOR;
|
||||||
|
*cmd = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
applog(LOG_WARNING, "API unknown command '%s' in group '%c'%s", ptr, group, GROUPDIS);
|
||||||
|
goto shin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = colon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * = allow all non-iswritemode commands
|
||||||
|
if (addstar) {
|
||||||
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
|
if (cmds[i].iswritemode == false) {
|
||||||
|
// skip duplicates
|
||||||
|
sprintf(cmdbuf, "|%s|", cmds[i].name);
|
||||||
|
if (strstr(commands, cmdbuf) == NULL) {
|
||||||
|
strcpy(cmd, cmds[i].name);
|
||||||
|
cmd += strlen(cmds[i].name);
|
||||||
|
*(cmd++) = SEPARATOR;
|
||||||
|
*cmd = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = apigroups[GROUPOFFSET(group)].commands = malloc(strlen(commands) + 1);
|
||||||
|
if (unlikely(!ptr))
|
||||||
|
quit(1, "Failed to malloc group commands buf");
|
||||||
|
|
||||||
|
strcpy(ptr, commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now define R (NOPRIVGROUP) as all non-iswritemode commands
|
||||||
|
cmd = &(commands[0]);
|
||||||
|
*(cmd++) = SEPARATOR;
|
||||||
|
*cmd = '\0';
|
||||||
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
|
if (cmds[i].iswritemode == false) {
|
||||||
|
strcpy(cmd, cmds[i].name);
|
||||||
|
cmd += strlen(cmds[i].name);
|
||||||
|
*(cmd++) = SEPARATOR;
|
||||||
|
*cmd = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = apigroups[GROUPOFFSET(NOPRIVGROUP)].commands = malloc(strlen(commands) + 1);
|
||||||
|
if (unlikely(!ptr))
|
||||||
|
quit(1, "Failed to malloc noprivgroup commands buf");
|
||||||
|
|
||||||
|
strcpy(ptr, commands);
|
||||||
|
|
||||||
|
// W (PRIVGROUP) is handled as a special case since it simply means all commands
|
||||||
|
|
||||||
|
groups_enabled = true;
|
||||||
|
shin:
|
||||||
|
free(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interpret [W:]IP[/Prefix][,[R|W:]IP2[/Prefix2][,...]] --api-allow option
|
||||||
* special case of 0/0 allows /0 (means all IP addresses)
|
* special case of 0/0 allows /0 (means all IP addresses)
|
||||||
*/
|
*/
|
||||||
#define ALLIP4 "0/0"
|
#define ALLIP4 "0/0"
|
||||||
@ -2288,7 +2498,7 @@ static void setup_ipaccess()
|
|||||||
{
|
{
|
||||||
char *buf, *ptr, *comma, *slash, *dot;
|
char *buf, *ptr, *comma, *slash, *dot;
|
||||||
int ipcount, mask, octet, i;
|
int ipcount, mask, octet, i;
|
||||||
bool writemode;
|
char group;
|
||||||
|
|
||||||
buf = malloc(strlen(opt_api_allow) + 1);
|
buf = malloc(strlen(opt_api_allow) + 1);
|
||||||
if (unlikely(!buf))
|
if (unlikely(!buf))
|
||||||
@ -2322,16 +2532,16 @@ static void setup_ipaccess()
|
|||||||
if (comma)
|
if (comma)
|
||||||
*(comma++) = '\0';
|
*(comma++) = '\0';
|
||||||
|
|
||||||
writemode = false;
|
group = NOPRIVGROUP;
|
||||||
|
|
||||||
if (isalpha(*ptr) && *(ptr+1) == ':') {
|
if (isalpha(*ptr) && *(ptr+1) == ':') {
|
||||||
if (tolower(*ptr) == 'w')
|
if (DEFINEDGROUP(*ptr))
|
||||||
writemode = true;
|
group = GROUP(*ptr);
|
||||||
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipaccess[ips].writemode = writemode;
|
ipaccess[ips].group = group;
|
||||||
|
|
||||||
if (strcmp(ptr, ALLIP4) == 0)
|
if (strcmp(ptr, ALLIP4) == 0)
|
||||||
ipaccess[ips].ip = ipaccess[ips].mask = 0;
|
ipaccess[ips].ip = ipaccess[ips].mask = 0;
|
||||||
@ -2421,10 +2631,11 @@ void api(int api_thr_id)
|
|||||||
struct sockaddr_in serv;
|
struct sockaddr_in serv;
|
||||||
struct sockaddr_in cli;
|
struct sockaddr_in cli;
|
||||||
socklen_t clisiz;
|
socklen_t clisiz;
|
||||||
|
char cmdbuf[100];
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *param;
|
char *param;
|
||||||
bool addrok;
|
bool addrok;
|
||||||
bool writemode;
|
char group;
|
||||||
json_error_t json_err;
|
json_error_t json_err;
|
||||||
json_t *json_config;
|
json_t *json_config;
|
||||||
json_t *json_val;
|
json_t *json_val;
|
||||||
@ -2445,6 +2656,9 @@ void api(int api_thr_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_api_groups)
|
||||||
|
setup_groups();
|
||||||
|
|
||||||
if (opt_api_allow) {
|
if (opt_api_allow) {
|
||||||
setup_ipaccess();
|
setup_ipaccess();
|
||||||
|
|
||||||
@ -2523,12 +2737,13 @@ void api(int api_thr_id)
|
|||||||
connectaddr = inet_ntoa(cli.sin_addr);
|
connectaddr = inet_ntoa(cli.sin_addr);
|
||||||
|
|
||||||
addrok = false;
|
addrok = false;
|
||||||
writemode = false;
|
group = NOPRIVGROUP;
|
||||||
if (opt_api_allow) {
|
if (opt_api_allow) {
|
||||||
|
if (groups_enabled)
|
||||||
for (i = 0; i < ips; i++) {
|
for (i = 0; i < ips; i++) {
|
||||||
if ((cli.sin_addr.s_addr & ipaccess[i].mask) == ipaccess[i].ip) {
|
if ((cli.sin_addr.s_addr & ipaccess[i].mask) == ipaccess[i].ip) {
|
||||||
addrok = true;
|
addrok = true;
|
||||||
writemode = ipaccess[i].writemode;
|
group = ipaccess[i].group;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2622,12 +2837,13 @@ void api(int api_thr_id)
|
|||||||
if (!did)
|
if (!did)
|
||||||
for (i = 0; cmds[i].name != NULL; i++) {
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
if (strcmp(cmd, cmds[i].name) == 0) {
|
if (strcmp(cmd, cmds[i].name) == 0) {
|
||||||
if (cmds[i].requires_writemode && !writemode) {
|
sprintf(cmdbuf, "|%s|", cmd);
|
||||||
|
if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf))
|
||||||
|
(cmds[i].func)(c, param, isjson, group);
|
||||||
|
else {
|
||||||
strcpy(io_buffer, message(MSG_ACCDENY, 0, cmds[i].name, isjson));
|
strcpy(io_buffer, message(MSG_ACCDENY, 0, cmds[i].name, isjson));
|
||||||
applog(LOG_DEBUG, "API: access denied to '%s' for '%s' command", connectaddr, cmds[i].name);
|
applog(LOG_DEBUG, "API: access denied to '%s' for '%s' command", connectaddr, cmds[i].name);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
(cmds[i].func)(c, param, isjson);
|
|
||||||
|
|
||||||
send_result(c, isjson);
|
send_result(c, isjson);
|
||||||
did = true;
|
did = true;
|
||||||
|
15
cgminer.c
15
cgminer.c
@ -131,6 +131,7 @@ bool opt_autofan;
|
|||||||
bool opt_autoengine;
|
bool opt_autoengine;
|
||||||
bool opt_noadl;
|
bool opt_noadl;
|
||||||
char *opt_api_allow = NULL;
|
char *opt_api_allow = NULL;
|
||||||
|
char *opt_api_groups;
|
||||||
char *opt_api_description = PACKAGE_STRING;
|
char *opt_api_description = PACKAGE_STRING;
|
||||||
int opt_api_port = 4028;
|
int opt_api_port = 4028;
|
||||||
bool opt_api_listen;
|
bool opt_api_listen;
|
||||||
@ -680,6 +681,13 @@ static char *set_api_allow(const char *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *set_api_groups(const char *arg)
|
||||||
|
{
|
||||||
|
opt_set_charp(arg, &opt_api_groups);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static char *set_api_description(const char *arg)
|
static char *set_api_description(const char *arg)
|
||||||
{
|
{
|
||||||
opt_set_charp(arg, &opt_api_description);
|
opt_set_charp(arg, &opt_api_description);
|
||||||
@ -730,10 +738,13 @@ static struct opt_table opt_config_table[] = {
|
|||||||
#endif
|
#endif
|
||||||
OPT_WITH_ARG("--api-allow",
|
OPT_WITH_ARG("--api-allow",
|
||||||
set_api_allow, NULL, NULL,
|
set_api_allow, NULL, NULL,
|
||||||
"Allow API access only to the given list of IP[/Prefix] addresses[/subnets]"),
|
"Allow API access only to the given list of [G:]IP[/Prefix] addresses[/subnets]"),
|
||||||
OPT_WITH_ARG("--api-description",
|
OPT_WITH_ARG("--api-description",
|
||||||
set_api_description, NULL, NULL,
|
set_api_description, NULL, NULL,
|
||||||
"Description placed in the API status header, default: cgminer version"),
|
"Description placed in the API status header, default: cgminer version"),
|
||||||
|
OPT_WITH_ARG("--api-groups",
|
||||||
|
set_api_groups, NULL, NULL,
|
||||||
|
"API one letter groups G:cmd:cmd[,P:cmd:*...] defining the cmds a groups can use"),
|
||||||
OPT_WITHOUT_ARG("--api-listen",
|
OPT_WITHOUT_ARG("--api-listen",
|
||||||
opt_set_bool, &opt_api_listen,
|
opt_set_bool, &opt_api_listen,
|
||||||
"Enable API, default: disabled"),
|
"Enable API, default: disabled"),
|
||||||
@ -2872,6 +2883,8 @@ void write_config(FILE *fcfg)
|
|||||||
fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", opt_api_allow);
|
fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", opt_api_allow);
|
||||||
if (strcmp(opt_api_description, PACKAGE_STRING) != 0)
|
if (strcmp(opt_api_description, PACKAGE_STRING) != 0)
|
||||||
fprintf(fcfg, ",\n\"api-description\" : \"%s\"", opt_api_description);
|
fprintf(fcfg, ",\n\"api-description\" : \"%s\"", opt_api_description);
|
||||||
|
if (opt_api_groups)
|
||||||
|
fprintf(fcfg, ",\n\"api-groups\" : \"%s\"", opt_api_groups);
|
||||||
if (opt_icarus_timing)
|
if (opt_icarus_timing)
|
||||||
fprintf(fcfg, ",\n\"icarus-timing\" : \"%s\"", opt_icarus_timing);
|
fprintf(fcfg, ",\n\"icarus-timing\" : \"%s\"", opt_icarus_timing);
|
||||||
fputs("\n}", fcfg);
|
fputs("\n}", fcfg);
|
||||||
|
1
miner.h
1
miner.h
@ -524,6 +524,7 @@ extern bool opt_autofan;
|
|||||||
extern bool opt_autoengine;
|
extern bool opt_autoengine;
|
||||||
extern bool use_curses;
|
extern bool use_curses;
|
||||||
extern char *opt_api_allow;
|
extern char *opt_api_allow;
|
||||||
|
extern char *opt_api_groups;
|
||||||
extern char *opt_api_description;
|
extern char *opt_api_description;
|
||||||
extern int opt_api_port;
|
extern int opt_api_port;
|
||||||
extern bool opt_api_listen;
|
extern bool opt_api_listen;
|
||||||
|
Loading…
Reference in New Issue
Block a user