When I was installing a new server I thought that it would be nice to
have the server display a nice banner when I contact it. With OpenSSH
this is rather easy to achieve. Just setting the Banner
option in
/etc/ssh/sshd_config
should do the trick. I also thought it would be
nice to have the servername displayed, created with
Figlet. So when I login the screen should look
something like this:
_ __ ___ _ _ ___ ___ _ ____ _____ _ __ | '_ ` _ \| | | / __|/ _ \ '__\ \ / / _ \ '__| | | | | | | |_| \__ \ __/ | \ V / __/ | |_| |_| |_|\__, |___/\___|_| \_/ \___|_| |___/
I set this all up and when I logged in the screen looked like:
_ __ ___ _ _ ___ ___ _ ____ _____ _ __ | '_ ` _ \\| | | / __|/ _ \\ '__\\ \\ / / _ \\ '__| | | | | | | |_| \\__ \\ __/ | \\ V / __/ | |_| |_| |_|\\__, |___/\\___|_| \\_/ \\___|_| |___/
I guess you can understand it’s not what I wanted. All backslashes are doubled, hmmm weird.
Poking around in the system (CentOS 5.4) seemed to lead me to the
mingetty
command, because that’s what’s used to login.
In the source code of mingetty
I found:
if ((fd = fopen (ISSUE, "r"))) { while ((c = getc (fd)) != EOF) { if (c == '\\') output_special_char (getc(fd)); else putchar (c); } fflush (stdout); fclose (fd); }
so that could be it.
As a test I put a mingetty
escape sequence in the /etc/issue
file,
but that showed up completely the same, no mingetty
translation. So
that’s not it. Not that many options left. Maybe the OpenSSH server
displaying the backslashes the wrong way.
Tracing the OpenSSH server source code showed that it couldn’t be that
one, because the Banner
file is just sent by an atomic write.
But, if it’s not the server, maybe it’s the client. Another source code
scan of the OpenSSH stuff revealed the culprit. In the file
sshconnect2.c
the function input_userauth_banner
displays the
banner, sent from the server. On line 417 (in my source tree, OpenSSH
version 5.3p1) it says
strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
So unsafe characters and octal characters are encoded. The man
page of strnvis
states:
There is one additional flag, VIS_NOSLASH, which inhibits the doubling of backslashes and the backslash before the default format
So I changed the line to
strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
recompiled SSH and reconnected to my new, shiny server.
Hurray, problem solved.
Checking the Internet I found out that someone already found this bug and checked it in with the OpenSSH developers (about an hour before I tried to check it in). It will be resolved in version 5.4, but it can still take some time to find it’s way into all distributions.