August 2005
Dale R. Williamson

Making a telnetd daemon for the tops computing environment.

Reference: 
   Postel, J., and Reynolds, J. K., "Telnet Protocol Specification," 
   RFC 854, May 1983.
   See:
      http://www.faqs.org/rfcs/rfc854.html
      http://rfc.sunsite.dk/rfc/rfc854.html

------------------------------------------------------------------------

Tar file netkit-telnet-0.17.tgz in this directory is based upon source
files from RH7.2 source CD number 2, retrieved using:
   rpm -ivh telnet-0.17-20.src.rpm 

Before making netkit-telnet-0.17.tgz in this directory, patches that 
accompanied the code from the RH7.2 RPM were installed (see file 
READMEdwil when the code is untarred).

These patched files appear to be more recent than those in the archive
   ftp://ftp.uk.linux.org/pub/linux/Networking/netkit

Files from archive, netkit-telnet-0.17.tgz dated July 31, 2000, were 
spot checked and found to be older and with patches missing.

It is concluded that the version of telnetd here is up-to-date compared
to its Internet archive, and that it will be suitable for the intended
use.

This version of telnetd is useful because it supports the "-debug PORT"
option, allowing a number of telnetd sessions to be started on different
ports, each serving a separate client.  As soon as the client connects,
the daemon stops listening and supports the client through their estab-
lished connection.  When the client disconnects, the daemon shuts down.

Setting of the port is done in main() within telnetd.c.

Exploring FreeBSD.
Daemon telnetd in FreeBSD also has code in main() of telnetd.c for set-
ting the port under the -debug option, and would possibly be an alterna-
tive to the files in netkit-telnet-0.17.tgz given here.  
To start, try:
   http://www.freebsd.org/cgi/cvsweb.cgi/src/libexec/telnetd/Attic/telnetd.c?hideattic=0#rev1.1

Exploring GNU inetutils.  File
   http://directory.fsf.org/network/inetutils.html
contains a telnetd (inetutils-1.4.2.tar.gz), but after downloading and
installing it, the port setting option was found to be absent (in spite 
of what the accompanying GNU man page says).  Here is a failed run:
[root@clacker] /packages/inetutils-1.4.2/telnetd # telnetd -debug 9923 &
[1] 1461
telnetd: unknown command line option: d
[root@clacker] /packages/inetutils-1.4.2/telnetd # 

------------------------------------------------------------------------

Installing telnetd daemon from usr/telnetd/netkit-telnet-0.17.tgz, which
includes patches.

1. Here is a sample installaton of this telnetd daemon, done by root to
a place that will not interfere with the system's telnetd:
[root@clacker] /usr/local # cp /opt/tops/tops/usr/telnetd/netkit-telnet-0.17.tgz /usr/local
[root@clacker] /usr/local # tar -zxvf netkit-telnet-0.17.tgz 
[root@clacker] /usr/local # rm netkit-telnet-0.17.tgz 
[root@clacker] /usr/local # cd netkit-telnet-0.17
[root@clacker] /usr/local/netkit-telnet-0.17 # ./configure;make

This shows the installation in telnetd/ is complete with executable
file telnetd:
[root@clacker] /usr/local/netkit-telnet-0.17 # cd telnetd
[root@clacker] /usr/local/netkit-telnet-0.17/telnetd # ls -alF telnetd
-rwxr-xr-x    1 root     root        49033 Aug  6 05:14 telnetd*
[root@clacker] /usr/local/netkit-telnet-0.17/telnetd # file telnetd
telnetd: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked (uses shared libs), not stripped
[root@clacker] /usr/local/netkit-telnet-0.17/telnetd #

File /usr/local/netkit-telnet-0.17/telnetd/telnetd is the program that 
local tops will run to be its local telnet server.  It is not intended
to use this program for other purposes.

If this step failed, the Appendix shows an alternative that succeeded.

2. The final step is to build a wrapper program that allows a regular 
user to start the telnetd daemon without having root priviledges.

To create the wrapper program, first edit usr/telnetd/telnetd_wrap.c to
match the path/filename of telnetd, such as
   /usr/local/netkit-telnet-0.17/telnetd/telnetd
created in 1.

Then as root, perform the following in usr/telnetd:
[root@clacker] /opt/tops/tops/usr/telnetd # gcc -o telnetd_init telnetd_wrap.c
[root@clacker] /opt/tops/tops/usr/telnetd # chmod a+x telnetd_init
[root@clacker] /opt/tops/tops/usr/telnetd # chmod +s telnetd_init
[root@clacker] /opt/tops/tops/usr/telnetd # mv telnetd_init ../../sys

Using this wrapper program, sys/telnetd_init, tops will start telnetd 
on a port that it specifies.  Each port is dedicated to a single user.

Only root can kill the telnetd program.  But with tops connected to 
telnetd, as soon as the connection is closed, telnetd will stop anyway, 
so no wrapper program is needed to kill telnetd.  This is shown in the 
testing done next.

------------------------------------------------------------------------

Regular user testing the telnetd daemon.

1. Start telnetd listening on port 9923:
[dale@clacker] /opt/tops/tops/sys > telnetd_init 9923 &
[1] 2624

