summaryrefslogtreecommitdiff
path: root/net/SSLtelnet
diff options
context:
space:
mode:
authorKris Kennaway <kris@FreeBSD.org>2002-10-19 10:27:25 +0000
committerKris Kennaway <kris@FreeBSD.org>2002-10-19 10:27:25 +0000
commit15a79b97ac258fdb0b7309d00ef5bffcf8ac2f4b (patch)
tree5ba15972212caa0369ff0205d7dd28ddf944be9d /net/SSLtelnet
parentDon't (badly) rewrite CFLAGS, assume the user knows what he/she is doing. (diff)
Re-add SSLtelnet, with patch (patch-an) to fix the security vulnerability
described in FreeBSD-SA-01:49.telnetd Submitted by: kondo hiroshi <kondo@ysyslab.co.jp> PR: ports/42676
Notes
Notes: svn path=/head/; revision=68324
Diffstat (limited to 'net/SSLtelnet')
-rw-r--r--net/SSLtelnet/Makefile32
-rw-r--r--net/SSLtelnet/distinfo1
-rw-r--r--net/SSLtelnet/files/Makefile.patch11
-rw-r--r--net/SSLtelnet/files/patch-aa64
-rw-r--r--net/SSLtelnet/files/patch-ab11
-rw-r--r--net/SSLtelnet/files/patch-ac14
-rw-r--r--net/SSLtelnet/files/patch-ad10
-rw-r--r--net/SSLtelnet/files/patch-ae11
-rw-r--r--net/SSLtelnet/files/patch-af79
-rw-r--r--net/SSLtelnet/files/patch-ag46
-rw-r--r--net/SSLtelnet/files/patch-ah24
-rw-r--r--net/SSLtelnet/files/patch-ai24
-rw-r--r--net/SSLtelnet/files/patch-aj13
-rw-r--r--net/SSLtelnet/files/patch-ak10
-rw-r--r--net/SSLtelnet/files/patch-al26
-rw-r--r--net/SSLtelnet/files/patch-am43
-rw-r--r--net/SSLtelnet/files/patch-an1320
-rw-r--r--net/SSLtelnet/pkg-comment1
-rw-r--r--net/SSLtelnet/pkg-descr20
-rw-r--r--net/SSLtelnet/pkg-plist4
20 files changed, 1764 insertions, 0 deletions
diff --git a/net/SSLtelnet/Makefile b/net/SSLtelnet/Makefile
new file mode 100644
index 000000000000..248f95f2594f
--- /dev/null
+++ b/net/SSLtelnet/Makefile
@@ -0,0 +1,32 @@
+# New ports collection makefile for: SSLtelnet
+# Date created: Mar 29, 1998
+# Whom: issei@jp.FreeBSD.org
+#
+# $FreeBSD$
+
+PORTNAME= SSLtelnet
+PORTVERSION= 0.13
+CATEGORIES= net security
+MASTER_SITES= ${MASTER_SITE_LOCAL} \
+ ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/
+MASTER_SITE_SUBDIR= kris
+
+MAINTAINER= ports@FreeBSD.org
+
+USE_OPENSSL= YES
+
+PLIST_SUB+= OPENSSLDIR="${OPENSSLDIR}"
+
+.if !defined(BATCH)
+INSTALL_TARGET= install certificate
+.endif
+
+# Make sure that whole directory tree exists.
+pre-install:
+ ${MKDIR} ${OPENSSLDIR}/certs
+
+post-install:
+ strip $(PREFIX)/bin/telnet
+ strip $(PREFIX)/libexec/telnetd
+
+.include <bsd.port.mk>
diff --git a/net/SSLtelnet/distinfo b/net/SSLtelnet/distinfo
new file mode 100644
index 000000000000..e8ba32132f21
--- /dev/null
+++ b/net/SSLtelnet/distinfo
@@ -0,0 +1 @@
+MD5 (SSLtelnet-0.13.tar.gz) = 51025a9aaceaa2581377f7be7e0d913e
diff --git a/net/SSLtelnet/files/Makefile.patch b/net/SSLtelnet/files/Makefile.patch
new file mode 100644
index 000000000000..173a0d76f97d
--- /dev/null
+++ b/net/SSLtelnet/files/Makefile.patch
@@ -0,0 +1,11 @@
+--- Makefile.orig Thu Aug 5 09:03:59 1999
++++ Makefile Thu Aug 5 09:05:32 1999
+@@ -98,7 +98,7 @@
+
+ #BSD386
+ CC += -DTERMCAP $(socksflags)
+-LDADD = -ltermcap $(sockslib)
++LDADD = -L$(SSLTOP)/lib -lssl -lcrypto -lRSAglue -lrsaref -ltermcap $(sockslib)
+
+ all:
+ @-mkdir bin 2>/dev/null
diff --git a/net/SSLtelnet/files/patch-aa b/net/SSLtelnet/files/patch-aa
new file mode 100644
index 000000000000..1aac4699add4
--- /dev/null
+++ b/net/SSLtelnet/files/patch-aa
@@ -0,0 +1,64 @@
+--- Makefile.orig Thu Sep 24 17:50:59 1998
++++ Makefile Tue Feb 1 11:11:24 2000
+@@ -47,7 +47,7 @@
+
+ # the location where SSLeay is installed ...
+ # - expect a include and lib directory under here
+-SSLTOP=/usr/local/ssl
++SSLTOP=$(PREFIX)
+
+ INSTALLTOP=$(SSLTOP)
+
+@@ -83,8 +83,8 @@
+ #LDADD=$(sockslib) -ltermcap -lcurses
+
+ # uncomment the next two lines for linux
+-CC = gcc -DLINUX -DTERMIOS $(socksflags)
+-LDADD = $(sockslib) -lbsd -lncurses
++#CC = gcc -DLINUX -DTERMIOS $(socksflags)
++#LDADD = $(sockslib) -lbsd -lncurses
+
+ ##OLD Linux stuff
+ #CC = gcc -DLINUX -DUSE_SHADOW $(socksflags)
+@@ -95,6 +95,11 @@
+ #BSD386
+ #CC = gcc -DBSD386 -DTERMCAP $(socksflags)
+ #LDADD = -ltermcap $(sockslib)
++
++#FreeBSD
++CC += -DTERMCAP $(socksflags)
++LDADD = -L$(OPENSSLLIB) -lssl -lcrypto $(EXTRA_SSL_LIBS) \
++ -ltermcap $(sockslib)
+
+ all:
+ @-mkdir bin 2>/dev/null
+@@ -145,12 +150,11 @@
+ tar: clean
+ (cd ..; tar cf $(TARFILE) $(DIRECTORY); /bin/rm -f $(TARFILE).Z $(TARFILE).gz >/dev/null 2>&1 ; $(COMPRESS) $(TARFILE) )
+
+-install: telnet telnetd /dev/null
+- @-mkdir -p $(INSTALLTOP)/bin 2>/dev/null
++install: telnet telnetd
+ cp bin/telnet $(INSTALLTOP)/bin/telnet
+ chmod 755 $(INSTALLTOP)/bin/telnet
+- cp bin/telnetd $(INSTALLTOP)/bin/telnetd
+- chmod 755 $(INSTALLTOP)/bin/telnetd
++ cp bin/telnetd $(INSTALLTOP)/libexec/telnetd
++ chmod 755 $(INSTALLTOP)/libexec/telnetd
+ @echo "*****************************************************"
+ @echo "* Do not forget to make the certificate for telnetd *"
+ @echo "* either manually or via \"make certificate\" *"
+@@ -158,9 +162,10 @@
+
+ certificate:
+ (\
+- cd $(INSTALLTOP)/certs; \
+- ssleay req -new -x509 -nodes -days 365 -out telnetd.pem -keyout telnetd.pem; \
+- ln -s telnetd.pem `ssleay x509 -noout -hash < telnetd.pem`.0 ;\
+- chmod 600 $(INSTALLTOP)/certs/telnetd.pem; \
++ [ -f $(OPENSSLDIR)/certs/telnetd.pem ] && exit; \
++ cd $(OPENSSLDIR)/certs; \
++ openssl req -new -x509 -nodes -days 365 -out telnetd.pem -keyout telnetd.pem; \
++ ln -s telnetd.pem `openssl x509 -noout -hash < telnetd.pem`.0 ;\
++ chmod 600 $(OPENSSLDIR)/certs/telnetd.pem; \
+ )
diff --git a/net/SSLtelnet/files/patch-ab b/net/SSLtelnet/files/patch-ab
new file mode 100644
index 000000000000..8dc321e8b2f7
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ab
@@ -0,0 +1,11 @@
+--- telnetd/pathnames.h.orig Sat Jun 15 17:26:10 1996
++++ telnetd/pathnames.h Sat Oct 17 22:11:51 1998
+@@ -53,7 +53,7 @@
+ /* I'm working on having this work as is with SunOS 5.x */
+ #ifndef USE_SRALOGIN
+ #undef _PATH_LOGIN
+-#ifdef __bsdi__
++#if defined(__bsdi__) || defined(__FreeBSD__)
+ #define _PATH_LOGIN "/usr/bin/login"
+ #else
+ #define _PATH_LOGIN "/bin/login"
diff --git a/net/SSLtelnet/files/patch-ac b/net/SSLtelnet/files/patch-ac
new file mode 100644
index 000000000000..a18ec3842bc2
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ac
@@ -0,0 +1,14 @@
+--- telnet/sys_bsd.c.orig Sat Aug 2 14:18:09 1997
++++ telnet/sys_bsd.c Fri Oct 16 20:43:32 1998
+@@ -580,10 +580,7 @@
+ else
+ lmode &= ~LPASS8;
+ #else
+- if (f & MODE_INBIN)
+- tmp_tc.c_iflag &= ~ISTRIP;
+- else
+- tmp_tc.c_iflag |= ISTRIP;
++ tmp_tc.c_iflag &= ~ISTRIP;
+ if (f & MODE_OUTBIN) {
+ tmp_tc.c_cflag &= ~(CSIZE|PARENB);
+ tmp_tc.c_cflag |= CS8;
diff --git a/net/SSLtelnet/files/patch-ad b/net/SSLtelnet/files/patch-ad
new file mode 100644
index 000000000000..09ee0ce1b39d
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ad
@@ -0,0 +1,10 @@
+--- lib/libtelnet/sslapp.h.orig Fri Oct 16 21:14:59 1998
++++ lib/libtelnet/sslapp.h Fri Oct 16 21:15:07 1998
+@@ -53,6 +53,7 @@
+ extern int ssl_disabled_flag;
+ extern int ssl_cert_required;
+ extern int ssl_certsok_flag;
++extern int ssl_quiet_flag;
+
+ extern char *ssl_log_file;
+ extern char *ssl_cert_file;
diff --git a/net/SSLtelnet/files/patch-ae b/net/SSLtelnet/files/patch-ae
new file mode 100644
index 000000000000..c44e222bd4eb
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ae
@@ -0,0 +1,11 @@
+--- lib/Makefile.orig Wed Sep 2 13:11:39 1998
++++ lib/Makefile Wed Sep 2 13:11:49 1998
+@@ -1,7 +1,7 @@
+ #SUBDIRS= gmp-1.2 kerberosIV/krb libbsd libdes/des libpk libtelnet libutil
+ SUBDIRS= gmp-1.3.2 libbsd libpk libtelnet libutil
+
+-SUBDIRS= libbsd libtelnet libutil
++SUBDIRS= libtelnet
+
+ all:
+ @for i in $(SUBDIRS); \
diff --git a/net/SSLtelnet/files/patch-af b/net/SSLtelnet/files/patch-af
new file mode 100644
index 000000000000..0540f99f62cf
--- /dev/null
+++ b/net/SSLtelnet/files/patch-af
@@ -0,0 +1,79 @@
+--- telnetd/sys_term.c.orig Sat Aug 2 01:37:00 1997
++++ telnetd/sys_term.c Sun Aug 6 16:15:37 2000
+@@ -167,7 +167,7 @@
+ struct termios termbuf, termbuf2; /* pty control structure */
+ #endif /* USE_TERMIO */
+
+-extern long time();
++extern time_t time();
+
+ #ifndef STDIN_FILENO
+ #define STDIN_FILENO fileno(stdin)
+@@ -531,7 +531,7 @@
+ return(p);
+ #else
+
+- register char c, *p1, *p2;
++ register char c, *p1, *p2, *cp;
+ register int i;
+
+ #if defined(__GNUC__) || defined(__sgi)
+@@ -548,20 +548,40 @@
+ p1 = &line[8];
+ p2 = &line[9];
+ #endif
+-
+- for (c = 'p'; c <= 's'; c++) {
++ for (cp = "pqrsPQRS"; *cp; cp++) {
+ struct stat stb;
+
+- *p1 = c;
++ *p1 = *cp;
+ *p2 = '0';
++ /*
++ * This stat() check is just to keep us from
++ * looping through all 256 combinations if there
++ * aren't that many ptys available.
++ */
+ if (stat(line, &stb) < 0)
+ break;
+- for (i = 0; i < 16; i++) {
+- *p2 = "0123456789abcdef"[i];
++ for (i = 0; i < 32; i++) {
++ *p2 = "0123456789abcdefghijklmnopqrstuv"[i];
+ p = open(line, 2);
+ if (p > 0) {
++#ifndef __hpux
+ line[5] = 't';
+- return(p);
++#else
++ for (p1 = &line[8]; *p1; p1++)
++ *p1 = *(p1+1);
++ line[9] = 't';
++#endif
++ chown(line, 0, 0);
++ chmod(line, 0600);
++#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207
++ if (ioctl(p, TIOCGPGRP, &dummy) == 0
++ || errno != EIO) {
++ chmod(line, 0666);
++ close(p);
++ line[5] = 'p';
++ } else
++#endif /* defined(sun) && defined(TIOCGPGRP) && BSD < 199207 */
++ return(p);
+ }
+ }
+ }
+@@ -733,11 +753,7 @@
+ else
+ termbuf.lflags &= ~LPASS8;
+ #else
+- if (on) {
+- termbuf.c_iflag &= ~ISTRIP;
+- } else {
+- termbuf.c_iflag |= ISTRIP;
+- }
++ termbuf.c_iflag &= ~ISTRIP;
+ #endif
+ }
diff --git a/net/SSLtelnet/files/patch-ag b/net/SSLtelnet/files/patch-ag
new file mode 100644
index 000000000000..8afb82138f54
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ag
@@ -0,0 +1,46 @@
+--- telnetd/telnetd.c.orig Sat Aug 2 14:40:48 1997
++++ telnetd/telnetd.c Sat Oct 17 22:13:52 1998
+@@ -140,7 +140,7 @@
+ highpty = getnpty();
+ #endif /* CRAY */
+
+- while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:z:")) != EOF) {
++ while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:z:q")) != EOF) {
+ switch(ch) {
+
+ #ifdef USE_SSL
+@@ -203,6 +203,11 @@
+
+ }
+ break;
++
++ case 'q':
++ ssl_quiet_flag = 1;
++ break;
++
+ #endif /* USE_SSL */
+
+ #ifdef AUTHENTICATE
+@@ -584,7 +589,7 @@
+ #ifdef USE_SSL
+ /* might as well output something useful here ... */
+ fprintf(stderr, " [-z ssl] [-z secure] [-z debug] [-z verify=int]\n\t");
+- fprintf(stderr, " [-z cert=file] [-z key=file]\n\t");
++ fprintf(stderr, " [-z cert=file] [-z key=file] [-q]\n\t");
+ #endif /* USE_SSL */
+ fprintf(stderr, " [port]\n");
+ exit(1);
+@@ -656,7 +661,12 @@
+ fflush(stderr);
+ }
+
+- fatal(net,"[SSL required - connection rejected]");
++ if (ssl_quiet_flag) {
++ sleep(1);
++ exit(1);
++ }
++ else
++ fatal(net,"[SSL required - connection rejected]");
+
+ }
+ }
diff --git a/net/SSLtelnet/files/patch-ah b/net/SSLtelnet/files/patch-ah
new file mode 100644
index 000000000000..a67443989de8
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ah
@@ -0,0 +1,24 @@
+--- telnetd/Makefile.orig Mon Sep 11 22:22:51 1995
++++ telnetd/Makefile Tue Feb 1 09:20:28 2000
+@@ -4,17 +4,11 @@
+
+ PROG= telnetd
+
+-CFLAGS= -DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DAUTHENTICATE -DUSE_SSL \
+- -DDIAGNOSTICS -DFILIO_H \
+- -I../lib -I../lib/libbsd/include \
+- -I$(SSLTOP)/include
++CFLAGS+= -DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DAUTHENTICATE -DUSE_SSL \
++ -DDIAGNOSTICS -DFILIO_H -I../lib -I../lib/libbsd/include \
++ -I$(OPENSSLINC)/openssl -I$(OPENSSLINC)
+
+-LIBS= ../lib/libtelnet/libtelnet.a \
+- ../lib/libbsd/libbsd.a \
+- ../lib/libutil/libutil.a \
+- $(SSLTOP)/lib/libssl.a \
+- $(SSLTOP)/lib/libcrypto.a
+-# $(SSLTOP)/lib/libdes.a
++LIBS= ../lib/libtelnet/libtelnet.a -lutil
+
+ OBJS= authenc.o global.o slc.o state.o sys_term.o telnetd.o \
+ termstat.o utility.o
diff --git a/net/SSLtelnet/files/patch-ai b/net/SSLtelnet/files/patch-ai
new file mode 100644
index 000000000000..812ce63d3383
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ai
@@ -0,0 +1,24 @@
+--- telnet/Makefile.orig Sat Aug 2 01:30:16 1997
++++ telnet/Makefile Sun Feb 20 17:28:27 2000
+@@ -6,17 +6,12 @@
+ PROG= telnet
+
+
+-CFLAGS= -DKLUDGELINEMODE -DUSE_TERMIO -DAUTHENTICATE -DUSE_SSL \
+- -DFILIO_H \
+- -I../lib/libbsd/include -I../lib \
+- -I$(SSLTOP)/include
++CFLAGS+= -DKLUDGELINEMODE -DUSE_TERMIO -DAUTHENTICATE -DUSE_SSL \
++ -DFILIO_H -I../lib -I../lib/libbsd/include -I$(OPENSSLINC)/openssl \
++ -I$(OPENSSLINC)
+
+
+-LIBS= ../lib/libtelnet/libtelnet.a \
+- ../lib/libbsd/libbsd.a \
+- $(SSLTOP)/lib/libssl.a \
+- $(SSLTOP)/lib/libcrypto.a
+-# $(SSLTOP)/lib/libdes.a
++LIBS= ../lib/libtelnet/libtelnet.a
+
+ OBJS= authenc.o commands.o main.o network.o ring.o sys_bsd.o telnet.o \
+ terminal.o tn3270.o utilities.o
diff --git a/net/SSLtelnet/files/patch-aj b/net/SSLtelnet/files/patch-aj
new file mode 100644
index 000000000000..f559ddc6abcd
--- /dev/null
+++ b/net/SSLtelnet/files/patch-aj
@@ -0,0 +1,13 @@
+--- lib/libtelnet/Makefile.orig Sat Aug 2 01:31:37 1997
++++ lib/libtelnet/Makefile Sun Feb 20 17:31:46 2000
+@@ -12,8 +12,8 @@
+ #CFLAGS= -DENCRYPT -DAUTHENTICATE -DSRA -DUSE_SSL -DDES_ENCRYPTION \
+ #-I../libbsd/include -I../libpk
+
+-CFLAGS= -DAUTHENTICATE -DUSE_SSL \
+--I../libbsd/include -I$(SSLTOP)/include -I../libpk -g
++CFLAGS+= -DAUTHENTICATE -DUSE_SSL -I$(OPENSSLINC)/openssl -I../libbsd/include \
++ -I$(OPENSSLINC)
+
+ lib${LIB}.a: ${OBJS}
+ echo building standard ${LIB} library
diff --git a/net/SSLtelnet/files/patch-ak b/net/SSLtelnet/files/patch-ak
new file mode 100644
index 000000000000..896e36470d21
--- /dev/null
+++ b/net/SSLtelnet/files/patch-ak
@@ -0,0 +1,10 @@
+--- lib/libtelnet/sslapp.c.old Thu Aug 5 03:36:35 1999
++++ lib/libtelnet/sslapp.c Thu Aug 5 03:36:55 1999
+@@ -81,7 +81,7 @@
+
+ if (ssl_debug_flag)
+ BIO_printf(bio_err,"Generating temp (512 bit) RSA key ...\r\n");
+- rsa=RSA_generate_key(512,RSA_F4,NULL);
++ rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
+ if (ssl_debug_flag)
+ BIO_printf(bio_err,"Generation of temp (512 bit) RSA key done\r\n");
diff --git a/net/SSLtelnet/files/patch-al b/net/SSLtelnet/files/patch-al
new file mode 100644
index 000000000000..39ed9d90ef05
--- /dev/null
+++ b/net/SSLtelnet/files/patch-al
@@ -0,0 +1,26 @@
+--- telnet/telnet.c.orig Sat Oct 16 11:32:57 1999
++++ telnet/telnet.c Sat Oct 16 11:34:05 1999
+@@ -68,6 +68,7 @@
+ #include "externs.h"
+ #include "types.h"
+ #include "general.h"
++#include <osreldate.h>
+
+
+ #define strip(x) ((x)&0x7f)
+@@ -752,6 +753,7 @@
+
+ #ifdef TERMCAP
+ char termbuf[1024];
++#if (__FreeBSD_version < 400011)
+
+ /*ARGSUSED*/
+ int
+@@ -769,6 +771,7 @@
+ *errp = 0;
+ return(-1);
+ }
++#endif
+ #else
+ #define termbuf ttytype
+ extern char ttytype[];
diff --git a/net/SSLtelnet/files/patch-am b/net/SSLtelnet/files/patch-am
new file mode 100644
index 000000000000..a385599eea64
--- /dev/null
+++ b/net/SSLtelnet/files/patch-am
@@ -0,0 +1,43 @@
+--- telnet/commands.c.old Sun Jan 7 10:03:38 2001
++++ telnet/commands.c Sun Jan 7 10:16:53 2001
+@@ -55,7 +55,7 @@
+ #include <netdb.h>
+ #include <ctype.h>
+ #include <pwd.h>
+-#include <varargs.h>
++#include <stdarg.h>
+ #include <errno.h>
+
+ #include <arpa/telnet.h>
+@@ -100,7 +100,8 @@
+ extern char **genget();
+ extern int Ambiguous();
+
+-static call();
++typedef int (*intrtn_t)();
++static int call(intrtn_t, ...);
+
+ typedef struct {
+ char *name; /* command name */
+@@ -2550,18 +2551,14 @@
+ */
+
+ /*VARARGS1*/
+- static
+-call(va_alist)
+- va_dcl
++ static int
++call(intrtn_t routine, ...)
+ {
+ va_list ap;
+- typedef int (*intrtn_t)();
+- intrtn_t routine;
+ char *args[100];
+ int argno = 0;
+
+- va_start(ap);
+- routine = (va_arg(ap, intrtn_t));
++ va_start(ap, routine);
+ while ((args[argno++] = va_arg(ap, char *)) != 0) {
+ ;
+ }
diff --git a/net/SSLtelnet/files/patch-an b/net/SSLtelnet/files/patch-an
new file mode 100644
index 000000000000..7d2a742426ec
--- /dev/null
+++ b/net/SSLtelnet/files/patch-an
@@ -0,0 +1,1320 @@
+diff -u telnetd.old/authenc.c telnetd/authenc.c
+--- telnetd.old/authenc.c Fri Oct 15 05:47:52 1993
++++ telnetd/authenc.c Fri Aug 2 11:02:09 2002
+@@ -45,8 +45,7 @@
+ int len;
+ {
+ if (nfrontp + len < netobuf + BUFSIZ) {
+- memcpy((void *)nfrontp, (void *)str, len);
+- nfrontp += len;
++ output_datalen(str, len);
+ return(len);
+ }
+ return(0);
+diff -u telnetd.old/ext.h telnetd/ext.h
+--- telnetd.old/ext.h Sat Aug 2 14:55:54 1997
++++ telnetd/ext.h Thu Aug 1 14:56:01 2002
+@@ -74,7 +74,8 @@
+
+ extern char netibuf[BUFSIZ], *netip;
+
+-extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
++/* extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; */
++extern char netobuf[BUFSIZ], *nfrontp, *nbackp;
+ extern char *neturg; /* one past last bye of urgent data */
+
+ extern int pcc, ncc;
+@@ -183,8 +184,13 @@
+ tty_setsofttab P((int)),
+ tty_tspeed P((int)),
+ willoption P((int)),
+- wontoption P((int)),
+- writenet P((unsigned char *, int));
++ /*wontoption P((int)),
++ writenet P((unsigned char *, int));*/
++ wontoption P((int));
++
++int output_data __P((const char *, ...)) __printflike(1, 2);
++void output_datalen __P((const char *, int));
++
+
+ #if defined(ENCRYPT)
+ extern void (*encrypt_output) P((unsigned char *, int));
+diff -u telnetd.old/slc.c telnetd/slc.c
+--- telnetd.old/slc.c Fri Oct 15 05:48:20 1993
++++ telnetd/slc.c Fri Aug 2 11:03:20 2002
+@@ -172,7 +172,6 @@
+ register unsigned char **bufp;
+ {
+ register int len;
+- void netflush();
+
+ /*
+ * If a change has occured, store the new terminal control
+@@ -200,7 +199,7 @@
+ (void) sprintf((char *)slcptr, "%c%c", IAC, SE);
+ slcptr += 2;
+ len = slcptr - slcbuf;
+- writenet(slcbuf, len);
++ output_datalen(slcbuf, len);
+ netflush(); /* force it out immediately */
+ }
+ }
+diff -u telnetd.old/state.c telnetd/state.c
+--- telnetd.old/state.c Fri Oct 15 05:49:12 1993
++++ telnetd/state.c Fri Aug 2 10:08:59 2002
+@@ -35,6 +35,7 @@
+ static char sccsid[] = "@(#)state.c 5.10 (Berkeley) 3/22/91";
+ #endif /* not lint */
+
++#include <stdarg.h>
+ #include "telnetd.h"
+ #if defined(AUTHENTICATE)
+ #include <libtelnet/auth.h>
+@@ -193,8 +194,7 @@
+ }
+
+ netclear(); /* clear buffer back */
+- *nfrontp++ = IAC;
+- *nfrontp++ = DM;
++ output_data("%c%c", IAC, DM);
+ neturg = nfrontp-1; /* off by one XXX */
+ DIAG(TD_OPTIONS,
+ printoption("td: send IAC", DM));
+@@ -447,8 +447,7 @@
+ set_his_want_state_will(option);
+ do_dont_resp[option]++;
+ }
+- (void) sprintf(nfrontp, doopt, option);
+- nfrontp += sizeof (dont) - 2;
++ output_data((const char *)doopt, option);
+
+ DIAG(TD_OPTIONS, printoption("td: send do", option));
+ }
+@@ -661,8 +660,7 @@
+ set_his_want_state_wont(option);
+ do_dont_resp[option]++;
+ }
+- (void) sprintf(nfrontp, dont, option);
+- nfrontp += sizeof (doopt) - 2;
++ output_data((const char *)dont, option);
+
+ DIAG(TD_OPTIONS, printoption("td: send dont", option));
+ }
+@@ -807,8 +805,7 @@
+ set_my_want_state_will(option);
+ will_wont_resp[option]++;
+ }
+- (void) sprintf(nfrontp, will, option);
+- nfrontp += sizeof (doopt) - 2;
++ output_data((const char *)will, option);
+
+ DIAG(TD_OPTIONS, printoption("td: send will", option));
+ }
+@@ -963,8 +960,7 @@
+ set_my_want_state_wont(option);
+ will_wont_resp[option]++;
+ }
+- (void) sprintf(nfrontp, wont, option);
+- nfrontp += sizeof (wont) - 2;
++ output_data((const char *)wont, option);
+
+ DIAG(TD_OPTIONS, printoption("td: send wont", option));
+ }
+@@ -1435,9 +1431,57 @@
+ ADD(IAC);
+ ADD(SE);
+
+- writenet(statusbuf, ncp - statusbuf);
++ /*writenet(statusbuf, ncp - statusbuf);*/
++ output_datalen(statusbuf, ncp - statusbuf);
+ netflush(); /* Send it on its way */
+
+ DIAG(TD_OPTIONS,
+ {printsub('>', statusbuf, ncp - statusbuf); netflush();});
++}
++
++
++/*
++ * This function appends data to nfrontp and advances nfrontp.
++ * Returns the number of characters written altogether (the
++ * buffer may have been flushed in the process).
++ */
++
++int
++output_data(const char *format, ...)
++{
++ va_list args;
++ int len;
++ char *buf;
++
++ va_start(args, format);
++ if ((len = vasprintf(&buf, format, args)) == -1)
++ return -1;
++ output_datalen(buf, len);
++ va_end(args);
++ free(buf);
++ return (len);
++}
++
++void
++output_datalen(const char *buf, int len)
++{
++ int remaining, copied;
++
++ remaining = BUFSIZ - (nfrontp - netobuf);
++ while (len > 0) {
++ /* Free up enough space if the room is too low*/
++ if ((len > BUFSIZ ? BUFSIZ : len) > remaining) {
++ netflush();
++ remaining = BUFSIZ - (nfrontp - netobuf);
++ }
++
++ /* Copy out as much as will fit */
++ copied = remaining > len ? len : remaining;
++ memmove(nfrontp, buf, copied);
++ nfrontp += copied;
++ len -= copied;
++ remaining -= copied;
++ buf += copied;
++ }
++ return;
+ }
+diff -u telnetd.old/telnetd.c telnetd/telnetd.c
+--- telnetd.old/telnetd.c Fri Aug 2 11:08:49 2002
++++ telnetd/telnetd.c Fri Aug 2 10:14:08 2002
+@@ -704,25 +704,22 @@
+ if (his_state_is_will(TELOPT_TSPEED)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
+
+- memcpy(nfrontp, sbbuf,sizeof sbbuf);
+- nfrontp += sizeof sbbuf;
++ output_datalen(sbbuf, sizeof sbbuf);
++
+ }
+ if (his_state_is_will(TELOPT_XDISPLOC)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
+
+- memcpy(nfrontp, sbbuf,sizeof sbbuf);
+- nfrontp += sizeof sbbuf;
++ output_datalen(sbbuf, sizeof sbbuf);
+ }
+ if (his_state_is_will(TELOPT_ENVIRON)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE };
+
+- memcpy(nfrontp, sbbuf,sizeof sbbuf);
+- nfrontp += sizeof sbbuf;
++ output_datalen(sbbuf, sizeof sbbuf);
+ }
+ if (his_state_is_will(TELOPT_TTYPE)) {
+
+- memcpy(nfrontp,ttytype_sbbuf, sizeof ttytype_sbbuf);
+- nfrontp += sizeof ttytype_sbbuf;
++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
+ }
+ if (his_state_is_will(TELOPT_TSPEED)) {
+ while (sequenceIs(tspeedsubopt, baseline))
+@@ -791,8 +788,7 @@
+ if (his_state_is_wont(TELOPT_TTYPE))
+ return;
+ settimer(baseline);
+- memcpy(nfrontp,ttytype_sbbuf, sizeof ttytype_sbbuf);
+- nfrontp += sizeof ttytype_sbbuf;
++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
+ while (sequenceIs(ttypesubopt, baseline))
+ ttloop();
+ }
+@@ -978,7 +974,7 @@
+ char *HE;
+ char *HN;
+ char *IM;
+- void netflush();
++ /*void netflush();*/
+
+ /*
+ * Initialize the slc mapping table.
+@@ -1062,9 +1058,7 @@
+ * mode, which we do not want.
+ */
+ if (his_want_state_is_will(TELOPT_ECHO)) {
+- DIAG(TD_OPTIONS,
+- {sprintf(nfrontp, "td: simulating recv\r\n");
+- nfrontp += strlen(nfrontp);});
++ DIAG(TD_OPTIONS, output_data("td: simulating recv\r\n"));
+ willoption(TELOPT_ECHO);
+ }
+
+@@ -1207,8 +1201,7 @@
+ #endif /* LINEMODE */
+
+ DIAG(TD_REPORT,
+- {sprintf(nfrontp, "td: Entering processing loop\r\n");
+- nfrontp += strlen(nfrontp);});
++ output_data("td: Entering processing loop\r\n"));
+
+ #ifdef convex
+ startslave(host);
+@@ -1346,8 +1339,7 @@
+ netip = netibuf;
+ }
+ DIAG((TD_REPORT | TD_NETDATA),
+- {sprintf(nfrontp, "td: netread %d chars\r\n", ncc);
+- nfrontp += strlen(nfrontp);});
++ output_data("td: netread %d chars\r\n", ncc));
+ DIAG(TD_NETDATA, printdata("nd", netip, ncc));
+ }
+
+@@ -1401,19 +1393,17 @@
+ * royally if we send them urgent
+ * mode data.
+ */
+- *nfrontp++ = IAC;
+- *nfrontp++ = DM;
++ output_data("%c%c", IAC, DM);
+ neturg = nfrontp-1; /* off by one XXX */
+ #endif
+ }
+ if (his_state_is_will(TELOPT_LFLOW) &&
+ (ptyibuf[0] &
+ (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c",
++ output_data("%c%c%c%c%c%c",
+ IAC, SB, TELOPT_LFLOW,
+ ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0,
+ IAC, SE);
+- nfrontp += 6;
+ }
+ pcc--;
+ ptyip = ptyibuf+1;
+@@ -1436,19 +1426,19 @@
+ break;
+ c = *ptyip++ & 0377, pcc--;
+ if (c == IAC)
+- *nfrontp++ = c;
++ output_data("%c", c);
+ #if defined(CRAY2) && defined(UNICOS5)
+ else if (c == '\n' &&
+ my_state_is_wont(TELOPT_BINARY) && newmap)
+- *nfrontp++ = '\r';
++ output_data("\r");
+ #endif /* defined(CRAY2) && defined(UNICOS5) */
+- *nfrontp++ = c;
++ output_data("%c", c);
+ if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
+ if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
+- *nfrontp++ = *ptyip++ & 0377;
++ output_data("%c", *ptyip++ & 0377);
+ pcc--;
+ } else
+- *nfrontp++ = '\0';
++ output_data("%c", '\0');
+ }
+ }
+ #if defined(CRAY2) && defined(UNICOS5)
+@@ -1543,8 +1533,7 @@
+ return;
+ }
+ #endif
+- (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
+- nfrontp += 9;
++ output_data("\r\n[Yes]\r\n");
+ }
+
+ void
+diff -u telnetd.old/termstat.c telnetd/termstat.c
+--- telnetd.old/termstat.c Fri Oct 15 05:54:55 1993
++++ telnetd/termstat.c Fri Aug 2 10:14:53 2002
+@@ -130,7 +130,7 @@
+ void
+ localstat()
+ {
+- void netflush();
++ /*void netflush();*/
+ int need_will_echo = 0;
+
+ #if defined(CRAY2) && defined(UNICOS5)
+@@ -166,9 +166,8 @@
+ if (his_state_is_will(TELOPT_LFLOW)) {
+ if (tty_flowmode() != flowmode) {
+ flowmode = tty_flowmode();
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c", IAC, SB,
++ output_data("%c%c%c%c%c%c",
+ TELOPT_LFLOW, flowmode, IAC, SE);
+- nfrontp += 6;
+ }
+ }
+
+@@ -286,10 +285,9 @@
+ # endif /* KLUDGELINEMODE */
+ send_do(TELOPT_LINEMODE, 1);
+ /* send along edit modes */
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
++ output_data("%c%c%c%c%c%c%c", IAC, SB,
+ TELOPT_LINEMODE, LM_MODE, useeditmode,
+ IAC, SE);
+- nfrontp += 7;
+ editmode = useeditmode;
+ # ifdef KLUDGELINEMODE
+ }
+@@ -315,10 +313,9 @@
+ /*
+ * Send along appropriate edit mode mask.
+ */
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
++ output_data("%c%c%c%c%c%c%c", IAC, SB,
+ TELOPT_LINEMODE, LM_MODE, useeditmode,
+ IAC, SE);
+- nfrontp += 7;
+ editmode = useeditmode;
+ }
+
+@@ -420,10 +417,9 @@
+ useeditmode |= MODE_SOFT_TAB;
+ if (tty_islitecho())
+ useeditmode |= MODE_LIT_ECHO;
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
++ output_data("%c%c%c%c%c%c%c", IAC,
+ SB, TELOPT_LINEMODE, LM_MODE,
+ useeditmode, IAC, SE);
+- nfrontp += 7;
+ editmode = useeditmode;
+ }
+
+@@ -477,11 +473,10 @@
+ set_termbuf();
+
+ if (!ack) {
+- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
++ output_data("%c%c%c%c%c%c%c", IAC,
+ SB, TELOPT_LINEMODE, LM_MODE,
+ useeditmode|MODE_ACK,
+ IAC, SE);
+- nfrontp += 7;
+ }
+
+ editmode = useeditmode;
+diff -u telnetd.old/utility.c telnetd/utility.c
+--- telnetd.old/utility.c Mon Aug 26 11:06:43 1996
++++ telnetd/utility.c Fri Aug 2 10:01:52 2002
+@@ -54,11 +54,10 @@
+ void
+ ttloop()
+ {
+- void netflush();
++ /*void netflush();*/
+
+- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n");
+- nfrontp += strlen(nfrontp);});
+- if (nfrontp-nbackp) {
++ DIAG(TD_REPORT, output_data("td: ttloop\r\n"));
++ if (nfrontp - nbackp > 0) {
+ netflush();
+ }
+ #ifdef USE_SSL
+@@ -74,8 +73,7 @@
+ syslog(LOG_INFO, "ttloop: peer died: %m\n");
+ exit(1);
+ }
+- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc);
+- nfrontp += strlen(nfrontp);});
++ DIAG(TD_REPORT, output_data("td: ttloop read %d chars\r\n", ncc));
+ netip = netibuf;
+ telrcv(); /* state machine */
+ if (ncc > 0) {
+@@ -117,9 +115,8 @@
+ int n;
+
+ if ((n = pfrontp - pbackp) > 0) {
+- DIAG((TD_REPORT | TD_PTYDATA),
+- { sprintf(nfrontp, "td: ptyflush %d chars\r\n", n);
+- nfrontp += strlen(nfrontp); });
++ DIAG(TD_REPORT | TD_PTYDATA,
++ output_data("td: ptyflush %d chars\r\n", n));
+ DIAG(TD_PTYDATA, printdata("pd", pbackp, n));
+ n = write(pty, pbackp, n);
+ }
+@@ -249,12 +246,13 @@
+ int n;
+ extern int not42;
+
+- if ((n = nfrontp - nbackp) > 0) {
+- DIAG(TD_REPORT,
+- { sprintf(nfrontp, "td: netflush %d chars\r\n", n);
+- n += strlen(nfrontp); /* get count first */
+- nfrontp += strlen(nfrontp); /* then move pointer */
+- });
++ while ((n = nfrontp - nbackp) > 0) {
++#if 0
++ /* XXX This causes output_data() to recurse and die */
++ DIAG(TD_REPORT, {
++ n += output_data("td: netflush %d chars\r\n", n);
++ });
++#endif
+ #if defined(ENCRYPT)
+ if (encrypt_output) {
+ char *s = nclearto ? nclearto : nbackp;
+@@ -302,13 +300,33 @@
+ n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
+ }
+ }
++ if (n == -1) {
++ if (errno == EWOULDBLOCK || errno == EINTR)
++ continue;
++ cleanup(0);
++ /* NOTREACHED */
++ }
++ nbackp += n;
++#if defined(ENCRYPT)
++ if (nbackp > nclearto)
++ nclearto = 0;
++#endif
++ if (nbackp >= neturg) {
++ neturg = 0;
++ }
++ if (nbackp == nfrontp) {
++ nbackp = nfrontp = netobuf;
++#if defined(ENCRYPT)
++ nclearto = 0;
++#endif
++ }
+ }
+ if (n < 0) {
+ if (errno == EWOULDBLOCK || errno == EINTR)
+ return;
+ cleanup(0);
+ }
+- nbackp += n;
++/* nbackp += n;
+ #if defined(ENCRYPT)
+ if (nbackp > nclearto)
+ nclearto = 0;
+@@ -321,39 +339,12 @@
+ #if defined(ENCRYPT)
+ nclearto = 0;
+ #endif
+- }
++ }*/
+ return;
+ } /* end of netflush */
+
+
+ /*
+- * writenet
+- *
+- * Just a handy little function to write a bit of raw data to the net.
+- * It will force a transmit of the buffer if necessary
+- *
+- * arguments
+- * ptr - A pointer to a character string to write
+- * len - How many bytes to write
+- */
+- void
+-writenet(ptr, len)
+- register unsigned char *ptr;
+- register int len;
+-{
+- /* flush buffer if no room for new data) */
+- if ((&netobuf[BUFSIZ] - nfrontp) < len) {
+- /* if this fails, don't worry, buffer is a little big */
+- netflush();
+- }
+-
+- memcpy(nfrontp, ptr,len);
+- nfrontp += len;
+-
+-} /* end of writenet */
+-
+-
+-/*
+ * miscellaneous functions doing a variety of little jobs follow ...
+ */
+
+@@ -541,12 +532,11 @@
+ register int option;
+ {
+ if (TELOPT_OK(option))
+- sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option));
++ output_data("%s %s\r\n", fmt, TELOPT(option));
+ else if (TELCMD_OK(option))
+- sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option));
++ output_data("%s %s\r\n", fmt, TELCMD(option));
+ else
+- sprintf(nfrontp, "%s %d\r\n", fmt, option);
+- nfrontp += strlen(nfrontp);
++ output_data("%s %d\r\n", fmt, option);
+ return;
+ }
+
+@@ -563,9 +553,8 @@
+ return;
+
+ if (direction) {
+- sprintf(nfrontp, "td: %s suboption ",
+- direction == '<' ? "recv" : "send");
+- nfrontp += strlen(nfrontp);
++ output_data("td: %s suboption ",
++ direction == '<' ? "recv" : "send");
+ if (length >= 3) {
+ register int j;
+
+@@ -573,228 +562,195 @@
+ j = pointer[length-1];
+
+ if (i != IAC || j != SE) {
+- sprintf(nfrontp, "(terminated by ");
+- nfrontp += strlen(nfrontp);
++ output_data("(terminated by ");
+ if (TELOPT_OK(i))
+- sprintf(nfrontp, "%s ", TELOPT(i));
++ output_data("%s ", TELOPT(i));
+ else if (TELCMD_OK(i))
+- sprintf(nfrontp, "%s ", TELCMD(i));
++ output_data("%s ", TELCMD(i));
+ else
+- sprintf(nfrontp, "%d ", i);
+- nfrontp += strlen(nfrontp);
++ output_data("%d ", i);
+ if (TELOPT_OK(j))
+- sprintf(nfrontp, "%s", TELOPT(j));
++ output_data("%s", TELOPT(j));
+ else if (TELCMD_OK(j))
+- sprintf(nfrontp, "%s", TELCMD(j));
++ output_data("%s", TELCMD(j));
+ else
+- sprintf(nfrontp, "%d", j);
+- nfrontp += strlen(nfrontp);
+- sprintf(nfrontp, ", not IAC SE!) ");
+- nfrontp += strlen(nfrontp);
++ output_data("%d", j);
++ output_data(", not IAC SE!) ");
+ }
+ }
+ length -= 2;
+ }
+ if (length < 1) {
+- sprintf(nfrontp, "(Empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data("(Empty suboption??\?)");
+ return;
+ }
+ switch (pointer[0]) {
+ case TELOPT_TTYPE:
+- sprintf(nfrontp, "TERMINAL-TYPE ");
+- nfrontp += strlen(nfrontp);
++ output_data("TERMINAL-TYPE ");
+ switch (pointer[1]) {
+ case TELQUAL_IS:
+- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2);
+ break;
+ case TELQUAL_SEND:
+- sprintf(nfrontp, "SEND");
++ output_data("SEND");
+ break;
+ default:
+- sprintf(nfrontp,
+- "- unknown qualifier %d (0x%x).",
++ output_data(
++ "- unknown qualifier %d (0x%x).",
+ pointer[1], pointer[1]);
+ }
+- nfrontp += strlen(nfrontp);
+ break;
+ case TELOPT_TSPEED:
+- sprintf(nfrontp, "TERMINAL-SPEED");
+- nfrontp += strlen(nfrontp);
++ output_data("TERMINAL-SPEED");
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption??\?)");
+ break;
+ }
+ switch (pointer[1]) {
+ case TELQUAL_IS:
+- sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2);
+- nfrontp += strlen(nfrontp);
++ output_data(" IS %.*s", length-2, (char *)pointer+2);
+ break;
+ default:
+ if (pointer[1] == 1)
+- sprintf(nfrontp, " SEND");
++ output_data(" SEND");
+ else
+- sprintf(nfrontp, " %d (unknown)", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d (unknown)", pointer[1]);
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+ }
+ break;
+
+ case TELOPT_LFLOW:
+- sprintf(nfrontp, "TOGGLE-FLOW-CONTROL");
+- nfrontp += strlen(nfrontp);
++ output_data("TOGGLE-FLOW-CONTROL");
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption??\?)");
+ break;
+ }
+ switch (pointer[1]) {
+ case 0:
+- sprintf(nfrontp, " OFF"); break;
++ output_data(" OFF"); break;
+ case 1:
+- sprintf(nfrontp, " ON"); break;
++ output_data(" ON"); break;
++
++ /*
++ case LFLOW_RESTART_ANY:
++ output_data(" RESTART-ANY"); break;
++ case LFLOW_RESTART_XON:
++ output_data(" RESTART-XON"); break;
++ */
+ default:
+- sprintf(nfrontp, " %d (unknown)", pointer[1]);
++ output_data(" %d (unknown)", pointer[1]);
+ }
+- nfrontp += strlen(nfrontp);
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+
+ case TELOPT_NAWS:
+- sprintf(nfrontp, "NAWS");
+- nfrontp += strlen(nfrontp);
++ output_data("NAWS");
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption??\?)");
+ break;
+ }
+ if (length == 2) {
+- sprintf(nfrontp, " ?%d?", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[1]);
+ break;
+ }
+- sprintf(nfrontp, " %d %d (%d)",
++ output_data(" %d %d (%d)",
+ pointer[1], pointer[2],
+ (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
+- nfrontp += strlen(nfrontp);
+ if (length == 4) {
+- sprintf(nfrontp, " ?%d?", pointer[3]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[3]);
+ break;
+ }
+- sprintf(nfrontp, " %d %d (%d)",
++ output_data(" %d %d (%d)",
+ pointer[3], pointer[4],
+ (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
+- nfrontp += strlen(nfrontp);
+ for (i = 5; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+
+ case TELOPT_LINEMODE:
+- sprintf(nfrontp, "LINEMODE ");
+- nfrontp += strlen(nfrontp);
++ output_data("LINEMODE ");
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption??\?)");
+ break;
+ }
+ switch (pointer[1]) {
+ case WILL:
+- sprintf(nfrontp, "WILL ");
++ output_data("WILL ");
+ goto common;
+ case WONT:
+- sprintf(nfrontp, "WONT ");
++ output_data("WONT ");
+ goto common;
+ case DO:
+- sprintf(nfrontp, "DO ");
++ output_data("DO ");
+ goto common;
+ case DONT:
+- sprintf(nfrontp, "DONT ");
++ output_data("DONT ");
+ common:
+- nfrontp += strlen(nfrontp);
+ if (length < 3) {
+- sprintf(nfrontp, "(no option???)");
+- nfrontp += strlen(nfrontp);
++ output_data("(no option??\?)");
+ break;
+ }
+ switch (pointer[2]) {
+ case LM_FORWARDMASK:
+- sprintf(nfrontp, "Forward Mask");
+- nfrontp += strlen(nfrontp);
++ output_data("Forward Mask");
+ for (i = 3; i < length; i++) {
+- sprintf(nfrontp, " %x", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %x", pointer[i]);
+ }
+ break;
+ default:
+- sprintf(nfrontp, "%d (unknown)", pointer[2]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d (unknown)", pointer[2]);
+ for (i = 3; i < length; i++) {
+- sprintf(nfrontp, " %d", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i]);
+ }
+ break;
+ }
+ break;
+
+ case LM_SLC:
+- sprintf(nfrontp, "SLC");
+- nfrontp += strlen(nfrontp);
++ output_data("SLC");
+ for (i = 2; i < length - 2; i += 3) {
+ if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
+- sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
++ output_data(" %s", SLC_NAME(pointer[i+SLC_FUNC]));
+ else
+- sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i+SLC_FUNC]);
+ switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
+ case SLC_NOSUPPORT:
+- sprintf(nfrontp, " NOSUPPORT"); break;
++ output_data(" NOSUPPORT"); break;
+ case SLC_CANTCHANGE:
+- sprintf(nfrontp, " CANTCHANGE"); break;
++ output_data(" CANTCHANGE"); break;
+ case SLC_VARIABLE:
+- sprintf(nfrontp, " VARIABLE"); break;
++ output_data(" VARIABLE"); break;
+ case SLC_DEFAULT:
+- sprintf(nfrontp, " DEFAULT"); break;
++ output_data(" DEFAULT"); break;
+ }
+- nfrontp += strlen(nfrontp);
+- sprintf(nfrontp, "%s%s%s",
++ output_data("%s%s%s",
+ pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
+ pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
+ pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
+- nfrontp += strlen(nfrontp);
+ if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
+ SLC_FLUSHOUT| SLC_LEVELBITS)) {
+- sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]);
+- nfrontp += strlen(nfrontp);
++ output_data("(0x%x)", pointer[i+SLC_FLAGS]);
+ }
+- sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d;", pointer[i+SLC_VALUE]);
+ if ((pointer[i+SLC_VALUE] == IAC) &&
+ (pointer[i+SLC_VALUE+1] == IAC))
+ i++;
+ }
+ for (; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+
+ case LM_MODE:
+- sprintf(nfrontp, "MODE ");
+- nfrontp += strlen(nfrontp);
++ output_data("MODE ");
+ if (length < 3) {
+- sprintf(nfrontp, "(no mode???)");
+- nfrontp += strlen(nfrontp);
++ output_data("(no mode??\?)");
+ break;
+ }
+ {
+@@ -805,24 +761,19 @@
+ pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
+ pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
+ pointer[2]&MODE_ACK ? "|ACK" : "");
+- sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0");
+- nfrontp += strlen(nfrontp);
++ output_data("%s", tbuf[1] ? &tbuf[1] : "0");
+ }
+ if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) {
+- sprintf(nfrontp, " (0x%x)", pointer[2]);
+- nfrontp += strlen(nfrontp);
++ output_data(" (0x%x)", pointer[2]);
+ }
+ for (i = 3; i < length; i++) {
+- sprintf(nfrontp, " ?0x%x?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?0x%x?", pointer[i]);
+ }
+ break;
+ default:
+- sprintf(nfrontp, "%d (unknown)", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d (unknown)", pointer[1]);
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " %d", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i]);
+ }
+ }
+ break;
+@@ -831,24 +782,20 @@
+ register char *cp;
+ register int j, k;
+
+- sprintf(nfrontp, "STATUS");
+- nfrontp += strlen(nfrontp);
++ output_data("STATUS");
+
+ switch (pointer[1]) {
+ default:
+ if (pointer[1] == TELQUAL_SEND)
+- sprintf(nfrontp, " SEND");
++ output_data(" SEND");
+ else
+- sprintf(nfrontp, " %d (unknown)", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d (unknown)", pointer[1]);
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+ case TELQUAL_IS:
+- sprintf(nfrontp, " IS\r\n");
+- nfrontp += strlen(nfrontp);
++ output_data(" IS\r\n");
+
+ for (i = 2; i < length; i++) {
+ switch(pointer[i]) {
+@@ -859,18 +806,15 @@
+ common2:
+ i++;
+ if (TELOPT_OK((int)pointer[i]))
+- sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
++ output_data(" %s %s", cp, TELOPT(pointer[i]));
+ else
+- sprintf(nfrontp, " %s %d", cp, pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %s %d", cp, pointer[i]);
+
+- sprintf(nfrontp, "\r\n");
+- nfrontp += strlen(nfrontp);
++ output_data("\r\n");
+ break;
+
+ case SB:
+- sprintf(nfrontp, " SB ");
+- nfrontp += strlen(nfrontp);
++ output_data(" SB ");
+ i++;
+ j = k = i;
+ while (j < length) {
+@@ -886,20 +830,17 @@
+ }
+ printsub(0, &pointer[i], k - i);
+ if (i < length) {
+- sprintf(nfrontp, " SE");
+- nfrontp += strlen(nfrontp);
++ output_data(" SE");
+ i = j;
+ } else
+ i = j - 1;
+
+- sprintf(nfrontp, "\r\n");
+- nfrontp += strlen(nfrontp);
++ output_data("\r\n");
+
+ break;
+
+ default:
+- sprintf(nfrontp, " %d", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i]);
+ break;
+ }
+ }
+@@ -909,36 +850,32 @@
+ }
+
+ case TELOPT_XDISPLOC:
+- sprintf(nfrontp, "X-DISPLAY-LOCATION ");
+- nfrontp += strlen(nfrontp);
++ output_data("X-DISPLAY-LOCATION ");
+ switch (pointer[1]) {
+ case TELQUAL_IS:
+- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2);
+ break;
+ case TELQUAL_SEND:
+- sprintf(nfrontp, "SEND");
++ output_data("SEND");
+ break;
+ default:
+- sprintf(nfrontp, "- unknown qualifier %d (0x%x).",
++ output_data("- unknown qualifier %d (0x%x).",
+ pointer[1], pointer[1]);
+ }
+- nfrontp += strlen(nfrontp);
+ break;
+
+ case TELOPT_ENVIRON:
+- sprintf(nfrontp, "ENVIRON ");
+- nfrontp += strlen(nfrontp);
++ output_data("NEW-ENVIRON ");
+ switch (pointer[1]) {
+ case TELQUAL_IS:
+- sprintf(nfrontp, "IS ");
++ output_data("IS ");
+ goto env_common;
+ case TELQUAL_SEND:
+- sprintf(nfrontp, "SEND ");
++ output_data("SEND ");
+ goto env_common;
+ case TELQUAL_INFO:
+- sprintf(nfrontp, "INFO ");
++ output_data("INFO ");
+ env_common:
+- nfrontp += strlen(nfrontp);
+ {
+ register int noquote = 2;
+ for (i = 2; i < length; i++ ) {
+@@ -946,42 +883,43 @@
+ case ENV_VAR:
+ if (pointer[1] == TELQUAL_SEND)
+ goto def_case;
+- sprintf(nfrontp, "\" VAR " + noquote);
+- nfrontp += strlen(nfrontp);
++ output_data("\" VAR " + noquote);
+ noquote = 2;
+ break;
+
+ case ENV_VALUE:
+- sprintf(nfrontp, "\" VALUE " + noquote);
+- nfrontp += strlen(nfrontp);
++ output_data("\" VALUE " + noquote);
+ noquote = 2;
+ break;
+
+ case ENV_ESC:
+- sprintf(nfrontp, "\" ESC " + noquote);
+- nfrontp += strlen(nfrontp);
++ output_data("\" ESC " + noquote);
+ noquote = 2;
+ break;
+-
++ /*
++ case ENV_USERVAR:
++ output_data("\" USERVAR " + noquote);
++ noquote = 2;
++ break;
++ */
+ default:
+ def_case:
+ if (isprint(pointer[i]) && pointer[i] != '"') {
+ if (noquote) {
+- *nfrontp++ = '"';
++ output_data("\"");
+ noquote = 0;
+ }
+- *nfrontp++ = pointer[i];
++ output_data("%c", pointer[i]);
+ } else {
+- sprintf(nfrontp, "\" %03o " + noquote,
++ output_data("\" %03o " + noquote,
+ pointer[i]);
+- nfrontp += strlen(nfrontp);
+ noquote = 2;
+ }
+ break;
+ }
+ }
+ if (!noquote)
+- *nfrontp++ = '"';
++ output_data("\"");
+ break;
+ }
+ }
+@@ -989,80 +927,66 @@
+
+ #if defined(AUTHENTICATE)
+ case TELOPT_AUTHENTICATION:
+- sprintf(nfrontp, "AUTHENTICATION");
+- nfrontp += strlen(nfrontp);
++ output_data("AUTHENTICATION");
+
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption??\?)");
+ break;
+ }
+ switch (pointer[1]) {
+ case TELQUAL_REPLY:
+ case TELQUAL_IS:
+- sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ?
++ output_data(" %s ", (pointer[1] == TELQUAL_IS) ?
+ "IS" : "REPLY");
+- nfrontp += strlen(nfrontp);
+ if (AUTHTYPE_NAME_OK(pointer[2]))
+- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2]));
++ output_data("%s ", AUTHTYPE_NAME(pointer[2]));
+ else
+- sprintf(nfrontp, "%d ", pointer[2]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d ", pointer[2]);
+ if (length < 3) {
+- sprintf(nfrontp, "(partial suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data("(partial suboption??\?)");
+ break;
+ }
+- sprintf(nfrontp, "%s|%s",
++ output_data("%s|%s",
+ ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+ "CLIENT" : "SERVER",
+ ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+ "MUTUAL" : "ONE-WAY");
+- nfrontp += strlen(nfrontp);
++ {
++ char buf[512];
+
+ auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+- sprintf(nfrontp, "%s", buf);
+- nfrontp += strlen(nfrontp);
++ output_data("%s", buf);
++ }
+ break;
+
+ case TELQUAL_SEND:
+ i = 2;
+- sprintf(nfrontp, " SEND ");
+- nfrontp += strlen(nfrontp);
++ output_data(" SEND ");
+ while (i < length) {
+ if (AUTHTYPE_NAME_OK(pointer[i]))
+- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i]));
++ output_data("%s ", AUTHTYPE_NAME(pointer[i]));
+ else
+- sprintf(nfrontp, "%d ", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d ", pointer[i]);
+ if (++i >= length) {
+- sprintf(nfrontp, "(partial suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data("(partial suboption??\?)");
+ break;
+ }
+- sprintf(nfrontp, "%s|%s ",
++ output_data("%s|%s ",
+ ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
+ "CLIENT" : "SERVER",
+ ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
+ "MUTUAL" : "ONE-WAY");
+- nfrontp += strlen(nfrontp);
+ ++i;
+ }
+ break;
+
+ case TELQUAL_NAME:
+- i = 2;
+- sprintf(nfrontp, " NAME \"");
+- nfrontp += strlen(nfrontp);
+- while (i < length)
+- *nfrontp += pointer[i++];
+- *nfrontp += '"';
++ output_data(" NAME \"%.*s\"", length - 2, pointer + 2);
+ break;
+
+ default:
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " ?%d?", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ?%d?", pointer[i]);
+ }
+ break;
+ }
+@@ -1071,86 +995,70 @@
+
+ #if defined(ENCRYPT)
+ case TELOPT_ENCRYPT:
+- sprintf(nfrontp, "ENCRYPT");
+- nfrontp += strlen(nfrontp);
++ output_data("ENCRYPT");
+ if (length < 2) {
+- sprintf(nfrontp, " (empty suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (empty suboption???)");
+ break;
+ }
+ switch (pointer[1]) {
+ case ENCRYPT_START:
+- sprintf(nfrontp, " START");
+- nfrontp += strlen(nfrontp);
++ output_data(" START");
+ break;
+
+ case ENCRYPT_END:
+- sprintf(nfrontp, " END");
+- nfrontp += strlen(nfrontp);
++ output_data(" END");
+ break;
+
+ case ENCRYPT_REQSTART:
+- sprintf(nfrontp, " REQUEST-START");
+- nfrontp += strlen(nfrontp);
++ output_data(" REQUEST-START");
+ break;
+
+ case ENCRYPT_REQEND:
+- sprintf(nfrontp, " REQUEST-END");
+- nfrontp += strlen(nfrontp);
++ output_data(" REQUEST-END");
+ break;
+
+ case ENCRYPT_IS:
+ case ENCRYPT_REPLY:
+- sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ?
++ output_data(" %s ", (pointer[1] == ENCRYPT_IS) ?
+ "IS" : "REPLY");
+- nfrontp += strlen(nfrontp);
+ if (length < 3) {
+- sprintf(nfrontp, " (partial suboption???)");
+- nfrontp += strlen(nfrontp);
++ output_data(" (partial suboption???)");
+ break;
+ }
+ if (ENCTYPE_NAME_OK(pointer[2]))
+- sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2]));
++ output_data("%s ", ENCTYPE_NAME(pointer[2]));
+ else
+- sprintf(nfrontp, " %d (unknown)", pointer[2]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d (unknown)", pointer[2]);
+
+ encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
+- sprintf(nfrontp, "%s", buf);
+- nfrontp += strlen(nfrontp);
++ output_data("%s", buf);
+ break;
+
+ case ENCRYPT_SUPPORT:
+ i = 2;
+- sprintf(nfrontp, " SUPPORT ");
+- nfrontp += strlen(nfrontp);
++ output_data(" SUPPORT ");
+ while (i < length) {
+ if (ENCTYPE_NAME_OK(pointer[i]))
+- sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i]));
++ output_data("%s ", ENCTYPE_NAME(pointer[i]));
+ else
+- sprintf(nfrontp, "%d ", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d ", pointer[i]);
+ i++;
+ }
+ break;
+
+ case ENCRYPT_ENC_KEYID:
+- sprintf(nfrontp, " ENC_KEYID %d", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" ENC_KEYID %d", pointer[1]);
+ goto encommon;
+
+ case ENCRYPT_DEC_KEYID:
+- sprintf(nfrontp, " DEC_KEYID %d", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" DEC_KEYID %d", pointer[1]);
+ goto encommon;
+
+ default:
+- sprintf(nfrontp, " %d (unknown)", pointer[1]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d (unknown)", pointer[1]);
+ encommon:
+ for (i = 2; i < length; i++) {
+- sprintf(nfrontp, " %d", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i]);
+ }
+ break;
+ }
+@@ -1159,18 +1067,15 @@
+
+ default:
+ if (TELOPT_OK(pointer[0]))
+- sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0]));
++ output_data("%s (unknown)", TELOPT(pointer[0]));
+ else
+- sprintf(nfrontp, "%d (unknown)", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data("%d (unknown)", pointer[i]);
+ for (i = 1; i < length; i++) {
+- sprintf(nfrontp, " %d", pointer[i]);
+- nfrontp += strlen(nfrontp);
++ output_data(" %d", pointer[i]);
+ }
+ break;
+ }
+- sprintf(nfrontp, "\r\n");
+- nfrontp += strlen(nfrontp);
++ output_data("\r\n");
+ }
+
+ /*
+@@ -1192,26 +1097,23 @@
+ }
+
+ /* add a line of output */
+- sprintf(nfrontp, "%s: ", tag);
+- nfrontp += strlen(nfrontp);
++ output_data("%s: ", tag);
+ for (i = 0; i < 20 && cnt; i++) {
+- sprintf(nfrontp, "%02x", *ptr);
+- nfrontp += strlen(nfrontp);
++ output_data("%02x", *ptr);
+ if (isprint(*ptr)) {
+ xbuf[i] = *ptr;
+ } else {
+ xbuf[i] = '.';
+ }
+- if (i % 2) {
+- *nfrontp = ' ';
+- nfrontp++;
++ if (i % 2) {
++ output_data(" ");
+ }
+ cnt--;
+ ptr++;
+ }
+ xbuf[i] = '\0';
+- sprintf(nfrontp, " %s\r\n", xbuf );
+- nfrontp += strlen(nfrontp);
++ output_data(" %s\r\n", xbuf );
+ }
+ }
+ #endif /* DIAGNOSTICS */
++/* nfrontp += strlen(nfrontp); */
diff --git a/net/SSLtelnet/pkg-comment b/net/SSLtelnet/pkg-comment
new file mode 100644
index 000000000000..31fde571a282
--- /dev/null
+++ b/net/SSLtelnet/pkg-comment
@@ -0,0 +1 @@
+SSL enhanced telnet/telnetd
diff --git a/net/SSLtelnet/pkg-descr b/net/SSLtelnet/pkg-descr
new file mode 100644
index 000000000000..a7697d197fa7
--- /dev/null
+++ b/net/SSLtelnet/pkg-descr
@@ -0,0 +1,20 @@
+This program suports both certification and cryptogoraphic with using SSL.
+
+If you do not have certification (/etc/ssl/certs/telnet.pem) provided
+by CA, this port make dummy certification. Of cource it is useless to certify
+but you can use SSL telnet/telnetd in encryption only mode with it.
+
+You must edit /etc/inetd.conf to make SSL telnetd available. Some examples
+below:
+
+1. Accept both normal telnet client and SSL telnet client.
+
+telnet stream tcp nowait root /usr/local/libexec/telnetd telnetd
+
+2. Accpet only SSL encrypted client.
+
+telnet stream tcp nowait root /usr/local/libexec/telnetd telnetd -z secure
+
+3. Accept only SSL certificated client.
+
+telnet stream tcp nowait root /usr/local/libexec/telnetd telnetd -a valid
diff --git a/net/SSLtelnet/pkg-plist b/net/SSLtelnet/pkg-plist
new file mode 100644
index 000000000000..e97f9d87e472
--- /dev/null
+++ b/net/SSLtelnet/pkg-plist
@@ -0,0 +1,4 @@
+bin/telnet
+libexec/telnetd
+@exec mkdir %%OPENSSLDIR%%/certs
+@exec if [ ! -f $(OPENSSLDIR)/certs/telnetd.pem ]; then cd %%OPENSSLDIR%%/certs; openssl req -new -x509 -nodes -days 365 -out telnetd.pem -keyout telnetd.pem; ln -s telnetd.pem `openssl x509 -noout -hash < telnetd.pem`.0 ; chmod 600 $(OPENSSLDIR)/certs/telnetd.pem; fi