lightningd/jsonrpc.c: Set JSON-RPC socket permissions by command line.

Changelog-Added: Can now set the permissions on the JSON-RPC socket by `--rpc-file-mode`.
This commit is contained in:
ZmnSCPxj jxPCSnmZ
2020-01-24 10:20:45 +08:00
committed by Christian Decker
parent f619124cb9
commit 7f4ed54b46
6 changed files with 66 additions and 4 deletions

View File

@@ -188,6 +188,14 @@ cause it to reopen this file (useful for log rotation)\.
Set JSON-RPC socket (or /dev/tty), such as for \fBlightning-cli\fR(1)\. Set JSON-RPC socket (or /dev/tty), such as for \fBlightning-cli\fR(1)\.
\fBrpc-file-mode\fR=\fIMODE\fR
Set JSON-RPC socket file mode, as a 4-digit octal number\.
Default is 0600, meaning only the user that launched lightningd
can command it\.
Set to 0660 to allow users with the same group to access the RPC
as well\.
\fBdaemon\fR \fBdaemon\fR
Run in the background, suppress stdout and stderr\. Run in the background, suppress stdout and stderr\.

View File

@@ -149,6 +149,13 @@ cause it to reopen this file (useful for log rotation).
**rpc-file**=*PATH* **rpc-file**=*PATH*
Set JSON-RPC socket (or /dev/tty), such as for lightning-cli(1). Set JSON-RPC socket (or /dev/tty), such as for lightning-cli(1).
**rpc-file-mode**=*MODE*
Set JSON-RPC socket file mode, as a 4-digit octal number.
Default is 0600, meaning only the user that launched lightningd
can command it.
Set to 0660 to allow users with the same group to access the RPC
as well.
**daemon** **daemon**
Run in the background, suppress stdout and stderr. Run in the background, suppress stdout and stderr.

View File

@@ -1074,7 +1074,7 @@ bool command_check_only(const struct command *cmd)
void jsonrpc_listen(struct jsonrpc *jsonrpc, struct lightningd *ld) void jsonrpc_listen(struct jsonrpc *jsonrpc, struct lightningd *ld)
{ {
struct sockaddr_un addr; struct sockaddr_un addr;
int fd, old_umask; int fd, old_umask, new_umask;
const char *rpc_filename = ld->rpc_filename; const char *rpc_filename = ld->rpc_filename;
/* Should not initialize it twice. */ /* Should not initialize it twice. */
@@ -1103,8 +1103,9 @@ void jsonrpc_listen(struct jsonrpc *jsonrpc, struct lightningd *ld)
errx(1, "rpc filename '%s' in use", rpc_filename); errx(1, "rpc filename '%s' in use", rpc_filename);
unlink(rpc_filename); unlink(rpc_filename);
/* This file is only rw by us! */ /* Set the umask according to the desired file mode. */
old_umask = umask(0177); new_umask = ld->rpc_filemode ^ 0777;
old_umask = umask(new_umask);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
err(1, "Binding rpc socket to '%s'", rpc_filename); err(1, "Binding rpc socket to '%s'", rpc_filename);
umask(old_umask); umask(old_umask);

View File

@@ -78,7 +78,6 @@
#include <signal.h> #include <signal.h>
#include <sodium.h> #include <sodium.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@@ -254,6 +253,16 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->initial_umask = umask(0); ld->initial_umask = umask(0);
umask(ld->initial_umask); umask(ld->initial_umask);
/*~ This is the mode of the created JSON-RPC socket file, in
* traditional Unix octal. 0600 means only the user that ran
* lightningd can invoke RPC on it. Changing it to 0660 may
* be sensible if you run lightningd in its own system user,
* and just let specific users (add the group of the
* lightningd runner as an ancillary group) access its
* RPC. Can be overridden with `--rpc-file-mode`.
*/
ld->rpc_filemode = 0600;
return ld; return ld;
} }

View File

@@ -10,6 +10,7 @@
#include <lightningd/htlc_set.h> #include <lightningd/htlc_set.h>
#include <lightningd/plugin.h> #include <lightningd/plugin.h>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h>
#include <wallet/txfilter.h> #include <wallet/txfilter.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
@@ -91,6 +92,8 @@ struct lightningd {
/* Location of the RPC socket. */ /* Location of the RPC socket. */
char *rpc_filename; char *rpc_filename;
/* Mode of the RPC filename. */
mode_t rpc_filemode;
/* The root of the jsonrpc interface. Can be shut down /* The root of the jsonrpc interface. Can be shut down
* separately from the rest of the daemon to allow a clean * separately from the rest of the daemon to allow a clean

View File

@@ -105,6 +105,30 @@ static char *opt_set_s32(const char *arg, s32 *u)
return NULL; return NULL;
} }
static char *opt_set_mode(const char *arg, mode_t *m)
{
char *endp;
long l;
assert(arg != NULL);
/* Ensure length, and starts with 0. */
if (strlen(arg) != 4 || arg[0] != '0')
return tal_fmt(NULL, "'%s' is not a file mode", arg);
/* strtol, manpage, yech. */
errno = 0;
l = strtol(arg, &endp, 8); /* Octal. */
if (errno || *endp)
return tal_fmt(NULL, "'%s' is not a file mode", arg);
*m = l;
/* Range check not needed, previous strlen checks ensures only
* 9-bit, which fits mode_t (unless your Unix is seriously borked).
*/
return NULL;
}
static char *opt_add_addr_withtype(const char *arg, static char *opt_add_addr_withtype(const char *arg,
struct lightningd *ld, struct lightningd *ld,
enum addr_listen_announce ala, enum addr_listen_announce ala,
@@ -225,6 +249,11 @@ static void opt_show_s32(char buf[OPT_SHOW_LEN], const s32 *u)
snprintf(buf, OPT_SHOW_LEN, "%"PRIi32, *u); snprintf(buf, OPT_SHOW_LEN, "%"PRIi32, *u);
} }
static void opt_show_mode(char buf[OPT_SHOW_LEN], const mode_t *m)
{
snprintf(buf, OPT_SHOW_LEN, "\"%04o\"", (int) *m);
}
static char *opt_set_rgb(const char *arg, struct lightningd *ld) static char *opt_set_rgb(const char *arg, struct lightningd *ld)
{ {
assert(arg != NULL); assert(arg != NULL);
@@ -842,6 +871,11 @@ static void register_opts(struct lightningd *ld)
"Set the password to encrypt hsm_secret with. If no password is passed through command line, " "Set the password to encrypt hsm_secret with. If no password is passed through command line, "
"you will be prompted to enter it."); "you will be prompted to enter it.");
opt_register_arg("--rpc-file-mode", &opt_set_mode, &opt_show_mode,
&ld->rpc_filemode,
"Set the file mode (permissions) for the "
"JSON-RPC socket");
opt_register_logging(ld); opt_register_logging(ld);
opt_register_version(); opt_register_version();