From: Damien Miller Subject: ssh: allow UTF-8 characters in log messages To: tech@openbsd.org Cc: openssh@openssh.com Date: Thu, 13 Aug 2026 11:42:33 +1000 Hi, This allows UTF-8 characters in log messages, either destined to the TTY or to syslog IFF ssh/sshd is started in a UTF-8 locale. It will fall back to strnvis() sanitisation of output strings in other cases. ok? diff --git a/Makefile.inc b/Makefile.inc index a642017..3f15128 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -53,6 +53,7 @@ SRCS_BASE+= sshbuf-getput-basic.c SRCS_BASE+= sshbuf-misc.c SRCS_BASE+= ssherr.c SRCS_BASE+= log.c +SRCS_BASE+= utf8.c SRCS_BASE+= xmalloc.c SRCS_BASE+= misc.c SRCS_BASE+= addr.c diff --git a/log.c b/log.c index 74ecd5b..2fad5e2 100644 --- a/log.c +++ b/log.c @@ -45,10 +45,10 @@ #include #include #include -#include #include "log.h" #include "match.h" +#include "utf8.h" static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 1; @@ -361,12 +361,12 @@ do_log(LogLevel level, int force, const char *suffix, const char *fmt, snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", msgbuf, suffix); strlcpy(msgbuf, fmtbuf, sizeof(msgbuf)); } - strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_SAFE|VIS_OCTAL); + snmprintf(fmtbuf, sizeof(fmtbuf), NULL, "%s", msgbuf); if (log_handler != NULL) { /* Avoid recursion */ tmp_handler = log_handler; log_handler = NULL; - /* Note: this sends the raw (i.e. no strnvis) log message */ + /* Note: this sends a raw (i.e. no sanitisation) log message */ tmp_handler(level, force, msgbuf, log_handler_ctx); log_handler = tmp_handler; } else if (log_on_stderr) { diff --git a/scp/Makefile b/scp/Makefile index 14fa6ac..5809882 100644 --- a/scp/Makefile +++ b/scp/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= scp.c -SRCS+= fatal.c atomicio.c progressmeter.c utf8.c +SRCS+= fatal.c atomicio.c progressmeter.c SRCS+= sftp-common.c sftp-client.c sftp-glob.c SRCS+= ssherr-nolibcrypto.c SRCS+= ${SRCS_BASE} diff --git a/sftp/Makefile b/sftp/Makefile index 129d054..8369f99 100644 --- a/sftp/Makefile +++ b/sftp/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= sftp.c sftp-client.c sftp-common.c sftp-glob.c sftp-usergroup.c -SRCS+= atomicio.c cleanup.c fatal.c progressmeter.c utf8.c +SRCS+= atomicio.c cleanup.c fatal.c progressmeter.c SRCS+= ssherr-nolibcrypto.c SRCS+= ${SRCS_BASE} diff --git a/ssh-add/Makefile b/ssh-add/Makefile index 05dc0b2..367b360 100644 --- a/ssh-add/Makefile +++ b/ssh-add/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= ssh-add.c -SRCS+= authfd.c cleanup.c fatal.c readpass.c utf8.c hostfile.c hmac.c +SRCS+= authfd.c cleanup.c fatal.c readpass.c hostfile.c hmac.c SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL} SRCS+= ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT} diff --git a/ssh-agent/Makefile b/ssh-agent/Makefile index 0fbf493..35e00fd 100644 --- a/ssh-agent/Makefile +++ b/ssh-agent/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= ssh-agent.c ${SRCS_PKCS11_CLIENT} -SRCS+= compat.c fatal.c readpass.c utf8.c misc-agent.c +SRCS+= compat.c fatal.c readpass.c misc-agent.c SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL} SRCS+= ${SRCS_SK_CLIENT} diff --git a/ssh-keygen/Makefile b/ssh-keygen/Makefile index 8c9c924..70e7577 100644 --- a/ssh-keygen/Makefile +++ b/ssh-keygen/Makefile @@ -4,7 +4,7 @@ SRCS= ssh-keygen.c ${SRCS_MODULI} SRCS+= authfd.c cleanup.c dns.c fatal.c hmac.c hostfile.c \ - readpass.c utf8.c sshsig.c + readpass.c sshsig.c SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL} \ ${SRCS_PKCS11} ${SRCS_SK_CLIENT} diff --git a/ssh-keysign/Makefile b/ssh-keysign/Makefile index 8093090..8b8bb62 100644 --- a/ssh-keysign/Makefile +++ b/ssh-keysign/Makefile @@ -4,7 +4,7 @@ SRCS= ssh-keysign.c readconf.c compat.c SRCS+= cleanup.c fatal.c -SRCS+= uidswap.c utf8.c +SRCS+= uidswap.c SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_PKT} \ ${SRCS_UTL} ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT} PROG= ssh-keysign diff --git a/ssh/Makefile b/ssh/Makefile index 8fc7e9d..94c3704 100644 --- a/ssh/Makefile +++ b/ssh/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= ssh.c readconf.c clientloop.c sshtty.c sshconnect.c sshconnect2.c mux.c -SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c +SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXC} ${SRCS_KEY} ${SRCS_KEYP} \ ${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \ ${SRCS_SK_CLIENT} diff --git a/sshd-auth/Makefile b/sshd-auth/Makefile index 4c2381d..34852c8 100644 --- a/sshd-auth/Makefile +++ b/sshd-auth/Makefile @@ -9,7 +9,7 @@ SRCS= sshd-auth.c auth2-methods.c \ auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \ monitor_wrap.c misc-agent.c \ sftp-server.c sftp-common.c sftp-realpath.c -SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c +SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c uidswap.c SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \ ${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \ ${SRCS_SK_CLIENT} diff --git a/sshd-session/Makefile b/sshd-session/Makefile index ba38530..e72ed26 100644 --- a/sshd-session/Makefile +++ b/sshd-session/Makefile @@ -9,7 +9,7 @@ SRCS= sshd-session.c auth2-methods.c \ auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \ monitor.c monitor_wrap.c \ sftp-server.c sftp-common.c sftp-realpath.c srclimit.c -SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c +SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c uidswap.c SRCS+= misc-agent.c SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \ ${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \ diff --git a/sshd/Makefile b/sshd/Makefile index 9049a2f..51bb141 100644 --- a/sshd/Makefile +++ b/sshd/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. SRCS= sshd.c servconf.c sshpty.c srclimit.c groupaccess.c auth2-methods.c -SRCS+= dns.c fatal.c compat.c utf8.c authfd.c canohost.c kex-names.c +SRCS+= dns.c fatal.c compat.c authfd.c canohost.c kex-names.c SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} \ ${SRCS_MAC} ${SRCS_UTL} ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT}