1 From e47c600f563b6acdcfc5c5fb5751d85335f2225a 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] Accept LANG and LC_* environment variables from clients by
   5  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;
 
 
  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 5a64715..57f179d 100644
  82 --- a/session.c
  83 +++ b/session.c
  84 @@ -1010,6 +1010,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 @@ -1171,6 +1183,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 @@ -1215,8 +1237,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         /* Set custom environment options from RSA authentication. */
 130         if (!options.use_login) {
 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.3.2 (Apple Git-55)
 172 
 | 
   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;
 
 
  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 
 |