?? telnetd.c
字號:
/* * Copyright (c) 1989, 1993 * 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. * 3. 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. */#include "telnetd.h"#include <sys/socket.h>#include <netdb.h>#include <fcntl.h>#include <syslog.h>#include <unistd.h>#include <sys/ioctl.h>/* RCSID("$KTH: telnetd.c,v 1.64 2001/02/08 16:06:27 assar Exp $"); */#ifdef _SC_CRAY_SECURE_SYS#include <sys/sysv.h>#include <sys/secdev.h>#include <sys/secparm.h>#include <sys/usrv.h>int secflag;char tty_dev[16];struct secdev dv;struct sysv sysv;struct socksec ss;#endif /* _SC_CRAY_SECURE_SYS */#ifndef ENCRYPTION#define encrypt_delay() 0#endif#ifdef AUTHENTICATIONint auth_level = 0;#endifextern int utmp_len;int registerd_host_only = 0;#ifdef STREAMSPTY# include <stropts.h># include <termios.h>#ifdef HAVE_SYS_UIO_H#include <sys/uio.h>#endif /* HAVE_SYS_UIO_H */#ifdef HAVE_SYS_STREAM_H#include <sys/stream.h>#endif#ifdef _AIX#include <sys/termio.h>#endif# ifdef HAVE_SYS_STRTTY_H# include <sys/strtty.h># endif# ifdef HAVE_SYS_STR_TTY_H# include <sys/str_tty.h># endif/* make sure we don't get the bsd version *//* what is this here for? solaris? /joda */# ifdef HAVE_SYS_TTY_H# include "/usr/include/sys/tty.h"# endif# ifdef HAVE_SYS_PTYVAR_H# include <sys/ptyvar.h># endif/* * Because of the way ptyibuf is used with streams messages, we need * ptyibuf+1 to be on a full-word boundary. The following weirdness * is simply to make that happen. */long ptyibufbuf[BUFSIZ/sizeof(long)+1];char *ptyibuf = ((char *)&ptyibufbuf[1])-1;char *ptyip = ((char *)&ptyibufbuf[1])-1;char ptyibuf2[BUFSIZ];unsigned char ctlbuf[BUFSIZ];struct strbuf strbufc, strbufd;int readstream(int, char*, int);#else /* ! STREAMPTY *//* * I/O data buffers, * pointers, and counters. */char ptyibuf[BUFSIZ], *ptyip = ptyibuf;char ptyibuf2[BUFSIZ];#endif /* ! STREAMPTY */int hostinfo = 1; /* do we print login banner? */#ifdef _CRAYextern int newmap; /* nonzero if \n maps to ^M^J */int lowpty = 0, highpty; /* low, high pty numbers */#endif /* CRAY */int debug = 0;int keepalive = 1;char *progname;char *gettyent = "default";char *gettytab[2] = { "/etc/gettytab", NULL };static void usage (void);/* * The string to pass to getopt(). We do it this way so * that only the actual options that we support will be * passed off to getopt(). */char valid_opts[] = "Bd:g:hklnS:u:UL:y"#ifdef AUTHENTICATION "a:X:z"#endif#ifdef DIAGNOSTICS "D:"#endif#ifdef _CRAY "r:"#endif ;static void doit(struct sockaddr*, int);intmain(int argc, char **argv){ struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; int on = 1; socklen_t sa_size; int ch;#if defined(IPPROTO_IP) && defined(IP_TOS) int tos = -1;#endif#ifdef ENCRYPTION extern int des_check_key; des_check_key = 1; /* Kludge for Mac NCSA telnet 2.6 /bg */#endif pfrontp = pbackp = ptyobuf; netip = netibuf; nfrontp = nbackp = netobuf; progname = *argv;#ifdef ENCRYPTION nclearto = 0;#endif#ifdef _CRAY /* * Get number of pty's before trying to process options, * which may include changing pty range. */ highpty = getnpty();#endif /* CRAY */ while ((ch = getopt(argc, argv, valid_opts)) != -1) { switch(ch) {#ifdef AUTHENTICATION case 'a': /* * Check for required authentication level */ if (strcmp(optarg, "debug") == 0) { auth_debug_mode = 1; } else if (strcasecmp(optarg, "none") == 0) { auth_level = 0; } else if (strcasecmp(optarg, "other") == 0) { auth_level = AUTH_OTHER; } else if (strcasecmp(optarg, "user") == 0) { auth_level = AUTH_USER; } else if (strcasecmp(optarg, "valid") == 0) { auth_level = AUTH_VALID; } else if (strcasecmp(optarg, "off") == 0) { /* * This hack turns off authentication */ auth_level = -1; } else { fprintf(stderr, "telnetd: unknown authorization level for -a\n"); } break;#endif /* AUTHENTICATION */ case 'B': /* BFTP mode is not supported any more */ break; case 'd': if (strcmp(optarg, "ebug") == 0) { debug++; break; } usage(); /* NOTREACHED */ break;#ifdef DIAGNOSTICS case 'D': /* * Check for desired diagnostics capabilities. */ if (!strcmp(optarg, "report")) { diagnostic |= TD_REPORT|TD_OPTIONS; } else if (!strcmp(optarg, "exercise")) { diagnostic |= TD_EXERCISE; } else if (!strcmp(optarg, "netdata")) { diagnostic |= TD_NETDATA; } else if (!strcmp(optarg, "ptydata")) { diagnostic |= TD_PTYDATA; } else if (!strcmp(optarg, "options")) { diagnostic |= TD_OPTIONS; } else { usage(); /* NOT REACHED */ } break;#endif /* DIAGNOSTICS */ case 'g': gettyent = optarg; break; case 'h': hostinfo = 0; break; case 'k': /* Linemode is not supported any more */ case 'l': break; case 'n': keepalive = 0; break;#ifdef _CRAY case 'r': { char *strchr(); char *c; /* * Allow the specification of alterations * to the pty search range. It is legal to * specify only one, and not change the * other from its default. */ c = strchr(optarg, '-'); if (c) { *c++ = '\0'; highpty = atoi(c); } if (*optarg != '\0') lowpty = atoi(optarg); if ((lowpty > highpty) || (lowpty < 0) || (highpty > 32767)) { usage(); /* NOT REACHED */ } break; }#endif /* CRAY */ case 'S':#ifdef HAVE_PARSETOS if ((tos = parsetos(optarg, "tcp")) < 0) fprintf(stderr, "%s%s%s\n", "telnetd: Bad TOS argument '", optarg, "'; will try to use default TOS");#else fprintf(stderr, "%s%s\n", "TOS option unavailable; ", "-S flag not supported\n");#endif break; case 'u': { char *eptr; utmp_len = strtol(optarg, &eptr, 0); if (optarg == eptr) fprintf(stderr, "telnetd: unknown utmp len (%s)\n", optarg); break; } case 'U': registerd_host_only = 1; break;#ifdef AUTHENTICATION case 'X': /* * Check for invalid authentication types */ auth_disable_name(optarg); break;#endif case 'y': no_warn = 1; break;#ifdef AUTHENTICATION case 'z': log_unauth = 1; break;#endif /* AUTHENTICATION */ case 'L': new_login = optarg; break; default: fprintf(stderr, "telnetd: %c: unknown option\n", ch); /* FALLTHROUGH */ case '?': usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (debug) { int port = 0; struct servent *sp; if (argc > 1) { usage (); } else if (argc == 1) { sp = getservbyname (*argv, "tcp"); if (sp) port = sp->s_port; else port = htons(atoi(*argv)); } else { sp = getservbyname ("telnet", "tcp"); port = sp ? sp->s_port : htons(23); } mini_inetd (port); } else if (argc > 0) { usage(); /* NOT REACHED */ }#ifdef _SC_CRAY_SECURE_SYS secflag = sysconf(_SC_CRAY_SECURE_SYS); /* * Get socket's security label */ if (secflag) { socklen_t szss = sizeof(ss); int sock_multi; socklen_t szi = sizeof(int); memset(&dv, 0, sizeof(dv)); if (getsysv(&sysv, sizeof(struct sysv)) != 0) fatalperror(net, "getsysv"); /* * Get socket security label and set device values * {security label to be set on ttyp device} */#ifdef SO_SEC_MULTI /* 8.0 code */ if ((getsockopt(0, SOL_SOCKET, SO_SECURITY, (void *)&ss, &szss) < 0) || (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI, (void *)&sock_multi, &szi) < 0)) fatalperror(net, "getsockopt"); else { dv.dv_actlvl = ss.ss_actlabel.lt_level; dv.dv_actcmp = ss.ss_actlabel.lt_compart; if (!sock_multi) { dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl; dv.dv_valcmp = dv.dv_actcmp; } else { dv.dv_minlvl = ss.ss_minlabel.lt_level; dv.dv_maxlvl = ss.ss_maxlabel.lt_level; dv.dv_valcmp = ss.ss_maxlabel.lt_compart; } dv.dv_devflg = 0; }#else /* SO_SEC_MULTI */ /* 7.0 code */ if (getsockopt(0, SOL_SOCKET, SO_SECURITY, (void *)&ss, &szss) >= 0) { dv.dv_actlvl = ss.ss_slevel; dv.dv_actcmp = ss.ss_compart; dv.dv_minlvl = ss.ss_minlvl; dv.dv_maxlvl = ss.ss_maxlvl; dv.dv_valcmp = ss.ss_maxcmp; }#endif /* SO_SEC_MULTI */ }#endif /* _SC_CRAY_SECURE_SYS */ openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); sa_size = sizeof (__ss); if (getpeername(STDIN_FILENO, sa, &sa_size) < 0) { fprintf(stderr, "%s: ", progname); perror("getpeername"); _exit(1); } if (keepalive && setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof (on)) < 0) { syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); }#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT) {# ifdef HAVE_GETTOSBYNAME struct tosent *tp; if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) tos = tp->t_tos;# endif if (tos < 0) tos = 020; /* Low Delay bit */ if (tos && sa->sa_family == AF_INET && (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS, (void *)&tos, sizeof(tos)) < 0) && (errno != ENOPROTOOPT) ) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); }#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ net = STDIN_FILENO; doit(sa, sa_size); /* NOTREACHED */ return 0;} /* end of main */static voidusage(void){ fprintf(stderr, "Usage: telnetd");#ifdef AUTHENTICATION fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t");#endif fprintf(stderr, " [-debug]");#ifdef DIAGNOSTICS fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -