openssh-SNAP-20001207 scp "Bad file descriptor" sort-of work-around

James james at amethyst.nurealm.net
Sun Dec 10 05:17:28 EST 2000


On Fri, 8 Dec 2000, Richard wrote:

>> Ugh!  I'd think bash should read different startup files when invoked by a
>> remote shell daemon and when invoked as a non interactive shell.

> How would you suggest it tell the difference?

As I understand, bash already can tell the difference - that's why BASH(1)
says:

       Bash  attempts  to  determine  when it is being run by the
       remote shell daemon, usually rshd.

That's part of the reason I had a problem with scp to start with.

bash-2.04/shell.c has:
---
/* The name of the .(shell)rc file. */
static char *bashrc_file = "~/.bashrc";
---
/* Execute ~/.bashrc for most shells.  Never execute it if
   ACT_LIKE_SH is set, or if NO_RC is set.

   If the executable file "/usr/gnu/src/bash/foo" contains:

   #!/usr/gnu/bin/bash
   echo hello

   then:

         COMMAND            EXECUTE BASHRC
         --------------------------------
         bash -c foo            NO
         bash foo               NO
         foo                    NO
         rsh machine ls         YES (for rsh, which calls `bash -c')
         rsh machine foo        YES (for shell started by rsh) NO (for foo!)
         echo ls | bash         NO
         login                  NO
         bash                   YES
*/
---
static void
run_startup_files ()
{
#if defined (JOB_CONTROL)
  int old_job_control;
#endif
  int sourced_login, run_by_ssh;

  /* get the rshd/sshd case out of the way first. */
  if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
      act_like_sh == 0 && local_pending_command)
    {
      run_by_ssh = find_variable ("SSH_CLIENT") != (SHELL_VAR *)0;
      run_by_ssh |= find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0;

      /* If we were run by sshd or we think we were run by rshd, execute
         ~/.bashrc if we are a top-level shell. */
      if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
        {
#ifdef SYS_BASHRC
#  if defined (__OPENNT)
          maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
#  else
          maybe_execute_file (SYS_BASHRC, 1);
#  endif
#endif
          maybe_execute_file (bashrc_file, 1);
          return;
        }
    }

I suppose the trick is to simply replace

          maybe_execute_file (bashrc_file, 1);

with something like

          maybe_execute_file ("~/.bash_rsh", 1);


> A non-interactive session is probably one program talking to another, and
> the random text simply screws up whatever protocol they're speaking.  It's
> more reasonable to expect a transparent, unpolluted connection, than to
> expect that every pair of programs you might want to connect together
> using SSH must try to heuristically filter out stuff that "looks like
> unwanted text" from their conversation.

I can see your point.  Still, I'm not suggesting a need for any kind of
heuristic filter.  Rather, I don't see any need for scp, in particular, to
be either the enforcer or the victim of a policy expecting a transparent,
unpolluted connection.  scp is simply not being "robust" here.  There
doesn't seem to be any _need_ to have scp fail crypticly.

Though I think bash needs to distinguish between "rshd" and
"non-interactive" startup files, I also think robust behavior for scp would
be to simply display or trash, depending on the terminal status, any
inconsequential returned text.  (Remember that fierce "suicide squad" at the
end of "Life of Brian"?  scp doesn't _need_ to be a member of the "suicide
squad", does it?)

Again, please Cc me on any response, as I'm not subscribed to the list.

Thanks.


James Feeney






More information about the openssh-unix-dev mailing list