Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/datum_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
.required = false, .ptr = &datum_config.stratum_v1_idle_timeout_no_share, .default_int = 7200 },
{ .var_type = DATUM_CONF_INT, .category = "stratum", .name = "idle_timeout_max_last_work", .description = "Seconds we allow a subscribed connection to be idle since its last accepted share? (0 disables)",
.required = false, .ptr = &datum_config.stratum_v1_idle_timeout_max_last_work, .default_int = 0 },
{ .var_type = DATUM_CONF_USERNAME_MODS, .category = "stratum", .name = "username_modifiers", .description = "Modifiers to redirect some portion of shares to alternate usernames", .required = false, .ptr = &datum_config.stratum_username_mod, },
{ .var_type = DATUM_CONF_STRING, .category = "stratum", .name = "password", .description = "Authentication password (disabled if blank)",
.required = false, .ptr = datum_config.stratum_v1_password, .default_string[0] = "", .max_string_len = sizeof(datum_config.stratum_v1_password) },
{ .var_type = DATUM_CONF_USERNAME_MODS, .category = "stratum", .name = "username_modifiers", .description = "Modifiers to redirect some portion of shares to alternate usernames",
.required = false, .ptr = &datum_config.stratum_username_mod, },

// mining settings
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "pool_address", .description = "Bitcoin address used for mining rewards.",
Expand Down Expand Up @@ -588,6 +591,8 @@ int datum_read_config(const char *conffile) {
return 0;
}

datum_config.stratum_v1_password_len = strlen(datum_config.stratum_v1_password);

if (datum_config.datum_protocol_global_timeout < (datum_config.bitcoind_work_update_seconds+5)) {
DLOG_FATAL("DATUM protocol global timeout must be at least the work update interval plus 5 seconds.");
return 0;
Expand Down
2 changes: 2 additions & 0 deletions src/datum_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ typedef struct {
int stratum_v1_idle_timeout_no_subscribe;
int stratum_v1_idle_timeout_no_share;
int stratum_v1_idle_timeout_max_last_work;
char stratum_v1_password[72];
size_t stratum_v1_password_len;

void *stratum_username_mod;

Expand Down
41 changes: 32 additions & 9 deletions src/datum_stratum.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,27 +1444,39 @@ int client_mining_configure(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_
int client_mining_authorize(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj) {
char s[256];
const char *username_s;
const char *password_s;
json_t *username;
json_t *password;

T_DATUM_MINER_DATA * const m = c->app_client_data;

username = json_array_get(params_obj, 0);
if (!username) {
username_s = json_string_value(username);
if (!username_s) {
username_s = (const char *)"NULL";
} else {
username_s = json_string_value(username);
if (!username_s) {
username_s = (const char *)"NULL";
}
}

strncpy(m->last_auth_username, username_s, sizeof(m->last_auth_username) - 1);
m->last_auth_username[sizeof(m->last_auth_username)-1] = 0;

snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id);
datum_socket_send_string_to_client(c, s);
password = json_array_get(params_obj, 1);
password_s = json_string_value(password);
if (!password_s) {
password_s = (const char *)"x";
}

m->authorized = true;
if (datum_config.stratum_v1_password_len > 0 && !datum_secure_strequals(datum_config.stratum_v1_password, datum_config.stratum_v1_password_len, password_s)) {
DLOG_DEBUG("Kicking client %d/%d (%s) due to unsuccessful authentication attempt", c->datum_thread->thread_id, c->cid, c->rem_host);
snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":false}\n", id);
c->datum_thread->has_client_kill_request = true;
c->kill_request = true;
m->authorized = false;
} else {
snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id);
m->authorized = true;
}

datum_socket_send_string_to_client(c, s);

return 0;
}
Expand All @@ -1485,6 +1497,17 @@ int send_mining_notify(T_DATUM_CLIENT_DATA *c, bool clean, bool quickdiff, bool
if (!j) {
return -1;
}

// do not send jobs to unauthorized clients
if (!m->authorized) {
// give unauthorized clients a bit of grace period to get authorization
usleep(1000000);
if (!m->authorized) {
c->kill_request = true;
c->datum_thread->has_client_kill_request = true;
return 0;
}
}

//job_id - ID of the job. Use this ID while submitting share generated from this job.
//prevhash - Hash of previous block.
Expand Down