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

📄 telnetd.c

📁 linux下telnet服务端的源码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1998, 2001, 2002, 2004x 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. */#include "telnetd.h"#include <getopt.h>#ifdef HAVE_SYS_UTSNAME_H# include <sys/utsname.h>#endif#include <libinetutils.h>static char short_options[] = "a:D::d:E:HhLl::nS:Uu:VX:";static struct option long_options[] ={  /* Help options */  {"version", no_argument, NULL, 'V'},  {"license", no_argument, NULL, 'L'},  {"help",    no_argument, NULL, 'H'},  /* Common options */  {"authmode", required_argument, NULL, 'a'},  {"debug", optional_argument, NULL, 'D'},  {"exec-login", required_argument, NULL, 'E'},  {"no-hostinfo", no_argument, NULL, 'h'},  {"linemode", optional_argument, NULL, 'l'},  {"no-keepalive", no_argument, NULL, 'n'},  {"reverse-lookup", no_argument, NULL, 'U'},  {"disable-auth-type", required_argument, NULL, 'X'},  {NULL, 0, NULL, 0}};static void telnetd_version P((void));static void telnetd_license P((void));static void telnetd_help P((void));static void parse_authmode P((char *str));static void parse_linemode P((char *str));static void parse_debug_level P((char *str));static void telnetd_setup P((int fd));static int telnetd_run P((void));static void print_hostinfo P((void));/* Template command line for invoking login program */char *login_invocation =#ifdef SOLARIS"/bin/login -h %h %?T{TERM=%T}{-} %?u{%?a{-f }-- %u}"#else"/bin/login -p -h %h %?u{-f %u}"#endif;int keepalive = 1;      /* Should the TCP keepalive bit be set */int reverse_lookup = 0; /* Reject connects from hosts which IP numbers			   cannot be reverse mapped to their hostnames */int alwayslinemode;     /* Always set the linemode (1) */ int lmodetype;          /* Type of linemode (2) */int hostinfo = 1;       /* Print the host-specific information before			   login */int auth_level = 0;     /* Authentication level */int debug_level[debug_max_mode]; /* Debugging levels */int debug_tcp = 0;               /* Should the SO_DEBUG be set? */int net;      /* Network connection socket */int pty;      /* PTY master descriptor */char *remote_hostname;char *local_hostname;char *user_name;char line[256];char	options[256];char	do_dont_resp[256];char	will_wont_resp[256];int	linemode;	/* linemode on/off */int	uselinemode;	/* what linemode to use (on/off) */int	editmode;	/* edit modes in use */int	useeditmode;	/* edit modes to use */int	alwayslinemode;	/* command line option */int	lmodetype;	/* Client support for linemode */int	flowmode;	/* current flow control state */int	restartany;	/* restart output on any character state */int	diagnostic;	/* telnet diagnostic capabilities */#if defined(AUTHENTICATION)int	auth_level;int     autologin;#endifslcfun	slctab[NSLC + 1];	/* slc mapping table */char	*terminaltype;int	SYNCHing;		/* we are in TELNET SYNCH mode */struct telnetd_clocks clocks;char *program_name;intmain (int argc, char **argv){  int c;  program_name = argv[0];  while ((c = getopt_long (argc, argv, short_options, long_options, NULL))	 != EOF)    {      switch (c)	{	case 'V': 	  telnetd_version ();	  exit (0);	  	case 'L':	  telnetd_license ();	  exit (0);	  	case 'H':	  telnetd_help ();	  exit (0);	  	case 'a':	  parse_authmode (optarg);	  break;	  	case 'D':	  parse_debug_level (optarg);	  break;	  	case 'E':	  login_invocation = optarg;	  break;	  	case 'h':	  hostinfo = 0;	  break;	  	case 'l':	  parse_linemode (optarg);	  break;	  	case 'n':	  keepalive = 0;	  break;	  	case 'U':	  reverse_lookup = 1;	  break;	  #ifdef	AUTHENTICATION	case 'X':	  auth_disable_name (optarg);	  break;#endif	default:	  fprintf (stderr, "telnetd: unknown command line option: %c\n", c);	  exit (1);	}    }  if (argc != optind)    {      fprintf (stderr, "telnetd: junk arguments in the command line\n");      exit (1);    }    openlog ("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);  telnetd_setup (0);  return telnetd_run ();}voidparse_linemode (char *str){  if (!str)    alwayslinemode = 1;  else if (strcmp (str, "nokludge") == 0)    lmodetype = NO_AUTOKLUDGE;  else    fprintf (stderr,	     "telnetd: invalid argument to --linemode\n");}voidparse_authmode (char *str){  if (strcasecmp (str, "none") == 0)     auth_level = 0;  else if (strcasecmp (str, "other") == 0)     auth_level = AUTH_OTHER;  else if (strcasecmp (str, "user") == 0)     auth_level = AUTH_USER;  else if (strcasecmp (str, "valid") == 0)     auth_level = AUTH_VALID;  else if (strcasecmp (str, "off") == 0)     auth_level = -1;  else     fprintf (stderr,	     "telnetd: unknown authorization level for -a\n");}static struct {  char *name;  int modnum;} debug_mode[debug_max_mode] = {  "options", debug_options,  "report",  debug_report,  "netdata", debug_net_data,  "ptydata", debug_pty_data,  "auth", debug_auth,};voidparse_debug_level (char *str){  int i;  char *tok;  if (!str)    {      for (i = 0; i < debug_max_mode; i++) 	debug_level[ debug_mode[i].modnum ] = MAX_DEBUG_LEVEL;      return;    }    for (tok = strtok (str, ","); tok; tok = strtok (NULL, ","))    {      int length, level;      char *p;      if (strcmp (tok, "tcp") == 0)	{	  debug_tcp = 1;	  continue;	}      p = strchr (tok, '=');      if (p)	{	  length = p - tok;	  level  = strtoul (p+1, NULL, 0);	}      else	{	  length = strlen (tok);	  level  = MAX_DEBUG_LEVEL;	}      for (i = 0; i < debug_max_mode; i++) 	if (strncmp (debug_mode[i].name, tok, length) == 0)	  {	    debug_level[ debug_mode[i].modnum ] = level;	    break;	  }      if (i == debug_max_mode)	fprintf (stderr, "telnetd: unknown debug mode: %s", tok);    }}typedef unsigned int ip_addr_t; /*FIXME*/voidtelnetd_setup (int fd){#ifdef IPV6  struct sockaddr_storage saddr;  char buf[256], buf2[256]; /* FIXME: We should use dynamic allocation. */  int err;#else  struct sockaddr_in saddr;  struct hostent *hp;#endif  int true = 1;  socklen_t len;  char uname[256]; /*FIXME*/  int level;   len = sizeof (saddr);  if (getpeername(fd, (struct sockaddr *)&saddr, &len) < 0)    {      syslog (LOG_ERR, "getpeername: %m");      exit (1);    }#ifdef IPV6  err = getnameinfo ((struct sockaddr *) &saddr, sizeof (saddr), buf,		     sizeof (buf), NULL, 0, NI_NUMERICHOST);  if (err)    {      const char *errmsg;            if (err == EAI_SYSTEM)	errmsg = strerror (errno);      else	errmsg = gai_strerror (err);            syslog (LOG_AUTH|LOG_NOTICE, "Cannot get address: %s", errmsg);      fatal (fd, "Cannot get address.");    }  /* We use a second buffer so we don't have to call getnameinfo again     if we need the numeric host below.  */  err = getnameinfo ((struct sockaddr *) &saddr, sizeof (saddr), buf2,		     sizeof (buf2), NULL, 0, NI_NAMEREQD);  if (reverse_lookup)    {      struct addrinfo *result, *aip;      if (err)	{	  const char *errmsg;	  	  if (err == EAI_SYSTEM)	    errmsg = strerror (errno);	  else	    errmsg = gai_strerror (err);	  	  syslog (LOG_AUTH|LOG_NOTICE, "Can't resolve %s: %s", buf, errmsg);	  fatal (fd, "Cannot resolve address.");	}      remote_hostname = xstrdup (buf2);      err = getaddrinfo (remote_hostname, NULL, NULL, &result);      if (err)	{	  const char *errmsg;	  	  if (err == EAI_SYSTEM)	    errmsg = strerror (errno);	  else	    errmsg = gai_strerror (err);	  	  syslog (LOG_AUTH|LOG_NOTICE, "Forward resolve of %s failed: %s",		  remote_hostname, errmsg);	  fatal (fd, "Cannot resolve address.");	}      for (aip = result; aip; aip = aip->ai_next)	if (!memcmp (aip->ai_addr, &saddr, aip->ai_addrlen))	  break;      if (aip == NULL)	{	  syslog (LOG_AUTH|LOG_NOTICE,		  "None of addresses of %s matched %s",		  remote_hostname,		  buf);	  exit (0);	}      freeaddrinfo (result);    }  else    {      if (!err)	remote_hostname = xstrdup (buf2);      else	remote_hostname = xstrdup (buf);    }#else  hp = gethostbyaddr ((char*)&saddr.sin_addr.s_addr,		      sizeof (saddr.sin_addr.s_addr), AF_INET);  if (reverse_lookup)    {      char **ap;            if (!hp)	{

⌨️ 快捷键说明

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