From c44be3f81d673540b8e464977fb530f6cfea10ba Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Thu, 18 May 2017 20:08:16 +0200 Subject: [PATCH] api: various fixes - prefer calloc to zero memory - bind: keep the normal network read access with -b 0.0.0.0 like previous versions - help: keep the write mode commands hidden in read-only mode - close the socket on refused api calls to prevent client hangs - small other changes --- api.cpp | 67 ++++++++++++++++++++++++++--------------------------- ccminer.cpp | 16 ++++++++++--- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/api.cpp b/api.cpp index b08938f..0ec023f 100644 --- a/api.cpp +++ b/api.cpp @@ -83,7 +83,7 @@ static struct IP4ACCESS *ipaccess = NULL; #define SOCK_REC_BUFSZ 1024 #define QUEUE 10 -//#define ALLIP4 "0.0.0.0" +#define ALLIP4 "0.0.0.0" static const char *localaddr = "127.0.0.1"; static const char *UNAVAILABLE = " - API will not be available"; static const char *MUNAVAILABLE = " - API multicast listener will not be available"; @@ -503,8 +503,10 @@ static char *gethelp(char *params) { *buffer = '\0'; char * p = buffer; - for (int i = 0; i < CMDMAX-1; i++) - p += sprintf(p, "%s\n", cmds[i].name); + for (int i = 0; i < CMDMAX-1; i++) { + bool displayed = !cmds[i].iswritemode || opt_api_allow; + if (displayed) p += sprintf(p, "%s\n", cmds[i].name); + } sprintf(p, "|"); return buffer; } @@ -673,15 +675,14 @@ static int websocket_handshake(SOCKETTYPE c, char *result, char *clientkey) static void setup_groups() { const char *api_groups = opt_api_groups ? opt_api_groups : ""; - char *buf, *ptr, *next, *colon; + char *buf, *cmd, *ptr, *next, *colon; + char commands[512] = { 0 }; + char cmdbuf[128] = { 0 }; char group; - char commands[512]; - char cmdbuf[100]; - char *cmd; - bool addstar, did; + bool addstar; int i; - buf = (char *)malloc(strlen(api_groups) + 1); + buf = (char *)calloc(1, strlen(api_groups) + 1); if (unlikely(!buf)) proper_exit(1); //, "Failed to malloc ipgroups buf"); @@ -731,8 +732,8 @@ static void setup_groups() if (strcmp(ptr, "*") == 0) addstar = true; else { - did = false; - for (i = 0; cmds[i].name != NULL; i++) { + bool did = false; + for (i = 0; i < CMDMAX-1; i++) { if (strcasecmp(ptr, cmds[i].name) == 0) { did = true; break; @@ -757,7 +758,7 @@ static void setup_groups() // * = allow all non-iswritemode commands if (addstar) { - for (i = 0; cmds[i].name != NULL; i++) { + for (i = 0; i < CMDMAX-1; i++) { if (cmds[i].iswritemode == false) { // skip duplicates sprintf(cmdbuf, "|%s|", cmds[i].name); @@ -771,7 +772,7 @@ static void setup_groups() } } - ptr = apigroups[GROUPOFFSET(group)].commands = (char *)malloc(strlen(commands) + 1); + ptr = apigroups[GROUPOFFSET(group)].commands = (char *)calloc(1, strlen(commands) + 1); if (unlikely(!ptr)) proper_exit(1); //, "Failed to malloc group commands buf"); @@ -782,7 +783,7 @@ static void setup_groups() cmd = &(commands[0]); *(cmd++) = '|'; *cmd = '\0'; - for (i = 0; cmds[i].name != NULL; i++) { + for (i = 0; i < CMDMAX-1; i++) { if (cmds[i].iswritemode == false) { strcpy(cmd, cmds[i].name); cmd += strlen(cmds[i].name); @@ -791,7 +792,7 @@ static void setup_groups() } } - ptr = apigroups[GROUPOFFSET(NOPRIVGROUP)].commands = (char *)malloc(strlen(commands) + 1); + ptr = apigroups[GROUPOFFSET(NOPRIVGROUP)].commands = (char *)calloc(1, strlen(commands) + 1); if (unlikely(!ptr)) proper_exit(1); //, "Failed to malloc noprivgroup commands buf"); @@ -857,7 +858,7 @@ static void setup_ipaccess() ipaccess[ips].group = group; - if (strcmp(ptr, ALLIPS) == 0) + if (strcmp(ptr, ALLIPS) == 0 || strcmp(ptr, ALLIP4) == 0) ipaccess[ips].ip = ipaccess[ips].mask = 0; else { @@ -920,6 +921,8 @@ static bool check_connect(struct sockaddr_in *cli, char **connectaddr, char *gro } } } + else if (strcmp(opt_api_bind, ALLIP4) == 0) + addrok = true; else addrok = (strcmp(*connectaddr, localaddr) == 0); @@ -995,13 +998,13 @@ static void mcast() } expect_code_len = sizeof(expect) + strlen(opt_api_mcast_code); - expect_code = (char *)malloc(expect_code_len + 1); + expect_code = (char *)calloc(1, expect_code_len + 1); if (!expect_code) proper_exit(1); //, "Failed to malloc mcast expect_code"); snprintf(expect_code, expect_code_len + 1, "%s%s-", expect, opt_api_mcast_code); count = 0; - while (80085) { + while (42) { sleep(1); count++; @@ -1016,8 +1019,9 @@ static void mcast() addrok = check_connect(&came_from, &connectaddr, &group); applog(LOG_DEBUG, "API mcast from %s - %s", connectaddr, addrok ? "Accepted" : "Ignored"); - if (!addrok) + if (!addrok) { continue; + } buf[rep] = '\0'; if (rep > 0 && buf[rep - 1] == '\n') @@ -1044,14 +1048,12 @@ static void mcast() snprintf(replybuf, sizeof(replybuf), "ccm-%s-%d-%s", opt_api_mcast_code, opt_api_port, opt_api_mcast_des); - rep = sendto(reply_sock, replybuf, strlen(replybuf) + 1, - 0, (struct sockaddr *)(&came_from), - sizeof(came_from)); + rep = sendto(reply_sock, replybuf, (int) strlen(replybuf) + 1, + 0, (struct sockaddr *)(&came_from), (int) sizeof(came_from)); if (SOCKETFAIL(rep)) { applog(LOG_DEBUG, "API mcast send reply failed (%s) (%d)", strerror(errno), (int)reply_sock); - } - else { + } else { applog(LOG_DEBUG, "API mcast send reply (%s) succeeded (%d) (%d)", replybuf, (int)rep, (int)reply_sock); } @@ -1064,7 +1066,6 @@ static void mcast() } die: - CLOSESOCKET(mcast_sock); } @@ -1211,14 +1212,12 @@ static void api() return; } - if (opt_api_allow) - applog(LOG_WARNING, "API running in IP access mode on port %d (%d)", port, (int)*apisock); - else { - if (strcmp(opt_api_bind, "127.0.0.1")) - applog(LOG_WARNING, "API running in UNRESTRICTED read access mode on port %d (%d)", port, (int)*apisock); - else - applog(LOG_WARNING, "API running in local read access mode on port %d (%d)", port, (int)*apisock); - } + if (opt_api_allow && strcmp(opt_api_bind, "127.0.0.1") == 0) + applog(LOG_WARNING, "API open locally in full access mode on port %d", opt_api_port); + else if (opt_api_allow) + applog(LOG_WARNING, "API open in full access mode to %s on port %d", opt_api_allow, opt_api_port); + else if (strcmp(opt_api_bind, "127.0.0.1") != 0) + applog(LOG_INFO, "API open to the network in read-only mode on port %d", opt_api_port); if (opt_api_mcast) mcast_init(); @@ -1309,8 +1308,8 @@ static void api() break; } } - CLOSESOCKET(c); } + CLOSESOCKET(c); } } diff --git a/ccminer.cpp b/ccminer.cpp index aba98d8..652a884 100644 --- a/ccminer.cpp +++ b/ccminer.cpp @@ -324,7 +324,8 @@ Options:\n\ --cpu-affinity set process affinity to cpu core(s), mask 0x3 for cores 0 and 1\n\ --cpu-priority set process priority (default: 3) 0 idle, 2 normal to 5 highest\n\ -b, --api-bind=port IP:port for the miner API (default: 127.0.0.1:4068), 0 disabled\n\ - --api-remote Allow remote control, like pool switching\n\ + --api-remote Allow remote control, like pool switching, imply --api-allow=0/0\n\ + --api-allow=... IP/mask of the allowed api client(s), 0/0 for all\n\ --max-temp=N Only mine if gpu temp is less than specified value\n\ --max-rate=N[KMG] Only mine if net hashrate is less than specified value\n\ --max-diff=N Only mine if net difficulty is less than specified value\n\ @@ -593,6 +594,11 @@ void proper_exit(int reason) #endif free(opt_syslog_pfx); free(opt_api_bind); + if (opt_api_allow) free(opt_api_allow); + if (opt_api_groups) free(opt_api_groups); + free(opt_api_mcast_addr); + free(opt_api_mcast_code); + free(opt_api_mcast_des); //free(work_restart); //free(thr_info); exit(reason); @@ -3005,14 +3011,18 @@ void parse_arg(int key, char *arg) } break; case 1030: /* --api-remote */ + if (opt_api_allow) free(opt_api_allow); opt_api_allow = strdup("0/0"); break; case 1031: /* --api-allow */ - free(opt_api_allow); + // --api-allow 0/0 means opened to all, so assume -b 0.0.0.0 + if (!strcmp(arg, "0/0") && !strcmp(opt_api_bind, "127.0.0.1")) + parse_arg('b', (char*)"0.0.0.0"); + if (opt_api_allow) free(opt_api_allow); opt_api_allow = strdup(arg); break; case 1032: /* --api-groups */ - free(opt_api_groups); + if (opt_api_groups) free(opt_api_groups); opt_api_groups = strdup(arg); break; case 1033: /* --api-mcast */