Browse Source

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

pull/874/head
Logan oos Even 3 years ago
committed by GitHub
parent
commit
3b187b4ac8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      doc/ManagementAPI.md
  2. 7
      edge.8
  3. 3
      include/n2n_define.h
  4. 2
      include/n2n_typedefs.h
  5. 11
      src/edge.c
  6. 10
      src/edge_management.c
  7. 9
      src/edge_utils.c
  8. 10
      src/sn_management.c
  9. 10
      src/sn_utils.c
  10. 13
      src/supernode.c
  11. 4
      supernode.1

4
doc/ManagementAPI.md

@ -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

@ -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

3
include/n2n_define.h

@ -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 */

2
include/n2n_typedefs.h

@ -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;

11
src/edge.c

@ -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 }
};

10
src/edge_management.c

@ -325,18 +325,20 @@ 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;
}
/* if we dont have an auth key, we can still read */
if(type==N2N_MGMT_READ) {
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;
}

9
src/edge_utils.c

@ -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;
}

10
src/sn_management.c

@ -309,18 +309,20 @@ 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;
}
/* if we dont have an auth key, we can still read */
if(type==N2N_MGMT_READ) {
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;
}

10
src/sn_utils.c

@ -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 */
}

13
src/supernode.c

@ -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}
};

4
supernode.1

@ -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

Loading…
Cancel
Save