Add new log_passwords and passprompt_regex settings.
When logging terminal input, if log_passwords is false and any of the regular expressions in the passprompt_regex list are found in the terminal output, terminal input will be replaced with '*' characters until a newline or carriage return is found in the input or an output character is received.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "January 19, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "January 27, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -268,7 +268,7 @@ The default value is
|
||||
.TP 10n
|
||||
tls_verify = bool
|
||||
If true,
|
||||
\fBsudo_logsrvd.conf\fR
|
||||
\fBsudo_logsrvd\fR
|
||||
will validate its own certificate at startup time or when the
|
||||
configuration is changed.
|
||||
If false, no verification is performed of the server certificate.
|
||||
@@ -590,6 +590,35 @@ is set, it will be used instead of the user's primary group-ID.
|
||||
By default, I/O log files and directories are created with user and
|
||||
group-ID 0.
|
||||
.TP 10n
|
||||
log_passwords = bool
|
||||
Most programs that require a user's password will disable echo before
|
||||
reading the password to avoid displaying the plaintext password on
|
||||
the screen.
|
||||
However, if terminal input is being logged,
|
||||
the password will still be present in the I/O log.
|
||||
If
|
||||
\fIlog_passwords\fR
|
||||
is set to
|
||||
\fRfalse\fR,
|
||||
\fBsudo_logsrvd\fR
|
||||
will attempt to prevent passwords from being logged.
|
||||
It does this by using the regular expressions in
|
||||
\fIpassprompt_regex\fR
|
||||
to match a password prompt in the terminal output buffer.
|
||||
When a match is found, input characters in the I/O log will be replaced with
|
||||
\(oq*\(cq
|
||||
until either a line feed or carriage return is found in the terminal input
|
||||
or a new terminal output buffer is received.
|
||||
If, however, a program displays characters as the user types them
|
||||
(such as
|
||||
\fBsudo\fR
|
||||
when the
|
||||
\fIpwfeedback\fR
|
||||
option is set), only the
|
||||
first character of the password will be replaced in the I/O log.
|
||||
The default value is
|
||||
\fRtrue\fR.
|
||||
.TP 10n
|
||||
maxseq = number
|
||||
The maximum sequence number that will be substituted for the
|
||||
\(lq\fR%{seq}\fR\(rq
|
||||
@@ -606,6 +635,17 @@ base 36 sequence number
|
||||
\(lqZZZZZZ\(rq)
|
||||
will be silently truncated to 2176782336.
|
||||
The default value is 2176782336.
|
||||
.TP 10n
|
||||
passprompt_regex = string
|
||||
One or more POSIX extended regular expressions used to
|
||||
match password prompts in the terminal output when
|
||||
\fIlog_passwords\fR
|
||||
is disabled.
|
||||
Multiple
|
||||
\fIpassprompt_regex\fR
|
||||
settings may be specified.
|
||||
The default value is
|
||||
\(lq[Pp]assword[: ]*\(rq.
|
||||
.SS "eventlog"
|
||||
The
|
||||
\fIeventlog\fR
|
||||
@@ -948,6 +988,10 @@ Sudo log server configuration file
|
||||
# specified by iolog_mode.
|
||||
#iolog_mode = 0600
|
||||
|
||||
# If disabled, sudo_logsrvd will attempt to avoid logging plaintext
|
||||
# password in the terminal input using passprompt_regex.
|
||||
#log_passwords = true
|
||||
|
||||
# The maximum sequence number that will be substituted for the "%{seq}"
|
||||
# escape in the I/O log file. While the value substituted for "%{seq}"
|
||||
# is in base 36, maxseq itself should be expressed in decimal. Values
|
||||
@@ -955,6 +999,12 @@ Sudo log server configuration file
|
||||
# number "ZZZZZZ") will be silently truncated to 2176782336.
|
||||
#maxseq = 2176782336
|
||||
|
||||
# One or more POSIX extended regular expressions used to match
|
||||
# password prompts in the terminal output when log_passwords is
|
||||
# disabled. Multiple passprompt_regex settings may be specified.
|
||||
#passprompt_regex = [Pp]assword[: ]*
|
||||
#passprompt_regex = [Pp]assword for [a-z0-9]+: *
|
||||
|
||||
[eventlog]
|
||||
# Where to log accept, reject, exit, and alert events.
|
||||
# Accepted values are syslog, logfile, or none.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 19, 2022
|
||||
.Dd January 27, 2022
|
||||
.Dt SUDO_LOGSRVD.CONF @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -229,7 +229,7 @@ The default value is
|
||||
.Pa /etc/ssl/sudo/private/logsrvd_key.pem .
|
||||
.It tls_verify = bool
|
||||
If true,
|
||||
.Nm
|
||||
.Nm sudo_logsrvd
|
||||
will validate its own certificate at startup time or when the
|
||||
configuration is changed.
|
||||
If false, no verification is performed of the server certificate.
|
||||
@@ -522,6 +522,34 @@ If
|
||||
is set, it will be used instead of the user's primary group-ID.
|
||||
By default, I/O log files and directories are created with user and
|
||||
group-ID 0.
|
||||
.It log_passwords = bool
|
||||
Most programs that require a user's password will disable echo before
|
||||
reading the password to avoid displaying the plaintext password on
|
||||
the screen.
|
||||
However, if terminal input is being logged,
|
||||
the password will still be present in the I/O log.
|
||||
If
|
||||
.Em log_passwords
|
||||
is set to
|
||||
.Li false ,
|
||||
.Nm sudo_logsrvd
|
||||
will attempt to prevent passwords from being logged.
|
||||
It does this by using the regular expressions in
|
||||
.Em passprompt_regex
|
||||
to match a password prompt in the terminal output buffer.
|
||||
When a match is found, input characters in the I/O log will be replaced with
|
||||
.Ql *
|
||||
until either a line feed or carriage return is found in the terminal input
|
||||
or a new terminal output buffer is received.
|
||||
If, however, a program displays characters as the user types them
|
||||
(such as
|
||||
.Nm sudo
|
||||
when the
|
||||
.Em pwfeedback
|
||||
option is set), only the
|
||||
first character of the password will be replaced in the I/O log.
|
||||
The default value is
|
||||
.Li true .
|
||||
.It maxseq = number
|
||||
The maximum sequence number that will be substituted for the
|
||||
.Dq Li %{seq}
|
||||
@@ -538,6 +566,16 @@ base 36 sequence number
|
||||
.Dq ZZZZZZ )
|
||||
will be silently truncated to 2176782336.
|
||||
The default value is 2176782336.
|
||||
.It passprompt_regex = string
|
||||
One or more POSIX extended regular expressions used to
|
||||
match password prompts in the terminal output when
|
||||
.Em log_passwords
|
||||
is disabled.
|
||||
Multiple
|
||||
.Em passprompt_regex
|
||||
settings may be specified.
|
||||
The default value is
|
||||
.Dq [Pp]assword[: ]* .
|
||||
.El
|
||||
.Ss eventlog
|
||||
The
|
||||
@@ -876,6 +914,10 @@ Sudo log server configuration file
|
||||
# specified by iolog_mode.
|
||||
#iolog_mode = 0600
|
||||
|
||||
# If disabled, sudo_logsrvd will attempt to avoid logging plaintext
|
||||
# password in the terminal input using passprompt_regex.
|
||||
#log_passwords = true
|
||||
|
||||
# The maximum sequence number that will be substituted for the "%{seq}"
|
||||
# escape in the I/O log file. While the value substituted for "%{seq}"
|
||||
# is in base 36, maxseq itself should be expressed in decimal. Values
|
||||
@@ -883,6 +925,12 @@ Sudo log server configuration file
|
||||
# number "ZZZZZZ") will be silently truncated to 2176782336.
|
||||
#maxseq = 2176782336
|
||||
|
||||
# One or more POSIX extended regular expressions used to match
|
||||
# password prompts in the terminal output when log_passwords is
|
||||
# disabled. Multiple passprompt_regex settings may be specified.
|
||||
#passprompt_regex = [Pp]assword[: ]*
|
||||
#passprompt_regex = [Pp]assword for [a-z0-9]+: *
|
||||
|
||||
[eventlog]
|
||||
# Where to log accept, reject, exit, and alert events.
|
||||
# Accepted values are syslog, logfile, or none.
|
||||
|
@@ -179,6 +179,10 @@
|
||||
# specified by iolog_mode.
|
||||
#iolog_mode = 0600
|
||||
|
||||
# If disabled, sudo_logsrvd will attempt to avoid logging plaintext
|
||||
# password in the terminal input using passprompt_regex.
|
||||
#log_passwords = true
|
||||
|
||||
# The maximum sequence number that will be substituted for the "%{seq}"
|
||||
# escape in the I/O log file. While the value substituted for "%{seq}"
|
||||
# is in base 36, maxseq itself should be expressed in decimal. Values
|
||||
@@ -186,6 +190,12 @@
|
||||
# number "ZZZZZZ") will be silently truncated to 2176782336.
|
||||
#maxseq = 2176782336
|
||||
|
||||
# One or more POSIX extended regular expressions used to match
|
||||
# password prompts in the terminal output when log_passwords is
|
||||
# disabled. Multiple passprompt_regex settings may be specified.
|
||||
#passprompt_regex = [Pp]assword[: ]*
|
||||
#passprompt_regex = [Pp]assword for [a-z0-9]+: *
|
||||
|
||||
[eventlog]
|
||||
# Where to log accept, reject, exit, and alert events.
|
||||
# Accepted values are syslog, logfile, or none.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2019-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2019-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -208,6 +208,8 @@ struct connection_closure *connection_closure_alloc(int fd, bool tls, bool relay
|
||||
bool logsrvd_conf_read(const char *path);
|
||||
const char *logsrvd_conf_iolog_dir(void);
|
||||
const char *logsrvd_conf_iolog_file(void);
|
||||
bool logsrvd_conf_iolog_log_passwords(void);
|
||||
void *logsrvd_conf_iolog_passprompt_regex(void);
|
||||
struct server_address_list *logsrvd_conf_server_listen_address(void);
|
||||
struct server_address_list *logsrvd_conf_relay_address(void);
|
||||
const char *logsrvd_conf_relay_dir(void);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2019-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2019-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -148,12 +148,14 @@ static struct logsrvd_config {
|
||||
bool compress;
|
||||
bool flush;
|
||||
bool gid_set;
|
||||
bool log_passwords;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
unsigned int maxseq;
|
||||
char *iolog_dir;
|
||||
char *iolog_file;
|
||||
void *passprompt_regex;
|
||||
} iolog;
|
||||
struct logsrvd_config_eventlog {
|
||||
int log_type;
|
||||
@@ -215,6 +217,18 @@ logsrvd_conf_iolog_file(void)
|
||||
return logsrvd_config->iolog.iolog_file;
|
||||
}
|
||||
|
||||
bool
|
||||
logsrvd_conf_iolog_log_passwords(void)
|
||||
{
|
||||
return logsrvd_config->iolog.log_passwords;
|
||||
}
|
||||
|
||||
void *
|
||||
logsrvd_conf_iolog_passprompt_regex(void)
|
||||
{
|
||||
return logsrvd_config->iolog.passprompt_regex;
|
||||
}
|
||||
|
||||
/* server getters */
|
||||
struct server_address_list *
|
||||
logsrvd_conf_server_listen_address(void)
|
||||
@@ -367,6 +381,19 @@ cb_iolog_compress(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_iolog_log_passwords(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
{
|
||||
int val;
|
||||
debug_decl(cb_iolog_log_passwords, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((val = sudo_strtobool(str)) == -1)
|
||||
debug_return_bool(false);
|
||||
|
||||
config->iolog.log_passwords = val;
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_iolog_flush(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
{
|
||||
@@ -449,6 +476,20 @@ cb_iolog_maxseq(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_iolog_passprompt_regex(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
{
|
||||
debug_decl(cb_iolog_passprompt_regex, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (config->iolog.passprompt_regex == NULL) {
|
||||
/* Lazy alloc of the passprompt regex handle. */
|
||||
config->iolog.passprompt_regex = iolog_pwfilt_alloc();
|
||||
if (config->iolog.passprompt_regex == NULL)
|
||||
debug_return_bool(false);
|
||||
}
|
||||
debug_return_bool(iolog_pwfilt_add(config->iolog.passprompt_regex, str));
|
||||
}
|
||||
|
||||
/* Server callbacks */
|
||||
static bool
|
||||
append_address(struct server_address_list *addresses, const char *str,
|
||||
@@ -1069,7 +1110,9 @@ static struct logsrvd_config_entry iolog_conf_entries[] = {
|
||||
{ "iolog_user", cb_iolog_user },
|
||||
{ "iolog_group", cb_iolog_group },
|
||||
{ "iolog_mode", cb_iolog_mode },
|
||||
{ "log_passwords", cb_iolog_log_passwords },
|
||||
{ "maxseq", cb_iolog_maxseq },
|
||||
{ "passprompt_regex", cb_iolog_passprompt_regex },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -1242,7 +1285,7 @@ logsrvd_stub_close_log(int type, FILE *fp)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set eventlog configuration settings from on logsrvd config. */
|
||||
/* Set eventlog configuration settings from logsrvd config. */
|
||||
static void
|
||||
logsrvd_conf_eventlog_setconf(struct logsrvd_config *config)
|
||||
{
|
||||
@@ -1262,6 +1305,22 @@ logsrvd_conf_eventlog_setconf(struct logsrvd_config *config)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/* Set I/O log configuration settings from logsrvd config. */
|
||||
static void
|
||||
logsrvd_conf_iolog_setconf(struct logsrvd_config *config)
|
||||
{
|
||||
debug_decl(logsrvd_conf_iolog_setconf, SUDO_DEBUG_UTIL);
|
||||
|
||||
iolog_set_defaults();
|
||||
iolog_set_compress(config->iolog.compress);
|
||||
iolog_set_flush(config->iolog.flush);
|
||||
iolog_set_owner(config->iolog.uid, config->iolog.gid);
|
||||
iolog_set_mode(config->iolog.mode);
|
||||
iolog_set_maxseq(config->iolog.maxseq);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversation function for use by sudo_warn/sudo_fatal.
|
||||
* Logs to stdout/stderr.
|
||||
@@ -1483,6 +1542,7 @@ logsrvd_conf_free(struct logsrvd_config *config)
|
||||
/* struct logsrvd_config_iolog */
|
||||
free(config->iolog.iolog_dir);
|
||||
free(config->iolog.iolog_file);
|
||||
iolog_pwfilt_free(config->iolog.passprompt_regex);
|
||||
|
||||
/* struct logsrvd_config_logfile */
|
||||
free(config->logfile.path);
|
||||
@@ -1573,6 +1633,7 @@ logsrvd_conf_alloc(void)
|
||||
config->iolog.uid = ROOT_UID;
|
||||
config->iolog.gid = ROOT_GID;
|
||||
config->iolog.gid_set = false;
|
||||
config->iolog.log_passwords = true;
|
||||
|
||||
/* Event log defaults */
|
||||
config->eventlog.log_type = EVLOG_SYSLOG;
|
||||
@@ -1619,6 +1680,12 @@ logsrvd_conf_apply(struct logsrvd_config *config)
|
||||
#endif
|
||||
debug_decl(logsrvd_conf_apply, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* There can be multiple passprompt regular expressions. */
|
||||
if (config->iolog.passprompt_regex == NULL) {
|
||||
if (!cb_iolog_passprompt_regex(config, PASSPROMPT_REGEX, 0))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
/* There can be multiple addresses so we can't set a default earlier. */
|
||||
if (TAILQ_EMPTY(&config->server.addresses.addrs)) {
|
||||
/* Enable plaintext listender. */
|
||||
@@ -1738,15 +1805,12 @@ logsrvd_conf_apply(struct logsrvd_config *config)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set I/O log library settings */
|
||||
iolog_set_defaults();
|
||||
iolog_set_compress(config->iolog.compress);
|
||||
iolog_set_flush(config->iolog.flush);
|
||||
iolog_set_owner(config->iolog.uid, config->iolog.gid);
|
||||
iolog_set_mode(config->iolog.mode);
|
||||
iolog_set_maxseq(config->iolog.maxseq);
|
||||
|
||||
/* Set event log config */
|
||||
/*
|
||||
* Update event and I/O log library config and install the new
|
||||
* logsrvd config. We must not fail past this point or the event
|
||||
* and I/O log config will be inconsistent with the logsrvd config.
|
||||
*/
|
||||
logsrvd_conf_iolog_setconf(config);
|
||||
logsrvd_conf_eventlog_setconf(config);
|
||||
|
||||
logsrvd_conf_free(logsrvd_config);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2019-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2019-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -523,8 +523,9 @@ store_iobuf_local(int iofd, IoBuffer *iobuf, uint8_t *buf, size_t buflen,
|
||||
struct connection_closure *closure)
|
||||
{
|
||||
const struct eventlog *evlog = closure->evlog;
|
||||
struct ProtobufCBinaryData data = iobuf->data;
|
||||
char tbuf[1024], *newbuf = NULL;
|
||||
const char *errstr;
|
||||
char tbuf[1024];
|
||||
int len;
|
||||
debug_decl(store_iobuf_local, SUDO_DEBUG_UTIL);
|
||||
|
||||
@@ -538,19 +539,27 @@ store_iobuf_local(int iofd, IoBuffer *iobuf, uint8_t *buf, size_t buflen,
|
||||
/* FIXME - assumes IOFD_* matches IO_EVENT_* */
|
||||
len = snprintf(tbuf, sizeof(tbuf), "%d %lld.%09d %zu\n",
|
||||
iofd, (long long)iobuf->delay->tv_sec, (int)iobuf->delay->tv_nsec,
|
||||
iobuf->data.len);
|
||||
data.len);
|
||||
if (len < 0 || len >= ssizeof(tbuf)) {
|
||||
sudo_warnx(U_("unable to format timing buffer, length %d"), len);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!logsrvd_conf_iolog_log_passwords()) {
|
||||
if (!iolog_pwfilt_run(logsrvd_conf_iolog_passprompt_regex(), iofd,
|
||||
(char *)data.data, data.len, &newbuf))
|
||||
goto bad;
|
||||
if (newbuf != NULL)
|
||||
data.data = (uint8_t *)newbuf;
|
||||
}
|
||||
|
||||
/* Write to specified I/O log file. */
|
||||
if (!iolog_write(&closure->iolog_files[iofd], iobuf->data.data,
|
||||
iobuf->data.len, &errstr)) {
|
||||
if (!iolog_write(&closure->iolog_files[iofd], data.data, data.len, &errstr)) {
|
||||
sudo_warnx(U_("%s/%s: %s"), evlog->iolog_path, iolog_fd_to_name(iofd),
|
||||
errstr);
|
||||
goto bad;
|
||||
}
|
||||
free(newbuf);
|
||||
|
||||
/* Write timing data. */
|
||||
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
||||
@@ -574,6 +583,7 @@ store_iobuf_local(int iofd, IoBuffer *iobuf, uint8_t *buf, size_t buflen,
|
||||
|
||||
debug_return_bool(true);
|
||||
bad:
|
||||
free(newbuf);
|
||||
if (closure->errstr == NULL)
|
||||
closure->errstr = _("error writing IoBuffer");
|
||||
debug_return_bool(false);
|
||||
|
Reference in New Issue
Block a user