TCP Send Expect - make a chat over a TCP/IP connection
author: Giuseppe Zanetti
        (c) 1996 PROFUSO
        beppe@profuso.com, beppe@iperv.it, beppe@dei.unipd.it
        phone: ++348 2220811


SECURITY ALERT:

            *********************************************************
            If you put the chat in the command line (not using the -f
            option, anyone can see your password using "ps".

            DO NOT USE the command line if you send password !!!

            Use  the  -f  option  instead  and maintain you chat file
            protected from read, using "chmod 700 filename".
            *********************************************************

DISCLAIMER:

I'm not responsible for damnages. Use this program at your own risk !

DESCRIPTION

tcpsendexpect is a program that connects to a TCP port of a host and make a
chat. You can use it to automatize some operation on remote servers, for
example I use it to emulate a connection via telnet to a Cisco terminal
server for killing users that are not allowed. You can use it to retrieve
e-mail or news from your host or to make some remote operations, sending
commands directly to a login session. You can use to write simple clients for
some internet protocols, for example a single line WWW page retriever (I use it
to retrieve meteo maps via crontab) or a simple pop client writted in shell
language.

This is a little brick, that you can use to build the wall that you want.

LICENSE

This program is released under the GNU GPL. If you want include it on a CDROM
or on a commercial product, I whould appreciate a free copy.

INSTALLATION

Compile the program with

	make

and install it with

	make install

USAGE

This is the description of the command line parameters accepted. Note that
the chat is in the command line. In a future release you will allowed to use
a file instead. Note that you can select only a part of the output of the
program, using \o and \f in the chat. Note that you can use an impossible
expect string to wait at infinite, for example for the close of the connection
(see the WWW page retriving in the examples).

Usage: ./tcpsendexpect [-options] send1 expect1 send2 expect2 ...

   -hhost     the address of the remote host to use
   -pport     the remote TCP port to use (default=23)
   -ffilename use the file <filename> for reading chat (see README)
   -v         be verbose (use -v -v to be more verbose)
   -o         write remote output to stdout (redirection via > is a good idea)
   -i         write my input to stdout (redirection via > is a good idea)
   -I         as -1, but write in bold on a vt100 compatible terminal
   -7         use 7 bits
   -?         this help

   in send you can use these escape codes:
   \n        Line Feed (ASCII 10)
   \r        Carriage return (ASCII 13)
   \[        send ESC (ASCII 27)
   \o        enable output (see -o)
   \f        disable output

by Giuseppe Zanetti (beppe@profuso.com, beppe@dei.unipd.it, beppe@iperv.it)

EXAMPLES

You can use this program for example to get a WWW page. The HTTP protocol say
that you must connect to the TCP port 80 of the server and send to the httpd
the request as "GET /page HTTP/1.0" followed by two new line. You can make this
via tcpsendexpect as:

	tcpsendexpect -o -hwww.profuso.com -p80 "GET /PROFUSO/ HTTP/1.0\n\n" "WAIT THE END"

Not the use of the WAIT THE END expect string, to wait up to the end of the
connection from the remote server (you can use another string that you are
sure do not encounter in the output, for example "TCPSENDEXPECT IS A WONDERFULL
PROGRAM" :-)

To see what the program make, use twiche the -v switch (do not use the
-o option in this case, or you will obtain a double output, because -v writes
on the standard error and -o on the standard output).

	tcpsendexpect -v -v -hwww.profuso.com -p80 "GET /PROFUSO/ HTTP/1.0\n\n" "THE END"

If you use a proxy, you must connect to the proxy port, for example 8080 and
use a modified syntax for the request, with the complete URL:

	tcpsendexpect -o -hproxy.iperv.it -p8080 "GET http://www.profuso.com/PROFUSO/ HTTP/1.0\n\n" "THE END"

If you has to make batch operations, for example touch a file on a remote host,
you can omit the -o switch (but you must be sure that the program works ok).

See more (very usefull) examples in one of the next sessions... before you must
apply the simple patch that follows to your Linux box...

TELNET ... NOT SO SIMPLE

You will note that you cannot connect directly to the telnet port (23) or to
the rlogin one, because both protocols need to pass some information. You can
solve the problem creating a new service, that I call "mytelnetd", on your
machine. Mytelnetd emulates a rsh and has a little bug: it prompts directly for
a password, not the login name. You can bypass this problem sending a new line.
You can obtain this initiating the chat with "ssword:" "\n"

To make the mytelnetd service to work, you need to add this line to the
/etc/services configuration file:

	mytelnetd	9000/tcp

and this to inetd.conf:

	mytelnetd stream	tcp	nowait	daemon	/usr/sbin/tcpd	/usr/local/bin/mytelnetd

Now you must to restart inetd with a

	kill -HUP <inetd PID>

or a system reboot, to activate the service.

*** Do not modify the mytelnetd script, or you can obtain a security hole ***

I hope that mytelnetd, as is, is is not a security bug, but I'n not sure 100%.
I do not accept any responsability. Use at your own risk.

MORE EXAMPLES

Now you can simulate a true telnet using the port 9000 as a proxy. Remember the
raccomendation about the strange behaviour of mytelnetd in the previous chapter
and begin your chat waiting a password (this example connects to a remote host
and makes a who):

	tcpsendexpect -v -v -hlocalhost -p9000 "" "ssword:" "\n" "ogin:" "root\n" "ssword:" "your password\n" "#" "telnet freddy\n" "ogin:" "beppe\n" "ssword:" "your password\n" "$" "who\n" "$" "exit\n" "#" "exit\n" "THE END"

WARNING: this ^^^ has a security hole, because anyone can see your password
         using the "ps" command. Use the -f version instead: create a file
         with the chat (one word for every line), read protect it for anyone
         else you and use:

         	tcpsendexpect -v -v -hlocalhost -p9000 -f/tmp/who.chat

         In this example the file /tmp/who.chat appears as:

         	----------- /tmp/who.chat ------------
			
			ssword:
			\n
			ogin:
			root\n
			ssword:
			your password\n
			#
			telnet freddy\n
			ogin:
			beppe\n
			ssword:
			your password\n
			$
			who\n
			$
			exit\n
			#
			exit\n
			WAIT THE END
         	--------------------------------------


When the script works without problems, you can omit the -v switches and
use -o. If you do not want the output, do not use the -o at all (for example
if you need only to touch a file).

	tcpsendexpect -v -v -hlocalhost -p9000 "" "ssword:" "\n" "ogin:" "root\n" "ssword:" "your password\n" "#" "telnet freddy\n" "ogin:" "beppe\n" "ssword:" "your password\n" "$" "touch .last\n" "$" "exit\n" "#" "exit\n" "THE END"

WARNING: this ^^^ has a security hole ... make yourself a -f version...

I use it to open a xterminal on a remote host (alpha) on my machine (freddy):

	xhost + alpha ; tcpsendexpect -p9000 "" "sword:" "\n" "ogin:" "beppe\n" "ssword:" "your password\n" "$" "telnet alpha\n" "ogin:" "beppe\n" "ssword:" "your password\n" "$" "xterm -display freddy:0 &\n" "$" "exit\n" "$" "exit\n" "THE END"

WARNING: this ^^^ has a security hole ... make yourself a -f version...

Get the date from a remote host:

	tcpsendexpect -o -hsunsite.unc.edu -p13 "" "AHG"

and use it to set your date:

	date -s "`tcpsendexpect -o -hclock.mydomain.it -p13 '' AHG`"

Get some characters from a remote host:

	tcpsendexpect -o -hfreddy -p19 "" "z"

Wow, another finger client:

	tcpsendexpect -o -hmaya.dei.unipd.it -p79 "beppe\n" "THE END"

BUGS

- The length of the received buffer in tcp_receive can be a problem if
  it saturate.

- My english :-)