This shows telnetd running:
[dale@clacker] /opt/tops/tops/sys > ps -Af
...
dale      2538  2537  0 05:27 ttyp8    00:00:00 bash
root      2624  2152  0 05:39 ttyp7    00:00:00 telnetd -debug 9923
dale      2637  2152  0 05:40 ttyp7    00:00:00 ps -Af -Af

and this shows telnetd listening on port 9923:
[dale@clacker] /opt/tops/tops/sys > netstat -a | grep tcp
tcp     0      0 *:32768                 *:*                 LISTEN
tcp     0      0 localhost.localdo:32769 *:*                 LISTEN
tcp     0      0 *:9923                  *:*                 LISTEN
tcp     0      0 *:sunrpc                *:*                 LISTEN
tcp     0      0 *:x11                   *:*                 LISTEN
tcp     0      0 *:ssh                   *:*                 LISTEN
tcp     0      0 *:smtp                  *:*                 LISTEN

2. Connect tops program as a client to telnetd on IPloop (127.0.0.1), 
port 9923:
[dale@clacker] /opt/tops/tops/sys > tops
         Tops 3.0.1
Sat Aug  6 05:40:40 PDT 2005
[tops@clacker] ready > IPloop 9923 0 CONNECT

[tops@clacker] ready > 
 stack elements:
       0 volume: _foreign  1 by 12 << these are the first negotiation
                                      bytes from telnetd
       1 number: 3                 << this is the socket number
 [2] ok!
[tops@clacker] ready > INF xray .  << displaying the negotiation bytes
      (see Reference: 
          FF=IAC, FD 18="DO Terminal Type," then
          FF=IAC, FD 20="DO Terminal Speed," etc.)
       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
   0  FF FD 18 FF FD 20 FF FD 23 FF FD 27 00 00 00 00  ..... ..#..'....
 stack elements:
       0 number: 3
 [1] ok!
[tops@clacker] ready > sclose (closing socket 3; this will kill telnetd)

[tops@clacker] ready > bye
39 keys
         Good-bye
Sat Aug 6 05:41:23 PDT 2005

[dale@clacker] /opt/tops/tops/sys >   

Telnetd is exiting too:
[1]+  Exit 1                  telnetd_init 9923

and this verifies telnetd is gone:
[dale@clacker] /opt/tops/tops/sys > ps -Af
...
dale      2538  2537  0 05:27 ttyp8    00:00:00 bash
dale      2678  2152  0 05:46 ttyp7    00:00:00 ps -Af
[dale@clacker] /opt/tops/tops/sys > 

------------------------------------------------------------------------

Appendix

An alternative installation when Step 1 fails.

Running configure in /usr/local/netkit-telnet-0.17 may fail due to mis-
sing items that actually are not needed for compiling telnetd.  For 
example, the C++ compiler is not required to simply compile telnetd.
This shows configure failing on a machine due to problems it has with
C++:

[root@fortycoupe] /usr/local/netkit-telnet-0.17 # configure
Directories: /usr/bin /usr/sbin /usr/man 
Looking for a C compiler... gcc
Checking if gcc accepts gcc warnings... yes
Looking for a C++ compiler... failed.
Cannot find a C++ compiler. Run configure with --with-cpp-compiler.
[root@fortycoupe] /usr/local/netkit-telnet-0.17 # 

Trying the suggestion "--with-cpp-compiler" (but adjusting for what
really was intended, "--with-c++-compiler") still results in failure
because C++ won't compile:
[root@fortycoupe] /usr/local/netkit-telnet-0.17 # configure --with-c++-compiler=cc1
Directories: /usr/bin /usr/sbin /usr/man 
Looking for a C compiler... gcc
Checking if gcc accepts gcc warnings... yes
Checking if C++ compiler works... no
Compiler cc1 does not exist or cannot compile C++; try another.
[root@fortycoupe] /usr/local/netkit-telnet-0.17 # 

File MCONFIG in this directory has references to C++ deleted, and re-
sulted in a successful compilation.  On different systems it may need
further editing.

Copying MCONFIG to /usr/local/netkit-telnet-0.17:
[root@fortycoupe] /opt/tops/usr/telnetd # cp MCONFIG /usr/local/netkit-telnet-0.17        
cp: overwrite `/usr/local/netkit-telnet-0.17/MCONFIG'? y
[root@fortycoupe] /opt/tops/usr/telnetd # 

Compiling telnetd by running the make that is its own directory:
[root@fortycoupe] /opt/tops/usr/telnetd # cd /usr/local/netkit-telnet-0.17/telnetd
[root@fortycoupe] /usr/local/netkit-telnet-0.17/telnetd # make clean;make

This time the compilation worked.  

Here is the compiled telnetd program, and tests like those shown above
confirm that it runs fine:
[root@fortycoupe] /usr/local/netkit-telnet-0.17/telnetd # ls -alF telnetd
-rwxr-xr-x  1 root root 49207 Aug  6 11:32 telnetd*
[root@fortycoupe] /usr/local/netkit-telnet-0.17/telnetd # file telnetd
telnetd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0, dynamically linked (uses shared libs), not stripped
[root@fortycoupe] /usr/local/netkit-telnet-0.17/telnetd # 

Run step 2 above to create the wrapper program for a regular user.
