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

📄 rshd.c

📁 linux下常用的网络工具的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 1988, 1989, 1992, 1993, 1994, 2002 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * remote shell server: *	[port]\0 *	remuser\0 *	locuser\0 *	command\0 *	data */#ifdef HAVE_CONFIG_H# include <config.h>#endif#if !defined (__GNUC__) && defined (_AIX)#pragma alloca#endif#ifndef alloca /* Make alloca work the best possible way.  */# ifdef __GNUC__#  define alloca __builtin_alloca# else /* not __GNUC__ */#  if HAVE_ALLOCA_H#   include <alloca.h>#  else /* not __GNUC__ or HAVE_ALLOCA_H */#   ifndef _AIX /* Already did AIX, up at the top.  */char *alloca ();#   endif /* not _AIX */#  endif /* not HAVE_ALLOCA_H */# endif /* not __GNUC__ */#endif /* not alloca */#include <sys/param.h>#include <sys/ioctl.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#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include <fcntl.h>#ifdef HAVE_SYS_FILIO_H# include <sys/filio.h>#endif#include <pwd.h>#include <signal.h>#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <unistd.h>#include <getopt.h>#include <grp.h>#ifdef HAVE_SYS_SELECT_H# include <sys/select.h>#endif#include <libinetutils.h>int	keepalive = 1;		/* flag for SO_KEEPALIVE scoket option */int	check_all;int	log_success;		/* If TRUE, log all successful accesses */int	sent_null;void	 doit (int, struct sockaddr_in *);void	 rshd_error (const char *, ...);char	*getstr (const char *);int	 local_domain (const char *);const char *topdomain (const char *);void	 usage (void);void     help (void);#if defined(KERBEROS) || defined(SHISHI)#ifdef KERBEROS# include <kerberosIV/des.h># include <kerberosIV/krb.h>Key_schedule	schedule;char	authbuf[sizeof(AUTH_DAT)];char	tickbuf[sizeof(KTEXT_ST)];#elif defined(SHISHI)# include <shishi.h># include <shishi_def.h>Shishi * h;Shishi_ap * ap;Shishi_key * enckey;shishi_ivector iv1, iv2, iv3, iv4;shishi_ivector *ivtab[4];int protocol;#endif# define	VERSION_SIZE	9# define SECURE_MESSAGE  "This rsh session is using DES encryption for all transmissions.\r\n"# define	OPTIONS		"alnkvxLVh"int	doencrypt, use_kerberos, vacuous;#else# define	OPTIONS	"alnLVh"#endifstatic const char *short_options = OPTIONS;static struct option long_options[] ={  {"verify-hostname", no_argument, 0, 'a'},  {"no-rhosts", no_argument, 0, 'l'},  {"no-keepalive", no_argument, 0, 'n'},  {"log-sessions", required_argument, 0, 'L'},  {"kerberos", no_argument, 0, 'k'},  {"vacuous", no_argument, 0, 'v'},  {"help", no_argument, 0, 'h'},  {"version", no_argument, 0, 'V'},  {0, 0, 0, 0}};char *program_name;/* Remote shell server. We're invoked by the rcmd(3) function. */intmain (int argc, char *argv[]){  extern int __check_rhosts_file; /* hook in rcmd(3) */  struct linger linger;  int ch, on = 1, fromlen;  struct sockaddr_in from;  int sockfd;  program_name = argv[0];  opterr = 0;  while ((ch = getopt_long (argc, argv, short_options, long_options, NULL))	 != EOF)    {      switch (ch)	{	case 'a':	  check_all = 1;	  break;	case 'l':	  __check_rhosts_file = 0; /* don't check .rhosts file */	  break;	case 'n':	  keepalive = 0; /* don't enable SO_KEEPALIVE */	  break;#if defined(KERBEROS) || defined(SHISHI)	case 'k':	  use_kerberos = 1;	  break;	case 'v':	  vacuous = 1;	  break;#ifdef ENCRYPTION	case 'x':	  doencrypt = 1;	  break;#endif#endif	case 'L':	  log_success = 1;	  break;       case 'V':          printf ("rshd (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION);          exit (0);        case 'h':	  help ();	  exit (0);	case '?':	default:	  usage ();	  break;	}    }  openlog ("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);  argc -= optind;  if (argc > 0)    {      syslog (LOG_ERR, "%d extra arguments", argc);      exit (1);    }#if defined(KERBEROS) || defined(SHISHI)  if (use_kerberos && vacuous)    {      syslog (LOG_ERR, "only one of -k and -v allowed");      exit (2);    }#ifdef ENCRYPTION  if (doencrypt && !use_kerberos)    {      syslog (LOG_ERR, "-k is required for -x");      exit (2);    }#endif#endif  /*   * We assume we're invoked by inetd, so the socket that the   * connection is on, is open on descriptors 0, 1 and 2.   * STD{IN,OUT,ERR}_FILENO.   * We may in the future make it standalone for certain platform.   */  sockfd = STDIN_FILENO;  /*   * First get the Internet address of the client process.   * This is requored for all the authentication we perform.   */  fromlen = sizeof from;  if (getpeername (sockfd, (struct sockaddr *)&from, &fromlen) < 0)    {      syslog (LOG_ERR, "getpeername: %m");      _exit (1);    }  /* Set the socket options: SO_KEEPALIVE and SO_LINGER */  if (keepalive && setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,			      sizeof on) < 0)    syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");  linger.l_onoff = 1;  linger.l_linger = 60;			/* XXX */  if (setsockopt (sockfd, SOL_SOCKET, SO_LINGER, (char *)&linger,		  sizeof linger) < 0)    syslog (LOG_WARNING, "setsockopt (SO_LINGER): %m");  doit (sockfd, &from);  /* NOTREACHED */  return 0;}char	username[20] = "USER=";char	logname[23] = "LOGNAME=";char	homedir[64] = "HOME=";char	shell[64] = "SHELL=";char	path[100] = "PATH=";char	*envinit[] = { homedir, shell, path, logname, username, 0 };extern char	**environ;voiddoit (int sockfd, struct sockaddr_in *fromp){  extern char *__rcmd_errstr;	/* syslog hook from libc/net/rcmd.c. */  struct hostent *hp;  struct passwd *pwd;  u_short port;  fd_set ready, readfrom;  int cc, nfd, pv[2], pid, s = sockfd;  int one = 1;  const char *hostname, *errorstr, *errorhost = NULL;  char *cp, sig, buf[BUFSIZ];  char *cmdbuf, *locuser, *remuser;#ifdef	KERBEROS  AUTH_DAT	*kdata = (AUTH_DAT *) NULL;  KTEXT		ticket = (KTEXT) NULL;  char		instance[INST_SZ], version[VERSION_SIZE];  struct		sockaddr_in	fromaddr;  int		rc;  long		authopts;  int		pv1[2], pv2[2];  fd_set		wready, writeto;  fromaddr = *fromp;#elif defined SHISHI  int n;  int		pv1[2], pv2[2];  fd_set		wready, writeto;  int keytype, keylen;  int cksumtype, cksumlen;  char *cksum = NULL;#endif  signal(SIGINT, SIG_DFL);  signal(SIGQUIT, SIG_DFL);  signal(SIGTERM, SIG_DFL);#ifdef DEBUG  {    int t = open(PATH_TTY, O_RDWR);    if (t >= 0)      {	ioctl (t, TIOCNOTTY, (char *)0);	close (t);      }  }#endif  /* Verify that the client's address is an Internet adress. */  if (fromp->sin_family != AF_INET)    {      syslog (LOG_ERR, "malformed \"from\" address (af %d)\n",	      fromp->sin_family);      exit (1);    }#ifdef IP_OPTIONS  {    u_char optbuf[BUFSIZ/3], *cp;    char lbuf[BUFSIZ], *lp;    int optsize = sizeof(optbuf), ipproto;    struct protoent *ip;    if ((ip = getprotobyname ("ip")) != NULL)      ipproto = ip->p_proto;    else      ipproto = IPPROTO_IP;    if (!getsockopt (sockfd, ipproto, IP_OPTIONS, (char *)optbuf,		     &optsize) && optsize != 0)      {	lp = lbuf;	/* The clent has set IP options.  This isn't allowd.	 * Use syslog() to record the fact.	 */	for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)	  sprintf(lp, " %2.2x", *cp);	syslog(LOG_NOTICE,	       "Connection received from %s using IP options (ignored):%s",	       inet_ntoa (fromp->sin_addr), lbuf);	/* Turn off the options.  If this doesn't work, we quit */	if (setsockopt (sockfd, ipproto, IP_OPTIONS,			(char *)NULL, optsize) != 0)	  {	    syslog (LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");	    exit (1);	  }      }  }#endif  /* Need host byte ordered port# to compare */  fromp->sin_port = ntohs((u_short)fromp->sin_port);  /* Verify that the client's address was bound to a reserved port */#if defined(KERBEROS) || defined(SHISHI)  if (!use_kerberos)#endif    if (fromp->sin_port >= IPPORT_RESERVED	|| fromp->sin_port < IPPORT_RESERVED/2)      {	syslog (LOG_NOTICE|LOG_AUTH,		"Connection from %s on illegal port %u",		inet_ntoa(fromp->sin_addr), fromp->sin_port);	exit (1);      }  /* Read the ASCII string specifying the secondary port# from   * the socket.  We set a timer of 60 seconds to do this read,   * else we assume something is wrong.  If the client doesn't want   * the secondary port, they just send the terminating null byte.   */  alarm (60);  port = 0;  for (;;)    {      char c;      if ((cc = read (sockfd, &c, 1)) != 1)	{	  if (cc < 0)	    syslog (LOG_NOTICE, "read: %m");	  shutdown (sockfd, 2);	  exit (1);	}      /* null byte terminates the string */      if (c== 0)	break;      port = port * 10 + c - '0';    }  alarm (0);  if (port != 0)    {      /* If the secondary port# is nonzero, the we have to       * connect to that port (which the client has already       * created and is listening on).  The secondary port#       * that the client tells us to connect to has to also be       * a reserved port#.  Also, our end of this secondary       * connection has to also have a reserved TCP port bond

⌨️ 快捷键说明

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