Bug 2643 - Can not ssh with tr_TR.UTF-8 locale (Bad configuration options)
Summary: Can not ssh with tr_TR.UTF-8 locale (Bad configuration options)
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 7.3p1
Hardware: amd64 Linux
: P5 major
Assignee: Damien Miller
URL:
Keywords:
Depends on:
Blocks: V_7_4
  Show dependency treegraph
 
Reported: 2016-11-25 05:11 AEDT by Numan Demirdöðen
Modified: 2018-04-06 12:26 AEST (History)
4 users (show)

See Also:


Attachments
use an ASCII tolower replacement for lowercasing strings (1.95 KB, patch)
2016-12-09 12:46 AEDT, Damien Miller
dtucker: ok-
Details | Diff
use ctype functions instead of roll-ur-own (2.07 KB, patch)
2016-12-09 13:59 AEDT, Damien Miller
no flags Details | Diff
fall back to C locale for LC_CTYPE (2.07 KB, patch)
2016-12-09 15:09 AEDT, Damien Miller
no flags Details | Diff
fall back to C locale for LC_CTYPE (1.09 KB, patch)
2016-12-09 16:28 AEDT, Damien Miller
no flags Details | Diff
Cleaned-up fallback diff (2.99 KB, patch)
2016-12-12 11:20 AEDT, Damien Miller
dtucker: ok+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Numan Demirdöðen 2016-11-25 05:11:24 AEDT
I can not ssh to any host with Turkish locale (tr_TR.UTF-8). I reported this bug to Launchpad[1] and I was asked to report it to upstream[2].

[1] https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1638338
[2] https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1638338/comments/16 

What I expected to happen:

    I expected that 'ssh user@some_host' command would successfully run.

What actually happened

    'ssh user@some_host' command failed with an error.

Steps to produce:

1. Open a terminal
2. Run LANG=tr_TR.UTF-8 ssh user@some_host

If I run ssh with tr_TR.UTF-8 locale, the first error I get is:

    $HOME/.ssh/config: line 7: Bad configuration option: Identityfile
    $HOME/.ssh/config: terminating, 1 bad configuration options

If I commend out IdentityFile option from $HOME/.ssh/config file and re-run the command, I get this:

    debug1: Reading configuration data ~/.ssh/config
    debug1: Reading configuration data /etc/ssh/ssh_config
    debug1: /etc/ssh/ssh_config line 19: Applying options for *
    /etc/ssh/ssh_config: line 55: Bad configuration option: gssapIauthentication
    /etc/ssh/ssh_config: line 56: Bad configuration option: gssapIdelegatecredentials
    /etc/ssh/ssh_config: terminating, 2 bad configuration options

If I commend aut GSSAPIAuthentication and GSSAPIDelegateCredentials options, I can ssh to a host.

So to ssh to a host with tr_TR.UTF-8 locale, one must commend out IdentityFile, if it is used, GSSAPIAuthentication and GSSAPIDelegateCredentials optons.

Workaround:

    LC_ALL=C ssh some_host
Comment 1 Damien Miller 2016-11-25 11:21:33 AEDT
This is the infamous Turkish dotless i confusion and will break stuff wherever we naively tolower a compare a string and compare it.

We lowercase strings in:

auth.c
match.c
misc.c
misc.h
pkcs11.h
readconf.c
ssh.c
sshconnect.c

Given that this is a behaviour change, I propose that we replace the handful of calls with tolower() with one that uses the C locale always. This best matches what openssh <7.3 did.
Comment 2 Damien Miller 2016-12-09 12:46:59 AEDT
Created attachment 2908 [details]
use an ASCII tolower replacement for lowercasing strings
Comment 3 Darren Tucker 2016-12-09 13:27:05 AEDT
Comment on attachment 2908 [details]
use an ASCII tolower replacement for lowercasing strings

>+int
>+tolowerc(int c)
>+{
>+	if (c < (int)'A' || c > (int)'Z')

That's wrong for EBCDIC systems since the alphabet is not contiguous.

>+		return c;
>+	return c - ((int)'A' - (int)'a');
>+}

Does the C standard guarantee that the offset between upper and lowercase characters is constant?  It is in ASCII and EBCDIC.  What else is out there?
Comment 4 Damien Miller 2016-12-09 13:59:13 AEDT
Created attachment 2910 [details]
use ctype functions instead of roll-ur-own
Comment 5 Damien Miller 2016-12-09 14:37:44 AEDT
Comment on attachment 2910 [details]
use ctype functions instead of roll-ur-own

Not sure I want to go with the approach
Comment 6 Damien Miller 2016-12-09 15:09:24 AEDT
Created attachment 2911 [details]
fall back to C locale for LC_CTYPE

I think this is less terrible - it falls back to the C locale for tr* locales, and tries to preserve UTF-8 if the system supports C.UTF-8
Comment 7 Damien Miller 2016-12-09 16:28:55 AEDT
Created attachment 2912 [details]
fall back to C locale for LC_CTYPE

Helps if I attach the correct diff...
Comment 8 Numan Demirdöðen 2016-12-10 04:23:26 AEDT
Thank you for your work Damien Miller.

Do I have to compile ssh with the last patch you wrote in order to test whether patched ssh fixes the bug or not?
Comment 9 Colin Watson 2016-12-10 04:34:27 AEDT
Wow, that's really pretty ugly, and I'm not certain that Turkish is the only locale with this problem.

How about a simple char[256] table lookup instead?  That shouldn't be too ugly (still less code than the complicated setlocale fiddling) and it ought to deal with EBCDIC.
Comment 10 Damien Miller 2016-12-12 10:10:03 AEDT
(In reply to Numan Demirdöðen from comment #8)

> Do I have to compile ssh with the last patch you wrote in order to
> test whether patched ssh fixes the bug or not?

Yes, you'd need to recompile. I've already reproduced and tested the C locale fix though.

(In reply to Colin Watson from comment #9)
> Wow, that's really pretty ugly, and I'm not certain that Turkish is
> the only locale with this problem.
> 
> How about a simple char[256] table lookup instead?  That shouldn't
> be too ugly (still less code than the complicated setlocale
> fiddling) and it ought to deal with EBCDIC.

I think falling back to C locale is preferable. It matches the behaviour for OpenSSH <7.3 best while giving us a chance at preserving UTF-8 output. I'll tidy up that patch - there are a couple of minor problems with it.
Comment 11 Damien Miller 2016-12-12 11:20:30 AEDT
Created attachment 2913 [details]
Cleaned-up fallback diff

Previous fallback diff with a few fixes:

1) Correct precedence order for environment variables

2) Correctly terminate environment search if we find a non-TR locale

3) Check for a couple more variants of UTF-8 (lowercase and without hyphen)

4) Also try POSIX.UTF-8 locale if C.UTF-8 doesn't exist.

5) Stick the while mess in utf8.c where it better belongs. I preferred this rather than doing a xsetlocale, because I expect we'll upstream something like the final version in future.

6) Add a longwinded XXX comment describing how to fix this better in the future :)

Thanks to Ingo Schwarze for valuable feedback.
Comment 12 Damien Miller 2016-12-12 13:59:24 AEDT
Patch applied - this will be in openssh-7.4
Comment 13 Damien Miller 2018-04-06 12:26:54 AEST
Close all resolved bugs after release of OpenSSH 7.7.