Example #1
0
int
main(int argc, char *argv[])
{
	struct sockaddr_in from;
	int on = 1;
	socklen_t fromlen;
#ifndef REALLY_SMALL_TELNETD
	register int ch;
#endif
	
#if	defined(IPPROTO_IP) && defined(IP_TOS)
	int tos = -1;
#endif

	pfrontp = pbackp = ptyobuf;
	netip = netibuf;
	nfrontp = nbackp = netobuf;
#if	defined(ENCRYPT)
	nclearto = 0;
#endif

	progname = *argv;

#ifdef CRAY
	/*
	 * Get number of pty's before trying to process options,
	 * which may include changing pty range.
	 */
	highpty = getnpty();
#endif /* CRAY */

#ifndef REALLY_SMALL_TELNETD
	while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:L:")) != EOF) {
		switch(ch) {

#ifdef	AUTHENTICATE
		case 'a':
			/*
			 * Check for required authentication level
			 */
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				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	/* AUTHENTICATE */

#ifdef BFTPDAEMON
		case 'B':
			bftpd++;
			break;
#endif /* BFTPDAEMON */

		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 */

#ifdef	AUTHENTICATE
		case 'e':
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				auth_debug_mode = 1;
				break;
			}
			usage();
			/* NOTREACHED */
			break;
#endif	/* AUTHENTICATE */

		case 'h':
			hostinfo = 0;
			break;

#if	defined(CRAY) && defined(NEWINIT)
		case 'I':
		    {
			extern char *gen_id;
			gen_id = optarg;
			break;
		    }
#endif	/* defined(CRAY) && defined(NEWINIT) */

#ifdef	LINEMODE
		case 'l':
			alwayslinemode = 1;
			break;
#endif	/* LINEMODE */

		case 'L':
			loginprg = optarg;
			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 */

#ifdef	SecurID
		case 's':
			/* SecurID required */
			require_SecurID = 1;
			break;
#endif	/* SecurID */
		case 'S':
#ifdef	HAS_GETTOS
			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;

#ifdef	AUTHENTICATE
		case 'X':
			/*
			 * Check for invalid authentication types
			 */
			auth_disable_name(optarg);
			break;
#endif	/* AUTHENTICATE */

		default:
			fprintf(stderr, "telnetd: %c: unknown option\n", ch);
			/* FALLTHROUGH */
		case '?':
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;
#endif

#ifndef REALLY_SMALL_TELNETD
	if (debug) {
	    int s, ns;
	    size_t foo;
	    struct servent *sp;
	    static struct sockaddr_in sn = { AF_INET };

	    if (argc > 1) {
		usage();
		/* NOT REACHED */
	    } else if (argc == 1) {
		    if ((sp = getservbyname(*argv, "tcp"))!=NULL) {
			sn.sin_port = sp->s_port;
		    } 
		    else {
			sn.sin_port = atoi(*argv);
			if ((int)sn.sin_port <= 0) {
			    fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
			    usage();
			    /* NOT REACHED */
			}
			sn.sin_port = htons((u_short)sn.sin_port);
		   }
	    } else {
		sp = getservbyname("telnet", "tcp");
		if (sp == 0) {
		    fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
		    exit(1);
		}
		sn.sin_port = sp->s_port;
	    }

	    s = socket(AF_INET, SOCK_STREAM, 0);
	    if (s < 0) {
		    perror("telnetd: socket");;
		    exit(1);
	    }
	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	    if (bind(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {
		perror("bind");
		exit(1);
	    }
	    if (listen(s, 1) < 0) {
		perror("listen");
		exit(1);
	    }
	    foo = sizeof(sn);
	    ns = accept(s, (struct sockaddr *)&sn, &foo);
	    if (ns < 0) {
		perror("accept");
		exit(1);
	    }
	    (void) dup2(ns, 0);
	    (void) close(ns);
	    (void) close(s);
#ifdef convex
	} else if (argc == 1) {
		; /* VOID*/		/* Just ignore the host/port name */
#endif
	} else if (argc > 0) {
		usage();
		/* NOT REACHED */
	}
#endif

#ifndef REALLY_SMALL_TELNETD
	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
#endif
	fromlen = sizeof (from);
	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
		fprintf(stderr, "%s: ", progname);
		perror("getpeername");
//		_exit(1);
	}
	if (keepalive &&
	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
		/*syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");*/
	}

#if	defined(IPPROTO_IP) && defined(IP_TOS)
	{
# if	defined(HAS_GETTOS)
		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
		   && (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
		   && (errno != ENOPROTOOPT) )
			/*syslog(LOG_WARNING, "setsockopt (IP_TOS): %m")*/;
	}
#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
	net = 0;
	doit(&from);
	/* NOTREACHED */
	return 0;
}  /* end of main */
Example #2
0
int
main(int argc, char *argv[])
{
	struct sockaddr_storage from;
	int on = 1, fromlen;
	int ch;
#if	defined(IPPROTO_IP) && defined(IP_TOS)
	int tos = -1;
#endif

	pfrontp = pbackp = ptyobuf;
	netip = netibuf;
	nfrontp = nbackp = netobuf;
#ifdef	ENCRYPTION
	nclearto = 0;
#endif	/* ENCRYPTION */

	/*
	 * This initialization causes linemode to default to a configuration
	 * that works on all telnet clients, including the FreeBSD client.
	 * This is not quite the same as the telnet client issuing a "mode
	 * character" command, but has most of the same benefits, and is
	 * preferable since some clients (like usofts) don't have the
	 * mode character command anyway and linemode breaks things.
	 * The most notable symptom of fix is that csh "set filec" operations
	 * like <ESC> (filename completion) and ^D (choices) keys now work
	 * in telnet sessions and can be used more than once on the same line.
	 * CR/LF handling is also corrected in some termio modes.  This 
	 * change resolves problem reports bin/771 and bin/1037.
	 */

	linemode=1;	/*Default to mode that works on bulk of clients*/

	while ((ch = getopt(argc, argv, valid_opts)) != -1) {
		switch(ch) {

#ifdef	AUTHENTICATION
		case 'a':
			/*
			 * Check for required authentication level
			 */
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				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 {
				warnx("unknown authorization level for -a");
			}
			break;
#endif	/* AUTHENTICATION */

#ifdef BFTPDAEMON
		case 'B':
			bftpd++;
			break;
#endif /* BFTPDAEMON */

		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 */

#ifdef	ENCRYPTION
		case 'e':
			if (strcmp(optarg, "debug") == 0) {
				extern int encrypt_debug_mode;
				encrypt_debug_mode = 1;
				break;
			}
			usage();
			/* NOTREACHED */
			break;
#endif	/* ENCRYPTION */

		case 'h':
			hostinfo = 0;
			break;

#ifdef	LINEMODE
		case 'l':
			alwayslinemode = 1;
			break;
#endif	/* LINEMODE */

		case 'k':
#if	defined(LINEMODE) && defined(KLUDGELINEMODE)
			lmodetype = NO_AUTOKLUDGE;
#else
			/* ignore -k option if built without kludge linemode */
#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
			break;

		case 'n':
			keepalive = 0;
			break;

		case 'p':
			altlogin = optarg;
			break;

		case 'S':
#ifdef	HAS_GETTOS
			if ((tos = parsetos(optarg, "tcp")) < 0)
				warnx("%s%s%s",
					"bad TOS argument '", optarg,
					"'; will try to use default TOS");
#else
			warnx("TOS option unavailable; -S flag not supported");
#endif
			break;

		case 'u':
			utmp_len = (size_t)atoi(optarg);
			if (utmp_len >= sizeof(remote_hostname))
				utmp_len = sizeof(remote_hostname) - 1;
			break;

		case 'U':
			registerd_host_only = 1;
			break;

#ifdef	AUTHENTICATION
		case 'X':
			/*
			 * Check for invalid authentication types
			 */
			auth_disable_name(optarg);
			break;
#endif	/* AUTHENTICATION */

		case '4':
			family = AF_INET;
			break;

#ifdef INET6
		case '6':
			family = AF_INET6;
			break;
#endif

		default:
			warnx("%c: unknown option", ch);
			/* FALLTHROUGH */
		case '?':
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;

	if (debug) {
	    int s, ns, foo, error;
	    const char *service = "telnet";
	    struct addrinfo hints, *res;

	    if (argc > 1) {
		usage();
		/* NOT REACHED */
	    } else if (argc == 1)
		service = *argv;

	    memset(&hints, 0, sizeof(hints));
	    hints.ai_flags = AI_PASSIVE;
	    hints.ai_family = family;
	    hints.ai_socktype = SOCK_STREAM;
	    hints.ai_protocol = 0;
	    error = getaddrinfo(NULL, service, &hints, &res);

	    if (error) {
		errx(1, "tcp/%s: %s\n", service, gai_strerror(error));
		if (error == EAI_SYSTEM)
		    errx(1, "tcp/%s: %s\n", service, strerror(errno));
		usage();
	    }

	    s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	    if (s < 0)
		    err(1, "socket");
	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
				(char *)&on, sizeof(on));
	    if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
		err(1, "bind");
	    if (listen(s, 1) < 0)
		err(1, "listen");
	    foo = res->ai_addrlen;
	    ns = accept(s, res->ai_addr, &foo);
	    if (ns < 0)
		err(1, "accept");
	    (void) dup2(ns, 0);
	    (void) close(ns);
	    (void) close(s);
#ifdef convex
	} else if (argc == 1) {
		; /* VOID*/		/* Just ignore the host/port name */
#endif
	} else if (argc > 0) {
		usage();
		/* NOT REACHED */
	}

	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
	fromlen = sizeof (from);
	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
		warn("getpeername");
		_exit(1);
	}
	if (keepalive &&
	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
			(char *)&on, sizeof (on)) < 0) {
		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
	}

#if	defined(IPPROTO_IP) && defined(IP_TOS)
	if (from.ss_family == AF_INET) {
# if	defined(HAS_GETTOS)
		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
		   && (setsockopt(0, IPPROTO_IP, IP_TOS,
				  (char *)&tos, sizeof(tos)) < 0)
		   && (errno != ENOPROTOOPT) )
			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
	}
