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

📄 telnetd.c

📁 linux下telnet服务端的源码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	  syslog (LOG_AUTH|LOG_NOTICE,		  "Can't resolve %s: %s",		  inet_ntoa (saddr.sin_addr),		  hstrerror (h_errno));	  fatal (fd, "Cannot resolve address.");	}      remote_hostname = xstrdup (hp->h_name);      hp = gethostbyname (remote_hostname);      if (!hp)	{	  syslog (LOG_AUTH|LOG_NOTICE,		  "Forward resolve of %s failed: %s",		  remote_hostname, hstrerror (h_errno));	  fatal (fd, "Cannot resolve address.");	}      for (ap = hp->h_addr_list; *ap; ap++)	if (*(ip_addr_t*)ap == saddr.sin_addr.s_addr)	  break;      if (ap == NULL)	{	  syslog (LOG_AUTH|LOG_NOTICE,		  "None of addresses of %s matched %s",		  remote_hostname,		  inet_ntoa (saddr.sin_addr));	  exit (0);	}    }  else    {      if (hp)	remote_hostname = xstrdup (hp->h_name);      else	remote_hostname = xstrdup (inet_ntoa (saddr.sin_addr));    }#endif    /* Set socket options */  if (keepalive      && setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,		     (char *)&true, sizeof (true)) < 0)    syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");  if (debug_tcp      && setsockopt (fd, SOL_SOCKET, SO_DEBUG,		     (char *)&true, sizeof (true)) < 0)    syslog (LOG_WARNING, "setsockopt (SO_DEBUG): %m");  net = fd;  local_hostname = localhost ();#if defined(AUTHENTICATION) || defined(ENCRYPTION)  auth_encrypt_init (remote_hostname, local_hostname, "TELNETD", 1);#endif  io_setup ();    /* get terminal type. */  uname[0] = 0;  level = getterminaltype (uname);  setenv ("TERM", terminaltype ? terminaltype : "network", 1);  if (uname[0])    user_name = xstrdup (uname);  pty = startslave (remote_hostname, level, user_name);#ifndef	HAVE_STREAMSPTY  /* Turn on packet mode */  ioctl (pty, TIOCPKT, (char *)&true);#endif  ioctl (pty, FIONBIO, (char *)&true);  ioctl (net, FIONBIO, (char *)&true);  #if defined(SO_OOBINLINE)  setsockopt (net, SOL_SOCKET, SO_OOBINLINE, (char *)&true, sizeof true);#endif	#ifdef SIGTSTP  signal (SIGTSTP, SIG_IGN);#endif#ifdef	SIGTTOU  signal (SIGTTOU, SIG_IGN);#endif  signal (SIGCHLD, cleanup);}inttelnetd_run (){  int nfd;    get_slc_defaults ();  if (my_state_is_wont(TELOPT_SGA))    send_will(TELOPT_SGA, 1);  /* Old BSD 4.2 clients are unable to deal with TCP out-of-band data.     To find out, we send out a "DO ECHO". If the remote side is     a BSD 4.2 it will answer "WILL ECHO". See the response processing     below. */  send_do(TELOPT_ECHO, 1);  if (his_state_is_wont (TELOPT_LINEMODE))    {      /* Query the peer for linemode support by trying to negotiate	 the linemode option. */      linemode = 0;      editmode = 0;      send_do(TELOPT_LINEMODE, 1);  /* send do linemode */    }  send_do (TELOPT_NAWS, 1);  send_will (TELOPT_STATUS, 1);  flowmode = 1;		/* default flow control state */  restartany = -1;	/* uninitialized... */  send_do (TELOPT_LFLOW, 1);  /* Wait for a response from the DO ECHO. Reportedly, some broken     clients might not respond to it. To work around this, we wait     for a response to NAWS, which should have been processed after     DO ECHO (most dumb telnets respond with WONT for a DO that     they don't understand).         On the other hand, the client might have sent WILL NAWS as     part of its startup code, in this case it surely should have     answered our DO ECHO, so the second loop is waiting for     the ECHO to settle down.  */  ttloop (his_will_wont_is_changing (TELOPT_NAWS));  if (his_want_state_is_will (TELOPT_ECHO)      && his_state_is_will (TELOPT_NAWS))     ttloop (his_will_wont_is_changing (TELOPT_ECHO));  /* If the remote client is badly broken and did not respond to our     DO ECHO, we simulate the receipt of a will echo. This will also     send a WONT ECHO to the client, since we assume that the client     failed to respond because it believes that it is already in DO ECHO     mode, which we do not want. */    if (his_want_state_is_will (TELOPT_ECHO))    {      DEBUG(debug_options, 1, debug_output_data ("td: simulating recv\r\n"));      willoption (TELOPT_ECHO);    }  /* Turn on our echo */  if (my_state_is_wont (TELOPT_ECHO))    send_will (TELOPT_ECHO, 1);  /* Continuing line mode support.  If client does not support     real linemode, attempt to negotiate kludge linemode by sending     the do timing mark sequence. */  if (lmodetype < REAL_LINEMODE)    send_do (TELOPT_TM, 1);  /* Pick up anything received during the negotiations */  telrcv ();  if (hostinfo)    print_hostinfo ();      init_termbuf ();  localstat ();  DEBUG(debug_report, 1,	debug_output_data ("td: Entering processing loop\r\n"));  nfd = ((net > pty) ? net : pty) + 1;  for (;;)    {      fd_set ibits, obits, xbits;      register int c;      if (net_input_level () < 0 && pty_input_level () < 0)	break;      FD_ZERO(&ibits);      FD_ZERO(&obits);      FD_ZERO(&xbits);      /* Never look for input if there's still stuff in the corresponding	 output buffer */      if (net_output_level () || pty_input_level () > 0)  	FD_SET (net, &obits);      else 	FD_SET(pty, &ibits);      if (pty_output_level () || net_input_level () > 0) 	FD_SET(pty, &obits);      else 	FD_SET(net, &ibits);	      if (!SYNCHing) 	FD_SET(net, &xbits);      if ((c = select (nfd, &ibits, &obits, &xbits, NULL)) <= 0)	{	  if (c == -1 && errno == EINTR) 	    continue;	  sleep(5);	  continue;	}      if (FD_ISSET(net, &xbits)) 	SYNCHing = 1;      if (FD_ISSET(net, &ibits))	{	  /* Something to read from the network... */	  /*FIXME: handle  !defined(SO_OOBINLINE) */	  net_read ();	}      if (FD_ISSET(pty, &ibits))	{	  /* Something to read from the pty... */	  if (pty_read () < 0)	    break;	  c = pty_get_char (1); #if defined(TIOCPKT_IOCTL)	  if (c & TIOCPKT_IOCTL)	    {	      pty_get_char (0);	      copy_termbuf ();	      localstat ();	    }#endif	  if (c & TIOCPKT_FLUSHWRITE)	    {	      static char flushdata[] = { IAC, DM };	      pty_get_char (0);	      netclear();	/* clear buffer back */	      net_output_datalen (flushdata, sizeof (flushdata));	      set_neturg ();	      DEBUG(debug_options, 1, printoption("td: send IAC", DM));	    }	  if (his_state_is_will(TELOPT_LFLOW)	      && (c & (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)))	    {	      int newflow = c & TIOCPKT_DOSTOP ? 1 : 0;	      if (newflow != flowmode)		{		  net_output_data ("%c%c%c%c%c%c",				   IAC, SB, TELOPT_LFLOW,				   flowmode ? LFLOW_ON				   : LFLOW_OFF,				   IAC, SE);		}	      pty_get_char (0);	    }	}      while (pty_input_level () > 0)	{	  if (net_buffer_is_full ())	    break;	  c = pty_get_char (0);	  if (c == IAC)	    net_output_byte (c);	  net_output_byte (c);	  if (c == '\r' && my_state_is_wont (TELOPT_BINARY))	    {	      if (pty_input_level () > 0 && pty_get_char (1) == '\n')		net_output_byte (pty_get_char (0));	      else		net_output_byte (0);	    }	}      if (FD_ISSET(net, &obits) && net_output_level () > 0)	netflush ();      if (net_input_level () > 0)	telrcv ();            if (FD_ISSET(pty, &obits) && pty_output_level () > 0)	ptyflush ();    }  cleanup (0);}voidprint_hostinfo (){  char *im = NULL;  char *str;#ifdef HAVE_UNAME  struct utsname u;    if (uname (&u) == 0)    {      im = malloc (strlen (UNAME_IM_PREFIX)		   + strlen (u.sysname)		   + 1 + strlen (u.release)		   + strlen (UNAME_IM_SUFFIX) + 1);      if (im)	sprintf (im, "%s%s %s%s",		 UNAME_IM_PREFIX,		 u.sysname, u.release,		 UNAME_IM_SUFFIX);    }#endif /* HAVE_UNAME */  if (!im)    im = xstrdup ("\r\n\nUNIX (%l) (%t)\r\n\n");  str = expand_line (im);  free (im);    DEBUG(debug_pty_data, 1, debug_output_data ("sending %s", str));   pty_input_putback (str, strlen (str));  free (str);}voidtelnetd_version (){  printf ("telnetd - %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);  printf ("Copyright (C) 1998,2001,2002 Free Software Foundation, Inc.\n");  printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);  printf ("You may redistribute copies of %s\n", PACKAGE_NAME);  printf ("under the terms of the GNU General Public License.\n");  printf ("For more information about these matters, ");  printf ("see the files named COPYING.\n");}voidtelnetd_license (){  static char license_text[] ="   This program is free software; you can redistribute it and/or modify\n""   it under the terms of the GNU General Public License as published by\n""   the Free Software Foundation; either version 2, or (at your option)\n""   any later version.\n""\n""   This program is distributed in the hope that it will be useful,\n""   but WITHOUT ANY WARRANTY; without even the implied warranty of\n""   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n""   GNU General Public License for more details.\n""\n""   You should have received a copy of the GNU General Public License\n""   along with this program; if not, write to the Free Software\n""   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";  printf ("%s", license_text);}voidtelnetd_help (){  printf ("\Usage: telnetd [OPTION]\n\\n\Options are:\n\    -a, --authmode AUTHMODE  specify what mode to use for authentication\n\    -D, --debug[=LEVEL]      set debugging level\n\    -E, --exec-login STRING  set program to be executed instead of /bin/login\n\    -h, --no-hostinfo        do not print host information before login has\n\                             been completed\n\    -l, --linemode[=MODE]    set line mode\n\    -n, --no-keepalive       disable TCP keep-alives\n\    -U, --reverse-lookup     refuse  connections from addresses that\n\                             cannot be mapped back into a symbolic name\n\    -X, --disable-auth-type AUTHTYPE\n\                             disable the use of given authentication option\n\Informational options:\n\    -V, --version         display this help and exit\n\    -L, --license	  display license and exit\n\    -H. --help		  output version information and exit\n");}intstop(){  int volatile _s=1;  while (_s)    _s=_s;  return 0;}

⌨️ 快捷键说明

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