📄 telnetd.c
字号:
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "telnetd.h"#include <getopt.h>#ifdef HAVE_SYS_UTSNAME_H# include <sys/utsname.h>#endifstatic 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;intmain (int argc, char **argv){ int c; 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){ struct sockaddr_in saddr; int true = 1; int len; struct hostent *hp; char uname[256]; /*FIXME*/ int level; len = sizeof (saddr); if (getpeername(fd, (struct sockaddr *)&saddr, &len) < 0) { syslog (LOG_ERR, "getpeername: %m"); exit (1); } syslog (LOG_INFO, "Connect from %s", inet_ntoa (saddr.sin_addr)); hp = gethostbyaddr ((char*)&saddr.sin_addr.s_addr, sizeof (saddr.sin_addr.s_addr), AF_INET); if (reverse_lookup) { char **ap; if (!hp) { 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)); } /* Set socket options */ if (keepalive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -