Bug 3332 - Multiple SetEnv commands in the config are ignored (only the first one works)
Summary: Multiple SetEnv commands in the config are ignored (only the first one works)
Status: CLOSED WONTFIX
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 8.2p1
Hardware: All All
: P5 minor
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-26 20:26 AEST by Sven Berkvens-Matthijsse
Modified: 2022-02-25 13:57 AEDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Berkvens-Matthijsse 2021-07-26 20:26:29 AEST
Hi,

I tried placing something like this in my configuration:

Host dev6
        # Development LXC 6: Test 6
        Hostname 10.101.110.6
        SetEnv LC_MONETARY=en_US.UTF-8
        SetEnv LC_TELEPHONE=en_US.UTF-8
        SetEnv LC_MEASUREMENT=en_US.UTF-8
        SetEnv LC_NAME=en_US.UTF-8
        SetEnv LC_PAPER=en_US.UTF-8
        SetEnv LC_ADDRESS=en_US.UTF-8
        SetEnv LC_IDENTIFICATION=en_US.UTF-8
        SetEnv LC_NUMERIC=en_US.UTF-8
        SetEnv LC_TIME=en_US.UTF-8
        SetEnv LANG=en_US.UTF-8

This does not work properly. The SetEnv commands are all accepted while reading the configuration file, but only the first one is actually remembered and sent. If I run "ssh -G dev6" to get the configuration, it says:

....
userknownhostsfile ~/.ssh/known_hosts ~/.ssh/known_hosts2
sendenv LANG
sendenv LC_*
setenv LC_MONETARY=en_US.UTF-8
forwardagent yes
....

I think the culprit is a line in readconf.c that I don't understand the purpose of:

        case oSetEnv:
***             value = options->num_setenv;
                while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
                        if (strchr(arg, '=') == NULL)
                                fatal("%s line %d: Invalid SetEnv.",
                                    filename, linenum);
***                     if (!*activep || value != 0)
                                continue;
                        /* Adding a setenv var */
                        if (options->num_setenv >= INT_MAX)
                                fatal("%s line %d: too many SetEnv.",
                                    filename, linenum);
                        options->setenv = xrecallocarray(
                            options->setenv, options->num_setenv,
                            options->num_setenv + 1, sizeof(*options->setenv));
                        options->setenv[options->num_setenv++] = xstrdup(arg);
                }
                break;

The two lines I prefixed with *** look strange to me. The number of already remembered SetEnv items is remembered at the start. Later, in the loop, if there were already entries present at the start of the loop, then every entry that is found in the loop is not stored.

Of course, there is a simple solution for my use case: simply use a single SetEnv command with all the environment variables and their values as arguments. But I think the way I tried to write is should be accepted too. Or, as an alternative, the configuration file reader should warn me about incorrect usage.

Thanks for reading,
Sven
Comment 1 Damien Miller 2021-07-27 07:29:45 AEST
This is intentional - SetEnv behaves like almost all other ssh_config directives (first-match-wins).

Unfortunately, this is inconsistent with SendEnv, because I mistakenly implemented that allowing multiple directives, which leads to other problems (e.g. bug #3247).

You may enter multiple environment variables on a single SetEnv line.
Comment 2 Damien Miller 2022-02-25 13:57:15 AEDT
closing bugs resolved before openssh-8.9