From a537fa304c73c539a40be5303d848cc84f4d2e93 Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Fri, 13 Feb 2015 06:57:39 +0100 Subject: [PATCH] Add basic API remote control only allowed if --api-remote parameter or config key is set and fix possible problem with urls containing user:password@ Signed-off-by: Tanguy Pruvot --- api.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++-- ccminer.cpp | 28 ++++++++++++++++------ configure.ac | 2 +- cpuminer-config.h | 6 ++--- miner.h | 1 + 5 files changed, 83 insertions(+), 13 deletions(-) diff --git a/api.cpp b/api.cpp index d2cf041..64364e7 100644 --- a/api.cpp +++ b/api.cpp @@ -8,7 +8,7 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. See COPYING for more details. */ -#define APIVERSION "1.3" +#define APIVERSION "1.4" #ifdef WIN32 # define _WINSOCK_DEPRECATED_NO_WARNINGS @@ -91,6 +91,7 @@ static int bye = 0; extern char *opt_api_allow; extern int opt_api_listen; /* port */ +extern int opt_api_remote; extern uint32_t accepted_count; extern uint32_t rejected_count; extern int num_cpus; @@ -370,6 +371,46 @@ static char *getmeminfo(char *params) /*****************************************************************************/ +/** + * Remote control allowed ? + * TODO: ip filters + */ +static bool check_remote_access(void) +{ + return (opt_api_remote > 0); +} + +/** + * Change pool url (see --url parameter) + * seturl|stratum+tcp://Danila.1:X@pool.ipominer.com:3335| + */ +extern bool stratum_need_reset; +static char *remote_seturl(char *params) +{ + *buffer = '\0'; + if (!check_remote_access()) + return buffer; + parse_arg('o', params); + stratum_need_reset = true; + sprintf(buffer, "%s", "ok|"); + return buffer; +} + +/** + * Ask the miner to quit + */ +static char *remote_quit(char *params) +{ + *buffer = '\0'; + if (!check_remote_access()) + return buffer; + bye = 1; + sprintf(buffer, "%s", "bye|"); + return buffer; +} + +/*****************************************************************************/ + static char *gethelp(char *params); struct CMDS { const char *name; @@ -382,6 +423,11 @@ struct CMDS { { "hwinfo", gethwinfos }, { "meminfo", getmeminfo }, { "scanlog", getscanlog }, + + /* remote functions */ + { "seturl", remote_seturl }, + { "quit", remote_quit }, + /* keep it the last */ { "help", gethelp }, }; @@ -842,6 +888,11 @@ static void api() for (i = 0; i < CMDMAX; i++) { if (strcmp(buf, cmds[i].name) == 0 && strlen(buf)) { + if (params && strlen(params)) { + // remove possible trailing | + if (params[strlen(params)-1] == '|') + params[strlen(params)-1] = '\0'; + } result = (cmds[i].func)(params); if (wskey) { websocket_handshake(c, result, wskey); @@ -868,9 +919,13 @@ void *api_thread(void *userdata) startup = time(NULL); api(); - tq_freeze(mythr->q); + if (bye) { + // quit command + proper_exit(1); + } + return NULL; } diff --git a/ccminer.cpp b/ccminer.cpp index 306b5cf..dc97d37 100644 --- a/ccminer.cpp +++ b/ccminer.cpp @@ -174,7 +174,7 @@ uint32_t gpus_intensity[MAX_GPUS] = { 0 }; char *rpc_user = NULL; static char *rpc_pass; static char *rpc_userpass = NULL; -static char *rpc_url; +char *rpc_url; static char *short_url = NULL; char *opt_cert; char *opt_proxy; @@ -200,6 +200,7 @@ int opt_statsavg = 30; // strdup on char* to allow a common free() if used static char* opt_syslog_pfx = strdup(PROGRAM_NAME); char *opt_api_allow = strdup("127.0.0.1"); /* 0.0.0.0 for all ips */ +int opt_api_remote = 0; int opt_api_listen = 4068; /* 0 to disable */ #ifdef HAVE_GETOPT_LONG @@ -275,7 +276,8 @@ Options:\n\ -P, --protocol-dump verbose dump of protocol-level activities\n\ --cpu-affinity set process affinity to cpu core(s), mask 0x3 for cores 0 and 1\n\ --cpu-priority set process priority (default: 0 idle, 2 normal to 5 highest)\n\ - -b, --api-bind IP/Port for the miner API (default: 127.0.0.1:4068)\n" + -b, --api-bind IP/Port for the miner API (default: 127.0.0.1:4068)\n\ + --api-remote Allow remote control\n" #ifdef HAVE_SYSLOG_H "\ @@ -306,6 +308,7 @@ static char const short_options[] = static struct option const options[] = { { "algo", 1, NULL, 'a' }, { "api-bind", 1, NULL, 'b' }, + { "api-remote", 0, NULL, 1030 }, #ifndef WIN32 { "background", 0, NULL, 'B' }, #endif @@ -1672,7 +1675,7 @@ static void *stratum_thread(void *userdata) stratum.url = (char*)tq_pop(mythr->q, NULL); if (!stratum.url) goto out; - applog(LOG_BLUE, "Starting Stratum on %s", stratum.url); + applog(LOG_BLUE, "Starting on %s", stratum.url); while (1) { int failures = 0; @@ -1680,7 +1683,13 @@ static void *stratum_thread(void *userdata) if (stratum_need_reset) { stratum_need_reset = false; stratum_disconnect(&stratum); - applog(LOG_DEBUG, "stratum connection reset"); + if (strcmp(stratum.url, rpc_url)) { + free(stratum.url); + stratum.url = strdup(rpc_url); + applog(LOG_BLUE, "Connection changed to %s", short_url); + } else if (!opt_quiet) { + applog(LOG_DEBUG, "Stratum connection reset"); + } } while (!stratum.curl) { @@ -1767,7 +1776,7 @@ static void show_usage_and_exit(int status) proper_exit(status); } -static void parse_arg(int key, char *arg) +void parse_arg(int key, char *arg) { char *p = arg; int v, i; @@ -1806,6 +1815,9 @@ static void parse_arg(int key, char *arg) opt_api_listen = atoi(arg); } break; + case 1030: /* --api-remote */ + opt_api_remote = 1; + break; case 'B': opt_background = true; break; @@ -1944,7 +1956,7 @@ static void parse_arg(int key, char *arg) *p = '\0'; ap = strstr(rpc_url, "://") + 3; sp = strchr(ap, ':'); - if (sp) { + if (sp && sp < p) { free(rpc_userpass); rpc_userpass = strdup(ap); free(rpc_user); @@ -1956,8 +1968,10 @@ static void parse_arg(int key, char *arg) free(rpc_user); rpc_user = strdup(ap); } + // remove user[:pass]@ from rpc_url memmove(ap, p + 1, strlen(p + 1) + 1); - short_url = p + 1; + // host:port only + short_url = ap; } have_stratum = !opt_benchmark && !strncasecmp(rpc_url, "stratum", 7); break; diff --git a/configure.ac b/configure.ac index 569230b..fe99b0c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([ccminer], [1.5.3]) +AC_INIT([ccminer], [1.6-git]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpuminer-config.h b/cpuminer-config.h index 9053804..225d7d5 100644 --- a/cpuminer-config.h +++ b/cpuminer-config.h @@ -159,7 +159,7 @@ #define PACKAGE_NAME "ccminer" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ccminer 1.5.3" +#define PACKAGE_STRING "ccminer 1.6-git" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ccminer" @@ -168,7 +168,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.5.3" +#define PACKAGE_VERSION "1.6-git" /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be @@ -191,7 +191,7 @@ #define USE_XOP 1 /* Version number of package */ -#define VERSION "1.5.3" +#define VERSION "1.6-git" /* Define curl_free() as free() if our version of curl lacks curl_free. */ /* #undef curl_free */ diff --git a/miner.h b/miner.h index 52a21a7..de3e63f 100644 --- a/miner.h +++ b/miner.h @@ -634,6 +634,7 @@ extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime); extern void tq_freeze(struct thread_q *tq); extern void tq_thaw(struct thread_q *tq); +void parse_arg(int key, char *arg); void proper_exit(int reason); size_t time2str(char* buf, time_t timer);