[Gllug] SSH client and httpd

Richard Jones rich at annexia.org
Tue Apr 15 11:31:29 UTC 2003


On Mon, Apr 14, 2003 at 10:55:33PM +0100, Adrian McMenamin wrote:
> I would like a very small (when built statically) ssh client and httpd server 
> to run on a Dreamcast - so I can fufil a promise I made a long time ago to 
> run a httpd off the filesystem on the visual memory system on this thing.
> 
> (Actually the ssh client is to allow me to access my other boxes from the 
> Dreamcast rather than anything to do with a webserver)
> 
> Any recommendations? The simpler the better as I am not intending to serve 
> anything beyond a static page or two. Further more something that preserved 
> my mtd by caching the requested pages in memory would be extra welcome.

For the ssh client: OpenZaurus comes with OpenSSH. The client is:

$ ls -l `which ssh`
-rwxr-xr-x    1 root     root       226020 Jan  1  1970 /usr/bin/ssh

I don't know if that's small enough for you.

I have a webserver, rws, which is very small, but unfortunately
it would require some small amount of porting to the Hitachi micro-
processor used in the Dreamcast. http://www.annexia.org/freeware/rws/

Also see below.

Rich.

----------------------------------------------------------------------
/* This is the C version of httpd.pl (the Perl minimal webserver).
 *
 * By Richard W.M. Jones <rich at annexia.org>
 *
 * To compile:
 *
 *   gcc -Wall -Os -s httpd.c -o httpd
 *
 * To install, add the following line to /etc/inetd.conf:
 *
 *   port stream tcp nowait root /usr/sbin/tcpd /path/to/httpd /path/to/content/dir user
 *
 * ``user'' is the user that the webserver changes to on running. I
 * suggest using ``nobody''. The /path/to/content/dir is the top level
 * directory containing files to serve. The webserver chroot's to this
 * directory when it runs.
 *
 * Reasonable steps have been made to ensure that this webserver is
 * secure against denial of service attacks and buffer overflows. It
 * is believed to be secure, however use at your own risk and check the
 * code yourself first. There's not much of it.
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <syslog.h>

int
main (int argc, char *argv[])
{
  const char *web_content_dir, *user;
  char request[8192];
  char data[8192];
  int n, nbytes, i, fd;
  struct stat statbuf;
  struct passwd *pw;

  /* Open a connection to syslogd. */
  openlog ("httpd", LOG_NDELAY|LOG_PID, LOG_DAEMON);

  /* Check arguments. */
  if (argc != 3)
    {
      syslog (LOG_ERR, "usage: httpd /path/to/content/dir user");
      exit (1);
    }

  web_content_dir = argv[1];
  user = argv[2];

  /* Chroot and change user and group ID. */
  if ((pw = getpwnam (user)) == 0)
    {
      syslog (LOG_ERR, "getpwnam: %s: %m", user);
      exit (1);
    }

  initgroups (user, pw->pw_gid);

  if (chdir (web_content_dir) == -1)
    {
      syslog (LOG_ERR, "chdir: %s: %m", web_content_dir);
      exit (1);
    }

  if (chroot (".") == -1)
    {
      syslog (LOG_ERR, "chroot: %m");
      exit (1);
    }

  if (setgid (pw->pw_gid) == -1 ||
      setuid (pw->pw_uid) == -1)
    {
      syslog (LOG_ERR, "setgid or setuid: %m");
      exit (1);
    }

  /* Time out the request after 30 seconds. */
  alarm (30);

  /* Read the request into memory. */
  if ((n = read (0, request, sizeof request)) <= 0)
    {
      syslog (LOG_ERR, "read: %m");
      exit (1);
    }

  /* We're only into HTTP/0.9, so no keepalives or anything. */
  shutdown (0, 0);

  /* Parse the request. */
  if (n < 5 || request[0] != 'G' || request[1] != 'E' ||
      request[2] != 'T' || request[3] != ' ')
    {
      syslog (LOG_ERR, "not a GET method");
      exit (1);
    }

  for (i = 4; i < n; ++i)
    {
      if (request[i] == '\0' || request[i] == ' ' ||
	  request[i] == '\t' || request[i] == '\n' ||
	  request[i] == '\r')
	{
	  request[i] = '\0';
	  break;
	}
    }

  if (i == n)
    {
      syslog (LOG_ERR, "URL too long\n");
      exit (1);
    }

  if (i == 4)
    {
      syslog (LOG_ERR, "no URL in GET request");
      exit (1);
    }

  /* Stat the file. If it's a directory, then append /index.html. */
  if (stat (&request[4], &statbuf) == -1)
    {
      syslog (LOG_ERR, "%s: %m", &request[4]);
      exit (1);
    }

  if (S_ISDIR (statbuf.st_mode))
    {
      /* Check there's enough room to append in-place before we
       * actually append.
       */
      if (i >= sizeof request - 12)
	{
	  syslog (LOG_ERR, "URL too long to append index.html to name");
	  exit (1);
	}

      request[i++] = '/';
      request[i++] = 'i';
      request[i++] = 'n';
      request[i++] = 'd';
      request[i++] = 'e';
      request[i++] = 'x';
      request[i++] = '.';
      request[i++] = 'h';
      request[i++] = 't';
      request[i++] = 'm';
      request[i++] = 'l';
      request[i++] = '\0';
    }

  /* Open the file and send it back to the user. */
  fd = open (&request[4], O_RDONLY);
  if (fd == -1)
    {
      syslog (LOG_ERR, "%s: %m", &request[4]);
      exit (1);
    }

  nbytes = 0;
  while ((n = read (fd, data, sizeof data)) > 0)
    {
      /* Time out the write after a further 30 seconds. */
      alarm (30);

      if (write (1, data, n) < n)
	{
	  syslog (LOG_ERR, "write: %m");
	  exit (1);
	}
      nbytes += n;
    }

  if (n == -1)
    {
      syslog (LOG_ERR, "read: %m");
      exit (1);
    }

  if (close (fd) == -1)
    {
      syslog (LOG_ERR, "close: %m");
      exit (1);
    }

  /* Shut down the socket cleanly. */
  if (close (1) == -1)
    {
      syslog (LOG_ERR, "close: %m");
      exit (1);
    }

  /* Log the fact that the connection happened. */
  syslog (LOG_INFO, "\"%s\" %d OK", request, nbytes);

  exit (0);
}
----------------------------------------------------------------------

-- 
Richard Jones, Red Hat Inc. (London) and Merjis Ltd. http://www.merjis.com/
http://www.annexia.org/ Freshmeat projects: http://freshmeat.net/users/rwmj
NET::FTPSERVER is a full-featured, secure, configurable, database-backed
FTP server written in Perl: http://www.annexia.org/freeware/netftpserver/

-- 
Gllug mailing list  -  Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug




More information about the GLLUG mailing list