ssh shell spawn

Abel Romero abeltomillo at gmail.com
Tue Mar 13 05:26:14 EST 2012


Hello,

I'm trying to add a feature to the ssh daemon.
It consists in log all the buffer session between client and server
side into a log file.
I've coded a shell that works with pipes, it opens 2 fds for each std
(you can see code at the end) and so the communication can be
transferred to the client end point, the server side and to the log
file.

My goal is to patch it into ssh, but for that I need to locate where
the ssh dups (with dup2() the 0,1 and 2 fds with the client socket fd
(I guess it does like this, I've no another idea without pipes, but
I've read do_exec() and nothing about pipes, so... how can it be
possible if not like this way?) for the best working of the
application.

Basically I want to know where can I putt the code below.

Thanks in advance.

The code of the mini shell daemon with buffer session log is which
follows (I tried to simulate pty ssh features):

#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>

int
main (void)
{
  int fd_s = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
  struct sockaddr_in info_s = {.sin_family = AF_INET,.sin_port =
      htons (1024),.sin_zero = {0, 0, 0, 0, 0, 0, 0},.sin_addr.s_addr = 0
  };
  bind (fd_s, &info_s, sizeof (info_s));
  listen (fd_s, 1);
  int info_s_len = sizeof (struct sockaddr_in);
  int fd_c;
  struct sockaddr_in info_c;
  while ((fd_c = accept (fd_s, &info_c, &info_s_len)))
    {
      printf ("client connected.\n");
      if (!fork ())
    {
      int fd = open ("log", O_WRONLY | O_CREAT | O_APPEND);
      int pty, tty;
      char *name;
      openpty (&pty, &tty, NULL, NULL, NULL);
      name = ttyname (tty);
      int p0[2], p1[2], p2[2];
      pipe (p0);
      pipe2 (p1, O_NONBLOCK);
      pipe2 (p2, O_NONBLOCK);
      dup2 (tty, 0);
      dup2 (tty, 1);
      dup2 (tty, 2);
      dup2 (p0[0], 0);
      dup2 (p1[1], 1);
      dup2 (p2[1], 2);
      if (!fork ())
        {
          system ("/bin/sh");
          close (p0[0]);
          close (p0[1]);
          close (p1[0]);
          close (p1[1]);
          close (p2[0]);
          close (p2[1]);
          close (fd_c);
          close (fd);
          // some log
          exit (0);
        }
      else
        {
          fd_set rd, wr;
          fcntl (fd_c, F_SETFL, O_NONBLOCK);
          FD_ZERO (&rd);
          FD_ZERO (&wr);
          FD_SET (p1[0], &rd);
          FD_SET (p2[0], &rd);
          FD_SET (fd_c, &rd);
          char *b = 0;
          int bl, i;
          while (select (p2[1] + 1, &rd, &wr, 0, 0))
        {
          char c;
          if (FD_ISSET (fd_c, &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = recv (fd_c, &c, sizeof (c), 0);
              if (ret == sizeof (c))
                {
                  bl += sizeof (char);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == 0)
                {
                  close (fd_c);
                  free (b);
                  exit (0);
                }
              else if (ret == -1)
                {
                  write (p0[1], b, bl);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
            }
            }
          else if (FD_ISSET (p1[0], &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = read (p1[0], &c, sizeof (c));
              if (ret == sizeof (c))
                {
                  bl += sizeof (c);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == -1)
                {
                  send (fd_c, b, bl, 0);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
              else
                {
                }
            }
            }
          else if (FD_ISSET (p2[0], &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = read (p2[0], &c, sizeof (c));
              if (ret == sizeof (c))
                {
                  bl += sizeof (c);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == -1)
                {
                  send (fd_c, b, bl, 0);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
            }
            }
          FD_ZERO (&rd);
          FD_ZERO (&wr);
          FD_SET (p1[0], &rd);
          FD_SET (p2[0], &rd);
          FD_SET (fd_c, &rd);
        }
        }
    }
    }
  return 0;
}


More information about the openssh-unix-dev mailing list