#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
	net = 0;
	doit((struct sockaddr *)&from);
	/* NOTREACHED */
	return(0);
}  /* end of main */
Example #3
0
int
main(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 __attribute__ ((unused)) = -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, "otp") == 0) {
		auth_level = 0;
		require_otp = 1;
	    } 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;

#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 '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 (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("ddtelnetd", LOG_PID | LOG_ODELAY, LOG_LOCAL2);
    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 */
Example #4
0
int
main (int argc, char *argv[], char *env[])
{
  struct sockaddr_storage from;
  int on = 1, fromlen;
  register int ch;
#if defined(IPPROTO_IP) && defined(IP_TOS)
  int tos = -1;
#endif

  initsetproctitle(argc, argv, env);

  pfrontp = pbackp = ptyobuf;
  netip = netibuf;
  nfrontp = nbackp = netobuf;

  progname = *argv;

  while ((ch = getopt(argc, argv, valid_opts)) != EOF)
    {
      switch (ch)
	{
	case 'd':
	  if (strcmp(optarg, "ebug") == 0)
	    {
	      debug++;
	      break;
	    }
	  usage();
	  /* NOTREACHED */
	  break;
	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;
	case 'g':
	  gettyname = optarg;
	  break;

	case 'h':
	  hostinfo = 0;
	  break;

#ifdef	LINEMODE
	case 'l':
	  alwayslinemode = 1;
	  break;
#endif	/* LINEMODE */

	case 'L':
	  loginprg = strdup (optarg);
	  break;

#if defined(LINEMODE) && defined(KLUDGELINEMODE)
	case 'k':
	  lmodetype = NO_AUTOKLUDGE;
	  break;
#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */

	case 'n':
	  keepalive = 0;
	  break;

	case 'S':
#ifdef	HAS_GETTOS
	  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':
	  utmp_len = atoi(optarg);
	  break;

	case 'U':
	  registerd_host_only = 1;
	  break;
	case '4':
	  family = AF_INET;
	  break;
	case '6':
	  family = AF_INET6;
	  break;

	default:
	  fprintf(stderr, "telnetd: %c: unknown option\n", ch);
	  /* FALLTHROUGH */
	case '?':
	  usage();
	  /* NOTREACHED */
	}
    }

  argc -= optind;
  argv += optind;

  if (debug)
    {
      int s, ns, foo, error;
      char *service = "telnet";
      struct addrinfo hints, *res;

      if (argc > 1)
	{
	  usage();
	  /* NOT REACHED */
	}
      else if (argc == 1)
	service = *argv;

      memset(&hints, 0, sizeof(hints));
      hints.ai_flags = AI_PASSIVE;
      hints.ai_family = family;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = 0;
      error = getaddrinfo(NULL, service, &hints, &res);

      if (error)
	{
	  fprintf(stderr, "tcp/%s: %s\n", service, gai_strerror(error));
	  exit(1);
	}

      s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
      if (s < 0)
	{
	  perror("telnetd: socket");
	  exit(1);
	}
      setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
      if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
	{
	  perror ("bind");
	  exit (1);
	}
      if (listen (s, 1) < 0)
	{
	  perror ("listen");
	  exit (1);
	}
      foo = res->ai_addrlen;
      ns = accept(s, res->ai_addr, &foo);
      if (ns < 0)
	{
	  perror("accept");
	  exit(1);
	}
      dup2(ns, 0);
      close(ns);
      close(s);
    }
  else if (argc > 0)
    {
      usage();
      /* NOT REACHED */
    }

  openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
  fromlen = sizeof (from);
  if (getpeername (0, (struct sockaddr *)&from, &fromlen) < 0)
    {
      fprintf(stderr, "%s: ", progname);
      perror("getpeername");
      _exit(1);
    }
  if (keepalive &&
      setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof (on)) < 0)
    syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");

#if	defined(IPPROTO_IP) && defined(IP_TOS)
  if (from.ss_family == AF_INET) {
# if	defined(HAS_GETTOS)
    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
	&& (setsockopt(0, IPPROTO_IP, IP_TOS,
		       (char *)&tos, sizeof(tos)) < 0)
	&& (errno != ENOPROTOOPT) )
      syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
  }
#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */
  net = 0;
  doit((struct sockaddr *)&from);
  /* NOTREACHED */
  return 0;
}  /* end of main */
Example #5
0
int
main(int argc, char *argv[], char *env[])
{
	struct sockaddr_in from;
	int on = 1;
	socklen_t fromlen;
	register int ch;

#if	defined(HAS_IPPROTO_IP) && defined(IP_TOS)
	int tos = -1;
#endif

	initsetproctitle(argc, argv, env);

	pfrontp = pbackp = ptyobuf;
	netip = netibuf;
	nfrontp = nbackp = netobuf;
#if	defined(ENCRYPT)
	nclearto = 0;
#endif

	progname = *argv;

	while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:L:")) != EOF) {
		switch(ch) {

#ifdef	AUTHENTICATE
		case 'a':
			/*
			 * Check for required authentication level
			 */
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				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	/* AUTHENTICATE */

#ifdef BFTPDAEMON
		case 'B':
			bftpd++;
			break;
#endif /* BFTPDAEMON */

		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 */

#ifdef	AUTHENTICATE
		case 'e':
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				auth_debug_mode = 1;
				break;
			}
			usage();
			/* NOTREACHED */
			break;
#endif	/* AUTHENTICATE */

		case 'h':
			hostinfo = 0;
			break;

#ifdef	LINEMODE
		case 'l':
			alwayslinemode = 1;
			break;
#endif	/* LINEMODE */

		case 'L':
			loginprg = strdup(optarg);
			/* XXX what if strdup fails? */
			break;

		case 'n':
			keepalive = 0;
			break;

#ifdef	SecurID
		case 's':
			/* SecurID required */
			require_SecurID = 1;
			break;
#endif	/* SecurID */
		case 'S':
#ifdef	HAS_GETTOS
			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;

#ifdef	AUTHENTICATE
		case 'X':
			/*
			 * Check for invalid authentication types
			 */
			auth_disable_name(optarg);
			break;
#endif	/* AUTHENTICATE */

		default:
			fprintf(stderr, "telnetd: %c: unknown option\n", ch);
			/* FALLTHROUGH */
		case '?':
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;

	if (debug) {
	    int s, ns;
	    socklen_t foo;
	    struct servent *sp;
	    struct sockaddr_in sn;

	    memset(&sn, 0, sizeof(sn));
	    sn.sin_family = AF_INET;

	    if (argc > 1) {
		usage();
		/* NOTREACHED */
	    } else if (argc == 1) {
		    if ((sp = getservbyname(*argv, "tcp"))!=NULL) {
			sn.sin_port = sp->s_port;
		    } 
		    else {
			int pt = atoi(*argv);
			if (pt <= 0) {
			    fprintf(stderr, "telnetd: %s: bad port number\n",
				    *argv);
			    usage();
			    /* NOTREACHED */
			}
			sn.sin_port = htons(pt);
		   }
	    } else {
		sp = getservbyname("telnet", "tcp");
		if (sp == 0) {
		    fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
		    exit(1);
		}
		sn.sin_port = sp->s_port;
	    }

	    s = socket(AF_INET, SOCK_STREAM, 0);
	    if (s < 0) {
		    perror("telnetd: socket");;
		    exit(1);
	    }
	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	    if (bind(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {
		perror("bind");
		exit(1);
	    }
	    if (listen(s, 1) < 0) {
		perror("listen");
		exit(1);
	    }
	    foo = sizeof(sn);
	    ns = accept(s, (struct sockaddr *)&sn, &foo);
	    if (ns < 0) {
		perror("accept");
		exit(1);
	    }
	    (void) dup2(ns, 0);
	    (void) close(ns);
	    (void) close(s);
	} else if (argc > 0) {
		usage();
		/* NOT REACHED */
	}

	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
	fromlen = sizeof (from);
	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
		fprintf(stderr, "%s: ", progname);
		perror("getpeername");
		_exit(1);
	}
	if (keepalive &&
	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
	}

#if	defined(HAS_IPPROTO_IP) && defined(IP_TOS)
	{
# if	defined(HAS_GETTOS)
		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
		   && (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
		   && (errno != ENOPROTOOPT) )
			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
	}
#endif	/* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */
	net = 0;
	doit(&from);
	/* NOTREACHED */
	return 0;
}  /* end of main */
Example #6
0
int
main(int argc, char *argv[], char *env[])
{
	struct sockaddr_storage from;
	int on = 1;
	socklen_t fromlen;
	register int ch;
	int i;

#if	defined(HAS_IPPROTO_IP) && defined(IP_TOS)
	int tos = -1;
#endif

	initsetproctitle(argc, argv, env);

	pfrontp = pbackp = ptyobuf;
	netip = netibuf;

#ifdef USE_SSL
	/* we need to know the fullpath to the location of the
	 * certificate that we will be running with as we cannot
	 * be sure of the cwd when we are launched
	 */
	sprintf(cert_filepath,"%s/%s",X509_get_default_cert_dir(),
	        "telnetd.pem");
	ssl_cert_file=cert_filepath;
	ssl_key_file=NULL;
#endif /* USE_SSL */

	while ((ch = getopt(argc, argv, "d:a:e:lhnNr:I:D:B:sS:a:X:L:z:")) != EOF) {
		switch(ch) {

#ifdef USE_SSL
                case 'z':
		        { 
			char *origopt;

			origopt=strdup(optarg);
			optarg=strtok(origopt,",");

			while(optarg!=NULL) {

		        if (strcmp(optarg, "debug") == 0 ) {
			    ssl_debug_flag=1;
			} else if (strcmp(optarg, "ssl") == 0 ) {
			    ssl_only_flag=1;
			} else if (strcmp(optarg, "certsok") == 0 ) {
			    ssl_certsok_flag=1;
			} else if ( (strcmp(optarg, "!ssl") == 0) ||
		             (strcmp(optarg, "nossl") == 0) ) {
			    /* we may want to switch SSL negotiation off
			     * for testing or other reasons 
			     */
			    ssl_disabled_flag=1;
			} else if (strcmp(optarg, "certrequired") == 0 ) {
			    ssl_cert_required=1;
			} else if (strcmp(optarg, "secure") == 0 ) {
			    ssl_secure_flag=1;
			} else if (strncmp(optarg, "verify=", 
			                strlen("verify=")) == 0 ) {
			    ssl_verify_flag=atoi(optarg+strlen("verify="));
			} else if (strncmp(optarg, "cert=", 
			                strlen("cert=")) == 0 ) {
			    ssl_cert_file=optarg+strlen("cert=");
			} else if (strncmp(optarg, "key=", 
			                strlen("key=")) == 0 ) {
			    ssl_key_file=optarg+strlen("key=");
			} else if (strncmp(optarg,"cipher=",
			                strlen("cipher="))==0) {
			    ssl_cipher_list=optarg+strlen("cipher=");
			} else {
			    /* report when we are given rubbish so that
			     * if the user makes a mistake they have to
			     * correct it!
			     */
			    fprintf(stderr,"Unknown SSL option %s\n",optarg);
			    fflush(stderr);
			    exit(1);
			}

			/* get the next one ... */
                        optarg=strtok(NULL,",");

			}

			/*
			if (origopt!=NULL)
			    free(origopt);
			*/

			}
			break;
#endif /* USE_SSL */

#ifdef	AUTHENTICATE
		case 'a':
			/*
			 * Check for required authentication level
			 */
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				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	/* AUTHENTICATE */

#ifdef BFTPDAEMON
		case 'B':
			bftpd++;
			break;
#endif /* BFTPDAEMON */

		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 */

#ifdef	AUTHENTICATE
		case 'e':
			if (strcmp(optarg, "debug") == 0) {
				extern int auth_debug_mode;
				auth_debug_mode = 1;
				break;
			}
			usage();
			/* NOTREACHED */
			break;
#endif	/* AUTHENTICATE */

		case 'h':
			hostinfo = 0;
			break;

#ifdef	LINEMODE
		case 'l':
			alwayslinemode = 1;
			break;
#endif	/* LINEMODE */

		case 'L':
			loginprg = strdup(optarg);
			/* XXX what if strdup fails? */
			break;

		case 'n':
			keepalive = 0;
			break;

		case 'N':
		  numeric_hosts = 1;
		  break;

#ifdef	SecurID
		case 's':
			/* SecurID required */
			require_SecurID = 1;
			break;
#endif	/* SecurID */
		case 'S':
#ifdef	HAS_GETTOS
			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;

#ifdef	AUTHENTICATE
		case 'X':
			/*
			 * Check for invalid authentication types
			 */
			auth_disable_name(optarg);
			break;
#endif	/* AUTHENTICATE */

		default:
			fprintf(stderr, "telnetd: %c: unknown option\n", ch);
			/* FALLTHROUGH */
		case '?':
			usage();
			/* NOTREACHED */
		}
	}

#ifdef USE_SSL

        if (ssl_secure_flag || ssl_cert_required || ssl_certsok_flag) {
	    /* in secure mode we *must* switch on the base level
	     * verify checking otherwise we cannot abort connections
	     * at the right place!
	     */
	    if (ssl_verify_flag==0)
		ssl_verify_flag=1;
	}

	/* if we are not running in debug then any error
	 * stuff from SSL debug *must* not go down
	 * the socket (which 0,1,2 are all pointing to by
	 * default)
	 */
	if (ssl_debug_flag)
	    ssl_log_file="/telnetd.log";

	if (!do_ssleay_init(1)) {
	  if (bio_err!=NULL) {
	    BIO_printf(bio_err,"do_ssleay_init() failed\n");
	    ERR_print_errors(bio_err);
	  } else {
	    fflush(stderr);
	    fprintf(stderr,"do_ssleay_init() failed\n");
	    ERR_print_errors_fp(stderr);
	  }
	  exit(1);
	}

	if (ssl_debug_flag) {
	  BIO_printf(bio_err,"secure %d certrequired %d verify %d\n",
	      ssl_secure_flag,ssl_cert_required,ssl_verify_flag);
	  for(i=0;i<argc;i++)
	      BIO_printf(bio_err,"argv[%d]=\"%s\"\n",i,argv[i]);
	}

#endif /* USE_SSL */

	argc -= optind;
	argv += optind;

	if (debug) {
		if (argc > 1) {
			usage();
			/* NOTREACHED */
		}

		wait_for_connection((argc == 1) ? *argv : "telnet");
	}

	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
	fromlen = sizeof (from);
	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
		fatalperror(2, "getpeername");
	}
	if (keepalive &&
	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
	}

#if	defined(HAS_IPPROTO_IP) && defined(IP_TOS)
	{
# if	defined(HAS_GETTOS)
		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
		   && (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
		   && (errno != ENOPROTOOPT) )
			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
	}
#endif	/* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */

#ifdef USE_SSL
        /* do the SSL stuff now ... before we play with pty's */
	SSL_set_fd(ssl_con,0);

	if (ssl_only_flag) {
	    /* hmm ... only when running talking to things like
	     * https servers should we hit this code and then
	     * we really don't care *who* we talk to :-)
	     */
	    SSL_set_verify(ssl_con,ssl_verify_flag,NULL);

	    if (SSL_accept(ssl_con) <= 0) {
		static char errbuf[1024];
	    
	        sprintf(errbuf,"SSL_accept error %s\n",
		    ERR_error_string(ERR_get_error(),NULL));

		syslog(LOG_WARNING, "%s", errbuf);

		BIO_printf(bio_err,"%s",errbuf);

		/* go to sleep to make sure we are noticed */
		sleep(10);
		SSL_free(ssl_con);

		_exit(1);
	    } else {
		ssl_active_flag=1;
	    }
	}
#endif /* USE_SSL */

	net = 0;
	netopen();
	doit((struct sockaddr *)&from, fromlen);
	/* NOTREACHED */
	return 0;
}  /* end of main */