updated JSON API password handling '--management-password <pw>' (#869)

This commit is contained in:
Logan oos Even 2021-10-24 15:22:36 +05:45 committed by GitHub
parent 7bace3755c
commit 3b187b4ac8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 27 deletions

View File

@ -183,4 +183,6 @@ affect the availability of the n2n networking. Therefore the machine
readable API include an authentication component.
Currently, the only authentication is a simple password that the client
must provide.
must provide. It defaults to 'n2n' and can manually be set through the
command line parameter `--management-password <pw>` for edge as well
as for supernode.

7
edge.8
View File

@ -102,7 +102,7 @@ use header encryption, supernode needs fixed community
\fB\-z1\fR ... \fB\-z2\fR
compress outgoing data packets, -z1 = lzo1x, disabled by default
.TP
\fB\--select-rtt\fR
\fB\-\-select-rtt\fR
select supernode by round trip time if several to choose from (federation),
defaults to load-based selection strategy if not provided.
.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION
@ -186,6 +186,11 @@ binds the edge management system to the given UDP port. Default 5644. Use this
if you need to run multiple instance of edge; or something is bound to that
port.
.TP
\fB\-\-management-password \fR<\fIpassword\fR>
sets the password for access to JSON API at the management port, defaults to 'n2n'. The password
has to be provided when using 'scripts/n2n-ctl', 'scripts/n2n-httpd' or for any other relevant
access to JSON API at the management port.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
make more verbose, repeat as required
.TP

View File

@ -126,6 +126,9 @@ enum n2n_mgmt_type {
N2N_MGMT_WRITE = 1,
};
#define N2N_MGMT_PASSWORD "n2n" /* default password for management port access (so far, json only) */
#define N2N_TCP_BACKLOG_QUEUE_SIZE 3 /* number of concurrently pending connections to be accepted */
/* NOT the number of max. TCP connections */

View File

@ -675,6 +675,7 @@ typedef struct n2n_edge_conf {
int metric; /**< Network interface metric (Windows only). */
uint8_t sn_selection_strategy; /**< encodes currently chosen supernode selection strategy. */
uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */
uint64_t mgmt_password_hash; /**< contains hash of managament port password. */
} n2n_edge_conf_t;
@ -836,6 +837,7 @@ typedef struct n2n_sn {
uint32_t dynamic_key_time; /* UTC time of last dynamic key generation (second accuracy) */
uint8_t override_spoofing_protection; /* set if overriding MAC/IP spoofing protection (cli option '-M') */
n2n_resolve_parameter_t *resolve_parameter;/*Pointer to name resolver's parameter block */
uint64_t mgmt_password_hash;/* contains hash of managament port password */
} n2n_sn_t;

View File

@ -206,6 +206,8 @@ static void help (int level) {
"[-f] "
#endif
"[-t <management port>] "
"[--management-password <pw>] "
"\n "
"[-v] "
"[-n <cidr:gateway>] "
#ifndef WIN32
@ -325,6 +327,8 @@ static void help (int level) {
#endif
printf(" -t <port> | management UDP port, for multiple edges on a machine,\n"
" | defaults to %u\n", N2N_EDGE_MGMT_PORT);
printf(" --management_... | management port password, defaults to '%s'\n"
" ...password <pw> | \n", N2N_MGMT_PASSWORD);
printf(" -v | make more verbose, repeat as required\n");
printf(" -n <cidr:gateway> | route an IPv4 network via the gateway, use 0.0.0.0/0 for\n"
" | the default gateway, can be set multiple times\n");
@ -733,6 +737,12 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
break;
}
case ']': /* password for management port */ {
conf->mgmt_password_hash = pearson_hash_64((uint8_t*)optargument, strlen(optargument));
break;
}
case 'h': /* quick reference */ {
return 2;
}
@ -787,6 +797,7 @@ static const struct option long_options[] =
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, '@' }, /* internal special character '@' to identify long help case */
{ "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */
{ "management-password", required_argument, NULL, ']' }, /* ']' management port password */
{ NULL, 0, NULL, 0 }
};

View File

@ -325,10 +325,11 @@ static void mgmt_help (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in
* Reads are not dangerous, so they are simply allowed
* Writes are possibly dangerous, so they need a fake password
*/
static int mgmt_auth (const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) {
static int mgmt_auth (n2n_edge_t *eee, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) {
if(auth) {
/* If we have an auth key, it must match */
if(0 == strcmp(auth,"CHANGEME")) {
if(eee->conf.mgmt_password_hash == pearson_hash_64((uint8_t*)auth, strlen(auth))) {
return 1;
}
return 0;
@ -337,6 +338,7 @@ static int mgmt_auth (const struct sockaddr_in sender_sock, enum n2n_mgmt_type t
if(type == N2N_MGMT_READ) {
return 1;
}
return 0;
}
@ -414,7 +416,7 @@ void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in se
auth = NULL;
}
if(!mgmt_auth(sender_sock, type, auth, argv0, argv)) {
if(!mgmt_auth(eee, sender_sock, type, auth, argv0, argv)) {
mgmt_error(eee, udp_buf, sender_sock, tag, "badauth");
return;
}

View File

@ -3670,6 +3670,8 @@ static void edge_cleanup_routes (n2n_edge_t *eee) {
void edge_init_conf_defaults (n2n_edge_conf_t *conf) {
char *tmp_string;
memset(conf, 0, sizeof(*conf));
conf->bind_address = INADDR_ANY; /* any address */
@ -3701,6 +3703,13 @@ void edge_init_conf_defaults (n2n_edge_conf_t *conf) {
generate_private_key(*(conf->shared_secret), getenv("N2N_PASSWORD"));
}
tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1);
if(tmp_string) {
strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1);
conf->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen(N2N_MGMT_PASSWORD));
free(tmp_string);
}
conf->sn_selection_strategy = SN_SELECTION_STRATEGY_LOAD;
conf->metric = 0;
}

View File

@ -309,10 +309,11 @@ static void mgmt_help (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in se
* Reads are not dangerous, so they are simply allowed
* Writes are possibly dangerous, so they need a fake password
*/
static int mgmt_auth (const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) {
static int mgmt_auth (n2n_sn_t *sss, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) {
if(auth) {
/* If we have an auth key, it must match */
if(0 == strcmp(auth,"CHANGEME")) {
if(sss->mgmt_password_hash == pearson_hash_64((uint8_t*)auth, strlen(auth))) {
return 1;
}
return 0;
@ -321,6 +322,7 @@ static int mgmt_auth (const struct sockaddr_in sender_sock, enum n2n_mgmt_type t
if(type == N2N_MGMT_READ) {
return 1;
}
return 0;
}
@ -398,7 +400,7 @@ void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in s
auth = NULL;
}
if(!mgmt_auth(sender_sock, type, auth, argv0, argv)) {
if(!mgmt_auth(sss, sender_sock, type, auth, argv0, argv)) {
mgmt_error(sss, udp_buf, sender_sock, tag, "badauth");
return;
}

View File

@ -730,6 +730,9 @@ int comm_init (struct sn_community *comm, char *cmn) {
/** Initialise the supernode structure */
int sn_init_defaults (n2n_sn_t *sss) {
char *tmp_string;
#ifdef WIN32
initWin32();
#endif
@ -786,6 +789,13 @@ int sn_init_defaults (n2n_sn_t *sss) {
sss->mac_addr[0] &= ~0x01; /* Clear multicast bit */
sss->mac_addr[0] |= 0x02; /* Set locally-assigned bit */
tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1);
if(tmp_string) {
strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1);
sss->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen(N2N_MGMT_PASSWORD));
free(tmp_string);
}
return 0; /* OK */
}

View File

@ -80,6 +80,8 @@ static void help (int level) {
"[-f] "
#endif
"[-t <management port>] "
"\n "
"[--management-password <pw>] "
"[-v] "
#ifndef WIN32
"\n "
@ -138,6 +140,8 @@ static void help (int level) {
#endif
printf(" -t <port> | management UDP port, for multiple supernodes on a machine,\n"
" | defaults to %u\n", N2N_SN_MGMT_PORT);
printf(" --management_... | management port password, defaults to '%s'\n"
" ...password <pw> | \n", N2N_MGMT_PASSWORD);
printf(" -v | make more verbose, repeat as required\n");
#ifndef WIN32
printf(" -u <UID> | numeric user ID to use when privileges are dropped\n");
@ -303,6 +307,12 @@ static int setOption (int optkey, char *_optarg, n2n_sn_t *sss) {
if(sss->community_file)
strcpy(sss->community_file, _optarg);
break;
case ']': /* password for management port */ {
sss->mgmt_password_hash = pearson_hash_64((uint8_t*)_optarg, strlen(_optarg));
break;
}
#if defined(N2N_HAVE_DAEMON)
case 'f': /* foreground */
sss->daemon = 0;
@ -337,8 +347,9 @@ static const struct option long_options[] = {
{"local-port", required_argument, NULL, 'p'},
{"mgmt-port", required_argument, NULL, 't'},
{"autoip", required_argument, NULL, 'a'},
{"help", no_argument, NULL, '@'}, /* special character '@' to identify long help case */
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, '@'}, /* special character '@' to identify long help case */
{"management-password", required_argument, NULL, ']' }, /* ']' management port password */
{NULL, 0, NULL, 0}
};

View File

@ -67,6 +67,10 @@ disable daemon mode (UNIX) and run in foreground.
\fB\-t \fR<\fIport\fR>, \fB\-\-mgmt-port\fR=<\fIport\fR>
management UDP port, for multiple supernodes on a machine, defaults to 5645
.TP
\fB\-\-management-password \fR<\fIpassword\fR>
sets the password for access to JSON API at the management port, defaults to 'n2n'. The password
has to be provided for relevant access to JSON API at the management port.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
use verbose logging
.TP