⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlogind.c

📁 linux下常用的网络工具的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (C) 1998,2001, 2002 Free Software Foundation, Inc.   This file is part of GNU Inetutils.   GNU Inetutils is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GNU Inetutils is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GNU Inetutils; see the file COPYING.  If not, write   to the Free Software Foundation, Inc., 51 Franklin Street,   Fifth Floor, Boston, MA 02110-1301 USA. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <signal.h>#ifdef HAVE_SYS_FILIO_H# include <sys/filio.h>#endif#include <termios.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#ifdef HAVE_SYS_STREAM_H# include <sys/stream.h>#endif#ifdef HAVE_SYS_TTY_H# include <sys/tty.h>#endif#ifdef HAVE_SYS_PTYVAR_H# include <sys/ptyvar.h>#endif#include <sys/wait.h>#include <sys/socket.h>#include <netinet/in.h>#ifdef HAVE_NETINET_IN_SYSTM_H# include <netinet/in_systm.h>#endif#ifdef HAVE_NETINET_IP_H# include <netinet/ip.h>#endif#include <arpa/inet.h>#include <netdb.h>#include <pwd.h>#include <syslog.h>#include <errno.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#ifdef HAVE_SYS_SELECT_H# include <sys/select.h>#endif#include <sys/ioctl.h>#include <sys/stat.h>		/* Needed for chmod() */#include <libinetutils.h>/*  The TIOCPKT_* macros may not be implemented in the pty driver.  Defining them here allows the program to be compiled.  */#ifndef TIOCPKT# define TIOCPKT                 _IOW('t', 112, int)# define TIOCPKT_FLUSHWRITE      0x02# define TIOCPKT_NOSTOP          0x10# define TIOCPKT_DOSTOP          0x20#endif /*TIOCPKT*/#ifndef TIOCPKT_WINDOW# define TIOCPKT_WINDOW 0x80#endif/* `defaults' for tty settings.  */#ifndef TTYDEF_IFLAG#define	TTYDEF_IFLAG	(BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)#endif#ifndef TTYDEF_OFLAG#ifndef OXTABS#define OXTABS 0#endif#define TTYDEF_OFLAG	(OPOST | ONLCR | OXTABS)#endif#ifndef TTYDEF_LFLAG#define TTYDEF_LFLAG	(ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)#endif#define AUTH_KERBEROS_SHISHI 1#define AUTH_KERBEROS_4 4#define AUTH_KERBEROS_5 5#if defined(KERBEROS) || defined(SHISHI)# ifdef	KRB4# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"#  include <kerberosIV/des.h>#  include <kerberosIV/krb.h>#  define kerberos_error_string(c) krb_err_txt[c]#  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_4# elif defined(KRB5)# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"#  include <krb5.h>#  include <kerberosIV/krb.h>#  define kerberos_error_string(c) error_message (c)#  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_5# elif defined(SHISHI)# define SECURE_MESSAGE "This rlogin session is using encryption for all transmissions.\r\n"#  include <shishi.h>#  include "shishi_def.h"#  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_SHISHI#  define kerberos_error_string(c) shishi_strerror(c)# endif#endif /* KERBEROS */#define	ENVSIZE	(sizeof("TERM=")-1)	/* skip null for concatenation */#ifndef DEFMAXCHILDREN# define DEFMAXCHILDREN 10	/* Default maximum number of children */#endif#ifndef DEFPORT# define DEFPORT 513#endifextern int      __check_rhosts_file;#ifndef SHISHIstruct auth_data{  struct sockaddr_in from;  char           *hostname;  char           *lusername;  char           *rusername;  char           *term;  char           *env[2];#ifdef KERBEROS#ifdef KRB5  int             kerberos_version;  krb5_principal  client;  krb5_context    context;  krb5_ccache     ccache;  krb5_keytab     keytab;#endif#endif};#endifstatic const char *short_options = "aD::d::hk::L:lnp:orxV";static struct option long_options[] = {  {"allow-root", no_argument, 0, 'o'},  {"verify-hostname", no_argument, 0, 'a'},  {"daemon", optional_argument, 0, 'd'},  {"no-rhosts", no_argument, 0, 'l'},  {"no-keepalive", no_argument, 0, 'n'},  {"local-domain", required_argument, 0, 'L'},  {"kerberos", optional_argument, 0, 'k'},  {"encrypt", no_argument, 0, 'x'},  {"debug", optional_argument, 0, 'D'},  {"help", no_argument, 0, 'h'},  {"version", no_argument, 0, 'V'},  {"port", required_argument, 0, 'p'},  {"reverse-required", no_argument, 0, 'r'},  {0, 0, 0, 0}};int             allow_root = 0;int             verify_hostname = 0;int             keepalive = 1;#if defined(KERBEROS) || defined(SHISHI)int             kerberos = 0;#ifdef ENCRYPTIONint             encrypt_io = 0;#endif /* ENCRYPTION */#endif /* KERBEROS */int             reverse_required = 0;int             debug_level = 0;int             numchildren;int             netf;char            line[1024];	/* FIXME */int             confirmed;const char     *path_login = PATH_LOGIN;char           *local_domain_name;int             local_dot_count;struct winsize  win = { 0, 0, 0, 0 };void usage      __P ((void));void rlogin_daemon __P ((int maxchildren, int port));int rlogind_auth __P ((int fd, struct auth_data * ap));void setup_tty  __P ((int fd, struct auth_data * ap));void exec_login __P ((int authenticated, struct auth_data * ap));int rlogind_mainloop __P ((int infd, int outfd));int do_rlogin   __P ((int infd, struct auth_data * ap));int do_krb_login __P ((int infd, struct auth_data * ap, const char **msg));void getstr     __P ((int infd, char **ptr, const char *prefix));void protocol   __P ((int f, int p, struct auth_data * ap));int control     __P ((int pty, char *cp, size_t n));RETSIGTYPE cleanup __P ((int signo));void fatal      __P ((int f, const char *msg, int syserr));int in_local_domain __P ((char *hostname));char           *topdomain __P ((char *name, int max_dots));RETSIGTYPErlogind_sigchld (int sig){  pid_t           pid;  int             status;  while ((pid = waitpid (-1, &status, WNOHANG)) > 0)    --numchildren;  signal (sig, rlogind_sigchld);}#define MODE_INETD 0#define MODE_DAEMON 1#if defined(KERBEROS) && defined (ENCRYPTION)# define ENCRYPT_IO encrypt_io# define IF_ENCRYPT(stmt) if (encrypt_io) stmt# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt# define ENC_READ(c, fd, buf, size, ap) \ if (encrypt_io) \     c = des_read(fd, buf, size); \ else \     c = read(fd, buf, size);# define EN_WRITE(c, fd, buf, size, ap) \ if (encrypt_io) \     c = des_write(fd, buf, size); \ else \     c = write(fd, buf, size);#elif defined(SHISHI) && defined (ENCRYPTION)# define ENCRYPT_IO encrypt_io# define IF_ENCRYPT(stmt) if (encrypt_io) stmt# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt# define ENC_READ(c, fd, buf, size, ap) \ if (encrypt_io) \     readenc (ap->h, fd, buf, &c, &ap->iv1, ap->enckey, ap->protocol); \ else \     c = read(fd, buf, size);# define ENC_WRITE(c, fd, buf, size, ap) \ if (encrypt_io) \     writeenc (ap->h, fd, buf, size, &c, &ap->iv2, ap->enckey, ap->protocol); \ else \     c = write(fd, buf, size);#else# define ENCRYPT_IO 0# define IF_ENCRYPT(stmt)# define IF_NOT_ENCRYPT(stmt) stmt# define ENC_READ(c, fd, buf, size, ap) c = read (fd, buf, size)# define ENC_WRITE(c, fd, buf, size, ap) c = write (fd, buf, size)#endifchar *program_name;intmain (int argc, char *argv[]){  int             port = 0;  int             maxchildren = DEFMAXCHILDREN;  int             mode = MODE_INETD;  int             c;  program_name = argv[0];  while ((c = getopt_long (argc, argv, short_options, long_options, NULL))	 != EOF)    {      switch (c)	{	case 'a':	  verify_hostname = 1;	  break;	case 'D':	  if (optarg)	    debug_level = strtoul (optarg, NULL, 10);	  break;	case 'd':	  mode = MODE_DAEMON;	  if (optarg)	    maxchildren = strtoul (optarg, NULL, 10);	  if (maxchildren == 0)	    maxchildren = DEFMAXCHILDREN;	  break;	case 'l':	  __check_rhosts_file = 0;	/* FIXME: extern var? */	  break;	case 'L':	  local_domain_name = optarg;	  break;	case 'n':	  keepalive = 0;	  break;#if defined(KERBEROS) || defined(SHISHI)	case 'k':	  if (optarg)	    {	      if (*optarg == '4')		kerberos = AUTH_KERBEROS_4;	      else if (*optarg == '5')		kerberos = AUTH_KERBEROS_5;	    }	  else	    kerberos = AUTH_KERBEROS_DEFAULT;	  break;# ifdef ENCRYPTION	case 'x':	  encrypt_io = 1;	  break;# endif	/* ENCRYPTION */#endif /* KERBEROS */	case 'o':	  allow_root = 1;	  break;	case 'p':	  port = strtoul (optarg, NULL, 10);	  break;	case 'r':	  reverse_required = 1;	  break;	case 'V':	  printf ("rlogind (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION);	  exit (0);	case 'h':	default:	  usage ();	  exit (0);	}    }  openlog ("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);  argc -= optind;  if (argc > 0)    {      syslog (LOG_ERR, "%d extra arguments", argc);      exit (1);    }  signal (SIGHUP, SIG_IGN);  if (!local_domain_name)    {      char *p = localhost ();      if (!p)	{	  syslog (LOG_ERR, "can't determine local hostname");	  exit (1);	}      local_dot_count = 2;      local_domain_name = topdomain (p, local_dot_count);    }  else    {      char           *p;      local_dot_count = 0;      for (p = local_domain_name; *p; p++)	if (*p == '.')	  local_dot_count++;    }  if (mode == MODE_DAEMON)    rlogin_daemon (maxchildren, port);  else    exit (rlogind_mainloop (fileno (stdin), fileno (stdout)));  /* To pacify lint */  return 0;}voidrlogin_daemon (int maxchildren, int port){  pid_t           pid;  size_t          size;  struct sockaddr_in saddr;  int             listenfd, fd;  if (port == 0)    {      struct servent *svp;      svp = getservbyname ("login", "tcp");      if (svp != NULL)	port = ntohs (svp->s_port);      else	port = DEFPORT;    }  /* Become a daemon. Take care to close inherited fds and to hold     first three one, lest master/slave ptys clash with standard     in,out,err   */  if (daemon (0, 0) < 0)    {      syslog (LOG_ERR, "failed to become a daemon %s", strerror (errno));      fatal (fileno (stderr), "fork failed, exiting", 0);    }  signal (SIGCHLD, rlogind_sigchld);  listenfd = socket (AF_INET, SOCK_STREAM, 0);  if (listenfd == -1)    {      syslog (LOG_ERR, "socket: %s", strerror (errno));      exit (1);    }  {    int             on = 1;    setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);  }  size = sizeof saddr;  memset (&saddr, 0, size);  saddr.sin_family = AF_INET;  saddr.sin_addr.s_addr = htonl (INADDR_ANY);  saddr.sin_port = htons (port);  size = sizeof saddr;  if (bind (listenfd, (struct sockaddr *) &saddr, size) == -1)    {      syslog (LOG_ERR, "bind: %s", strerror (errno));      exit (1);    }  if (listen (listenfd, 128) == -1)    {      syslog (LOG_ERR, "listen: %s", strerror (errno));      exit (1);    }  while (1)    {      if (numchildren > maxchildren)	{	  syslog (LOG_ERR, "too many children (%d)", numchildren);	  pause ();	  continue;	}      size = sizeof saddr;      fd = accept (listenfd, (struct sockaddr *) &saddr, &size);      if (fd == -1)	{	  if (errno == EINTR)	    continue;	  syslog (LOG_ERR, "accept: %s", strerror (errno));	  exit (1);	}      pid = fork ();      if (pid == -1)	syslog (LOG_ERR, "fork: %s", strerror (errno));      else if (pid == 0)	/* child */	{	  close (listenfd);	  exit (rlogind_mainloop (fd, fd));	}      else	numchildren++;      close (fd);    }}intrlogind_auth (int fd, struct auth_data *ap){  struct hostent *hp;  char           *hostname;  int             authenticated = 0;#ifdef SHISHI  int             len, c;#endif  confirmed = 0;  /* Check the remote host name */  hp = gethostbyaddr ((char *) &ap->from.sin_addr, sizeof (struct in_addr),		      ap->from.sin_family);  if (hp)    hostname = hp->h_name;  else if (reverse_required)    {      syslog (LOG_CRIT, "can't resolve remote IP address");      exit (1);    }  else    hostname = inet_ntoa (ap->from.sin_addr);  ap->hostname = strdup (hostname);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -