1 From 71b520b3fdbd211fc92f455903a3c218250f44b8 Mon Sep 17 00:00:00 2001
2 From: Alex Wilson <alex.wilson@joyent.com>
3 Date: Fri, 4 Sep 2015 11:04:30 -0700
4 Subject: [PATCH 32/36] Accept LANG and LC_* environment variables from clients
5 by default
6
7 This preserves most of the old SunSSH locale negotiation
8 behaviour (at least the parts that are most commonly used).
9 ---
10 servconf.c | 27 +++++++++++++++++++++++++--
11 session.c | 26 ++++++++++++++++++++++++--
12 sshd_config | 4 ++++
13 sshd_config.4 | 13 ++++++++++++-
14 4 files changed, 65 insertions(+), 5 deletions(-)
15
16 diff --git a/servconf.c b/servconf.c
17 index f8122aa..245f2fd 100644
18 --- a/servconf.c
19 +++ b/servconf.c
20 @@ -155,7 +155,7 @@ initialize_server_options(ServerOptions *options)
21 options->client_alive_interval = -1;
22 options->client_alive_count_max = -1;
23 options->num_authkeys_files = 0;
24 - options->num_accept_env = 0;
25 + options->num_accept_env = -1;
26 options->permit_tun = -1;
27 options->num_permitted_opens = -1;
28 options->adm_forced_command = NULL;
29 @@ -411,6 +411,25 @@ fill_default_server_options(ServerOptions *options)
30 options->max_sessions = DEFAULT_SESSIONS_MAX;
31 if (options->use_dns == -1)
32 options->use_dns = 0;
33 + if (options->num_accept_env == -1) {
34 + options->num_accept_env = 0;
35 + options->accept_env[options->num_accept_env++] =
36 + xstrdup("LANG");
37 + options->accept_env[options->num_accept_env++] =
38 + xstrdup("LC_ALL");
39 + options->accept_env[options->num_accept_env++] =
40 + xstrdup("LC_CTYPE");
41 + options->accept_env[options->num_accept_env++] =
42 + xstrdup("LC_COLLATE");
43 + options->accept_env[options->num_accept_env++] =
44 + xstrdup("LC_TIME");
45 + options->accept_env[options->num_accept_env++] =
46 + xstrdup("LC_NUMERIC");
47 + options->accept_env[options->num_accept_env++] =
48 + xstrdup("LC_MONETARY");
49 + options->accept_env[options->num_accept_env++] =
50 + xstrdup("LC_MESSAGES");
51 + }
52 if (options->client_alive_interval == -1)
53 options->client_alive_interval = 0;
54 if (options->client_alive_count_max == -1)
55 @@ -1770,11 +1789,15 @@ process_server_config_line(ServerOptions *options, char *line,
56 if (strchr(arg, '=') != NULL)
57 fatal("%s line %d: Invalid environment name.",
58 filename, linenum);
59 + if (options->num_accept_env == -1)
60 + options->num_accept_env = 0;
61 if (options->num_accept_env >= MAX_ACCEPT_ENV)
62 fatal("%s line %d: too many allow env.",
63 filename, linenum);
64 if (!*activep)
65 continue;
66 + if (strcmp(arg, "none") == 0)
67 + continue;
68 options->accept_env[options->num_accept_env++] =
69 xstrdup(arg);
70 }
71 @@ -2216,7 +2239,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
72 } \
73 } while(0)
74 #define M_CP_STRARRAYOPT(n, num_n) do {\
75 - if (src->num_n != 0) { \
76 + if (src->num_n != 0 && src->num_n != -1) { \
77 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
78 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
79 } \
80 diff --git a/session.c b/session.c
81 index ab0ac1c..88cd9f0 100644
82 --- a/session.c
83 +++ b/session.c
84 @@ -1019,6 +1019,18 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
85 }
86
87 /*
88 + * If the given environment variable is set in the daemon's environment,
89 + * push it into the new child as well. If it is unset, do nothing.
90 + */
91 +static void
92 +child_inherit_env(char ***envp, u_int *envsizep, const char *name)
93 +{
94 + char *value;
95 + if ((value = getenv(name)) != NULL)
96 + child_set_env(envp, envsizep, name, value);
97 +}
98 +
99 +/*
100 * Reads environment variables from the given file and adds/overrides them
101 * into the environment. If the file does not exist, this does nothing.
102 * Otherwise, it must consist of empty lines, comments (line starts with '#')
103 @@ -1180,6 +1192,16 @@ do_setup_env(Session *s, const char *shell)
104 ssh_gssapi_do_child(&env, &envsize);
105 #endif
106
107 + /* Default to the system-wide locale/language settings. */
108 + child_inherit_env(&env, &envsize, "LANG");
109 + child_inherit_env(&env, &envsize, "LC_ALL");
110 + child_inherit_env(&env, &envsize, "LC_CTYPE");
111 + child_inherit_env(&env, &envsize, "LC_COLLATE");
112 + child_inherit_env(&env, &envsize, "LC_TIME");
113 + child_inherit_env(&env, &envsize, "LC_NUMERIC");
114 + child_inherit_env(&env, &envsize, "LC_MONETARY");
115 + child_inherit_env(&env, &envsize, "LC_MESSAGES");
116 +
117 if (!options.use_login) {
118 /* Set basic environment. */
119 for (i = 0; i < s->num_env; i++)
120 @@ -1224,8 +1246,8 @@ do_setup_env(Session *s, const char *shell)
121 /* Normal systems set SHELL by default. */
122 child_set_env(&env, &envsize, "SHELL", shell);
123 }
124 - if (getenv("TZ"))
125 - child_set_env(&env, &envsize, "TZ", getenv("TZ"));
126 +
127 + child_inherit_env(&env, &envsize, "TZ");
128
129 #ifdef PER_SESSION_XAUTHFILE
130 if (s->auth_file != NULL)
131 diff --git a/sshd_config b/sshd_config
132 index 0048f98..bbdc6ae 100644
133 --- a/sshd_config
134 +++ b/sshd_config
135 @@ -38,6 +38,10 @@ HostKey /var/ssh/ssh_host_ed25519_key
136 SyslogFacility AUTH
137 LogLevel INFO
138
139 +# Use the client's locale/language settings
140 +#AcceptEnv LANG LC_ALL LC_CTYPE LC_COLLATE LC_TIME LC_NUMERIC
141 +#AcceptEnv LC_MONETARY LC_MESSAGES
142 +
143 # Authentication:
144
145 #LoginGraceTime 2m
146 diff --git a/sshd_config.4 b/sshd_config.4
147 index cce3a5a..913f528 100644
148 --- a/sshd_config.4
149 +++ b/sshd_config.4
150 @@ -86,7 +86,18 @@ directives.
151 Be warned that some environment variables could be used to bypass restricted
152 user environments.
153 For this reason, care should be taken in the use of this directive.
154 -The default is not to accept any environment variables.
155 +The default is to accept only
156 +.Ev LANG
157 +and the
158 +.Ev LC_*
159 +family of environment variables. If any
160 +.Cm AcceptEnv
161 +directives are present in your config file, they will replace this default
162 +(ie, only the variables you list will be passed into the session's
163 +.Xr environ 7
164 +). You can also use an argument of
165 +.Dq none
166 +to specify that no environment variables should be passed.
167 .It Cm AddressFamily
168 Specifies which address family should be used by
169 .Xr sshd 1M .
170 --
171 2.5.4 (Apple Git-61)
172