


/*
 * kerberized telnet
 */


#include <stdio.h>
#include <krb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

main(argc, argv)
     int argc;
     char **argv;
{
  char *hostname;
  char *port;
  char *service;
  char *instance;
  char *realm = "ATHENA.MIT.EDU";
  KTEXT_ST ticket;
  struct hostent *hp;
  struct servent *sp;
  struct sockaddr_in saddr;
  int result;
  int s;
  char buf[128];
  int n;
  fd_set fds;
  u_short tick_length;

  if (argc != 5) {
    fprintf (stderr, "usage: ktelnet host port service instance\n");
    exit(1);
  }
  hostname = argv[1];
  port = argv[2];
  service = argv[3];
  instance = argv[4];

  if (result = krb_mk_req(&ticket, service, instance, realm, 0)) {
    fprintf (stderr, "Can't get ticket: %s\n", krb_err_txt[result]);
    exit(1);
  }
  saddr.sin_family = AF_INET;
  if (!(hp = gethostbyname(hostname)))
    if ((saddr.sin_addr.s_addr = inet_addr(hostname)) == (unsigned long) -1) {
      fprintf (stderr, "%s: unknown host\n", hostname);
      exit(1);
    } else ;
  else
    saddr.sin_addr.s_addr = *((u_long *) hp->h_addr_list[0]);
  
  if (!(sp = getservbyname(port, "tcp")))
    if ((saddr.sin_port = htons(atoi(port))) == 0) {
      fprintf (stderr, "%s: unknown service\n", port);
      exit(1);
    } else ;
  else
    saddr.sin_port = sp->s_port;

  printf ("Connecting to %s port %d using ticket %s.%s@%s\n",
	  inet_ntoa(saddr.sin_addr.s_addr),
	  ntohs(saddr.sin_port), service, instance, realm);

  if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
    perror ("socket");
    exit(1);
  }
  if (connect (s, &saddr, sizeof(saddr))) {
    perror("connect");
    exit(1);
  }
  tick_length = (u_short) htons(ticket.length);
  write (s, &tick_length, 2);
  write (s, ticket.dat, ticket.length);
  
  FD_ZERO (&fds);
  do {
    FD_SET (0, &fds);
    FD_SET (s, &fds);
    if (select (s+1, &fds, 0, 0, 0) < 0) {
      perror ("select");
      exit(1);
    } else {
      if (FD_ISSET(0, &fds)) {
	n = read(0, buf, sizeof(buf));
	write (s, buf, n);
      }
      if (FD_ISSET(s, &fds)) {
	n = read(s, buf, sizeof(buf));
	write (1, buf, n);
      }
    }
  } while (1);
}
