Skip to content

Instantly share code, notes, and snippets.

@ohga
Last active December 6, 2017 08:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ohga/2020546d88da27e0f6246a4152892287 to your computer and use it in GitHub Desktop.
Save ohga/2020546d88da27e0f6246a4152892287 to your computer and use it in GitHub Desktop.
diff -Nur ucspi-tcp-0.88.old/FILES ucspi-tcp-0.88.new/FILES
--- ucspi-tcp-0.88.old/FILES 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/FILES 2017-03-28 00:07:10.698623245 +0000
@@ -216,3 +216,19 @@
warn-auto.sh
warn-shsgr
x86cpuid.c
+addcr.1
+argv0.1
+date@.1
+delcr.1
+finger@.1
+fixcrio.1
+http@.1
+mconnect.1
+recordio.1
+tcpcat.1
+tcpclient.1
+tcprules.1
+tcprulescheck.1
+tcpserver.1
+who@.1
+tcp-environ.5
diff -Nur ucspi-tcp-0.88.old/Makefile ucspi-tcp-0.88.new/Makefile
--- ucspi-tcp-0.88.old/Makefile 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/Makefile 2017-03-28 00:07:10.698623245 +0000
@@ -1,13 +1,25 @@
# Don't edit Makefile! Use conf-* for configuration.
+DEFINES=-DWITH_SSL
+#add -DWITH_SSL to enable ssl support
+
+# LIBS for additional libraries and INCS for additional includes
+LIBS=-lcrypto -lssl
+#INCS=-I/usr/local/include
+OPENSSLBIN=openssl
+
SHELL=/bin/sh
-default: it
+default: it man
addcr: \
load addcr.o unix.a byte.a
./load addcr unix.a byte.a
+addcr.0: \
+addcr.1
+ nroff -man addcr.1 > addcr.0
+
addcr.o: \
compile addcr.c buffer.h exit.h
./compile addcr.c
@@ -24,6 +36,10 @@
load argv0.o unix.a byte.a
./load argv0 unix.a byte.a
+argv0.0: \
+argv0.1
+ nroff -man argv0.1 > argv0.0
+
argv0.o: \
compile argv0.c pathexec.h strerr.h
./compile argv0.c
@@ -151,6 +167,10 @@
> choose
chmod 755 choose
+clean: \
+TARGETS
+ rm -f `cat TARGETS`
+
commands.o: \
compile commands.c buffer.h stralloc.h gen_alloc.h str.h case.h \
commands.h
@@ -170,10 +190,18 @@
> date@
chmod 755 date@
+date@.0: \
+date@.1
+ nroff -man date@.1 > date@.0
+
delcr: \
load delcr.o unix.a byte.a
./load delcr unix.a byte.a
+delcr.0: \
+delcr.1
+ nroff -man delcr.1 > delcr.0
+
delcr.o: \
compile delcr.c buffer.h exit.h
./compile delcr.c
@@ -292,10 +320,18 @@
> finger@
chmod 755 finger@
+finger@.0: \
+finger@.1
+ nroff -man finger@.1 > finger@.0
+
fixcrio: \
load fixcrio.o time.a unix.a byte.a
./load fixcrio time.a unix.a byte.a
+fixcrio.0: \
+fixcrio.1
+ nroff -man fixcrio.1 > fixcrio.0
+
fixcrio.o: \
compile fixcrio.c sig.h buffer.h strerr.h byte.h readwrite.h exit.h \
iopause.h taia.h tai.h uint64.h pathexec.h
@@ -346,6 +382,10 @@
> http@
chmod 755 http@
+http@.0: \
+http@.1
+ nroff -man http@.1 > http@.0
+
install: \
load install.o hier.o auto_home.o unix.a byte.a
./load install hier.o auto_home.o unix.a byte.a
@@ -409,6 +449,11 @@
) > makelib
chmod 755 makelib
+man: \
+tcpclient.0 tcpserver.0 tcprules.0 tcprulescheck.0 tcp-environ.0 \
+who@.0 date@.0 finger@.0 http@.0 tcpcat.0 mconnect.0 fixcrio.0 addcr.0 \
+delcr.0 argv0.0 recordio.0
+
mconnect: \
warn-auto.sh mconnect.sh conf-home
cat warn-auto.sh mconnect.sh \
@@ -425,6 +470,10 @@
readwrite.h exit.h
./compile mconnect-io.c
+mconnect.0: \
+mconnect.1
+ nroff -man mconnect.1 > mconnect.0
+
ndelay_off.o: \
compile ndelay_off.c ndelay.h
./compile ndelay_off.c
@@ -495,6 +544,10 @@
exit.h fmt.h iopause.h taia.h tai.h uint64.h pathexec.h
./compile recordio.c
+recordio.0: \
+recordio.1
+ nroff -man recordio.1 > recordio.0
+
remoteinfo.o: \
compile remoteinfo.c fmt.h buffer.h socket.h uint16.h error.h \
iopause.h taia.h tai.h uint64.h timeoutconn.h uint16.h remoteinfo.h \
@@ -702,6 +755,10 @@
compile taia_uint.c taia.h tai.h uint64.h
./compile taia_uint.c
+tcp-environ.0: \
+tcp-environ.5
+ nroff -man tcp-environ.5 > tcp-environ.0
+
tcpcat: \
warn-auto.sh tcpcat.sh conf-home
cat warn-auto.sh tcpcat.sh \
@@ -709,12 +766,20 @@
> tcpcat
chmod 755 tcpcat
+tcpcat.0: \
+tcpcat.1
+ nroff -man tcpcat.1 > tcpcat.0
+
tcpclient: \
load tcpclient.o remoteinfo.o timeoutconn.o dns.a time.a unix.a \
byte.a socket.lib
./load tcpclient remoteinfo.o timeoutconn.o dns.a time.a \
unix.a byte.a `cat socket.lib`
+tcpclient.0: \
+tcpclient.1
+ nroff -man tcpclient.1 > tcpclient.0
+
tcpclient.o: \
compile tcpclient.c sig.h exit.h sgetopt.h subgetopt.h uint16.h fmt.h \
scan.h str.h ip4.h uint16.h socket.h uint16.h fd.h stralloc.h \
@@ -727,6 +792,10 @@
load tcprules.o cdb.a unix.a byte.a
./load tcprules cdb.a unix.a byte.a
+tcprules.0: \
+tcprules.1
+ nroff -man tcprules.1 > tcprules.0
+
tcprules.o: \
compile tcprules.c strerr.h stralloc.h gen_alloc.h getln.h buffer.h \
stralloc.h buffer.h exit.h fmt.h byte.h cdb_make.h buffer.h uint32.h
@@ -736,6 +805,10 @@
load tcprulescheck.o rules.o cdb.a unix.a byte.a
./load tcprulescheck rules.o cdb.a unix.a byte.a
+tcprulescheck.0: \
+tcprulescheck.1
+ nroff -man tcprulescheck.1 > tcprulescheck.0
+
tcprulescheck.o: \
compile tcprulescheck.c byte.h buffer.h strerr.h env.h rules.h \
stralloc.h gen_alloc.h
@@ -745,7 +818,11 @@
load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a \
time.a unix.a byte.a socket.lib
./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \
- dns.a time.a unix.a byte.a `cat socket.lib`
+ dns.a time.a unix.a byte.a $(LIBS) `cat socket.lib`
+
+tcpserver.0: \
+tcpserver.1
+ nroff -man tcpserver.1 > tcpserver.0
tcpserver.o: \
compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
@@ -754,7 +831,7 @@
socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \
stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \
taia.h
- ./compile tcpserver.c
+ ./compile $(DEFINES) $(INCS) tcpserver.c
time.a: \
makelib iopause.o tai_pack.o taia_add.o taia_approx.o taia_frac.o \
@@ -835,3 +912,22 @@
| sed s}HOME}"`head -1 conf-home`"}g \
> who@
chmod 755 who@
+
+who@.0: \
+who@.1
+ nroff -man who@.1 > who@.0
+
+cert:
+ ${OPENSSLBIN} req -new -x509 -nodes \
+ -out cert.pem -days 366 \
+ -keyout cert.pem
+
+cert-req:
+ ${OPENSSLBIN} req -new -nodes \
+ -out req.pem \
+ -keyout cert.pem
+ @echo
+ @echo "Send req.pem to your CA to obtain signed_req.pem, and do:"
+ @echo "cat signed_req.pem >> `head -1 conf-qmail`/control/cert.pem"
+
+
diff -Nur ucspi-tcp-0.88.old/TARGETS ucspi-tcp-0.88.new/TARGETS
--- ucspi-tcp-0.88.old/TARGETS 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/TARGETS 2017-03-28 00:07:10.698623245 +0000
@@ -169,3 +169,19 @@
it
setup
check
+addcr.0
+argv0.0
+date@.0
+delcr.0
+finger@.0
+fixcrio.0
+http@.0
+mconnect.0
+recordio.0
+tcp-environ.0
+tcpcat.0
+tcpclient.0
+tcprules.0
+tcprulescheck.0
+tcpserver.0
+who@.0
diff -Nur ucspi-tcp-0.88.old/addcr.1 ucspi-tcp-0.88.new/addcr.1
--- ucspi-tcp-0.88.old/addcr.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/addcr.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,22 @@
+.TH addcr 1
+.SH NAME
+addcr \- add a CR before each LF
+.SH SYNOPSIS
+.B addcr
+.SH DESCRIPTION
+.B addcr
+inserts CR at the end of each line of input.
+It does not insert CR at the end of a partial final line.
+.SH COMPATIBILITY
+Some vendors ship
+.B unix2dos
+or
+.B bsd2dos
+tools similar to
+.BR addcr .
+Those tools often blow up on long lines and nulls.
+.B addcr
+has no trouble with long lines and nulls.
+.SH "SEE ALSO"
+delcr(1),
+fixcrio(1)
diff -Nur ucspi-tcp-0.88.old/argv0.1 ucspi-tcp-0.88.new/argv0.1
--- ucspi-tcp-0.88.old/argv0.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/argv0.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,47 @@
+.TH argv0 1
+.SH NAME
+argv0 \- run a program with a specified 0th argument
+.SH SYNOPSIS
+.B argv0
+.I realname
+.I zero
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B argv0
+runs
+the program stored as
+.I realname
+on disk,
+with the given
+arguments.
+It sets the 0th argument of
+the program to
+.IR zero .
+
+For example,
+
+.EX
+ argv0 /bin/csh -bin/csh
+.EE
+
+runs
+.B /bin/csh
+with a 0th argument of
+.BR -bin/csh .
+.B csh
+will think it is a login shell
+and behave accordingly.
+
+.B argv0
+can be used to run some
+.B inetd
+wrappers under
+.BR tcpserver .
+.SH "SEE ALSO"
+csh(1),
+tcpserver(1),
+execve(2),
+execvp(3),
+inetd(8)
diff -Nur ucspi-tcp-0.88.old/conf-cc ucspi-tcp-0.88.new/conf-cc
--- ucspi-tcp-0.88.old/conf-cc 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/conf-cc 2017-03-28 00:07:38.286162374 +0000
@@ -1,3 +1,3 @@
-gcc -O2
+gcc -O2 --include /usr/include/errno.h
This will be used to compile .c files.
diff -Nur ucspi-tcp-0.88.old/date@.1 ucspi-tcp-0.88.new/date@.1
--- ucspi-tcp-0.88.old/date@.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/date@.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,32 @@
+.TH date@ 1
+.SH NAME
+date@ \- print the date on a host
+.SH SYNTAX
+.B date@
+[
+.I host
+]
+.SH DESCRIPTION
+.B date@
+connects to TCP port 13 (Daytime) on
+.I host
+and prints any data it receives.
+It removes CR and converts unprintable characters to a visible format.
+
+If
+.I host
+is not supplied,
+.B date@
+connects to the local host.
+
+Some computers respond to port 13 with a human-readable date.
+For example, they may be running
+
+.EX
+ tcpserver 0 13 date &
+.EE
+.SH "SEE ALSO"
+cat(1),
+delcr(1),
+tcpclient(1),
+tcpserver(1)
diff -Nur ucspi-tcp-0.88.old/delcr.1 ucspi-tcp-0.88.new/delcr.1
--- ucspi-tcp-0.88.old/delcr.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/delcr.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,30 @@
+.TH delcr 1
+.SH NAME
+delcr \- remove a CR before each LF
+.SH SYNOPSIS
+.B delcr
+.SH DESCRIPTION
+.B delcr
+removes a CR at the end of each line of input,
+if a CR is present.
+It also removes a CR at the end of a partial final line.
+
+The pipeline
+
+.EX
+ addcr | delcr
+.EE
+
+prints an exact copy of its input.
+.SH COMPATIBILITY
+Some vendors ship
+.B dos2unix
+or
+.B dos2bsd
+tools similar to
+.BR delcr .
+Those tools often blow up on long lines and nulls.
+.B delcr
+has no trouble with long lines and nulls.
+.SH "SEE ALSO"
+addcr(1)
diff -Nur ucspi-tcp-0.88.old/error.h ucspi-tcp-0.88.new/error.h
--- ucspi-tcp-0.88.old/error.h 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/error.h 2017-03-28 00:07:10.698623245 +0000
@@ -1,7 +1,7 @@
#ifndef ERROR_H
#define ERROR_H
-extern int errno;
+#include <errno.h>
extern int error_intr;
extern int error_nomem;
diff -Nur ucspi-tcp-0.88.old/finger@.1 ucspi-tcp-0.88.new/finger@.1
--- ucspi-tcp-0.88.old/finger@.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/finger@.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,45 @@
+.TH finger@ 1
+.SH NAME
+finger@ \- get user information from a host
+.SH SYNTAX
+.B finger@
+[
+.I host
+[
+.I user
+]
+]
+.SH DESCRIPTION
+.B finger@
+connects to TCP port 79 (Finger) on
+.IR host ,
+sends
+.I user
+(with an extra CR)
+to
+.IR host ,
+and prints any data it receives.
+It removes CR and converts unprintable characters to a visible format.
+Some computers respond to port 79 with information about
+.IR user .
+
+If
+.I user
+is not supplied,
+.B finger@
+sends a blank line to
+.IR host .
+Some computers respond with information about
+all the users who are logged in.
+
+If
+.I host
+is not supplied,
+.B finger@
+connects to the local host.
+.SH "SEE ALSO"
+addcr(1),
+cat(1),
+delcr(1),
+finger(1),
+tcpclient(1)
diff -Nur ucspi-tcp-0.88.old/fixcrio.1 ucspi-tcp-0.88.new/fixcrio.1
--- ucspi-tcp-0.88.old/fixcrio.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/fixcrio.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,15 @@
+.TH fixcrio 1
+.SH NAME
+fixcrio \- make sure that there is a CR before each LF
+.SH SYNOPSIS
+.B fixcrio
+.I program
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B fixcrio
+inserts CR at the end of each line of input where a CR is not already present.
+It does not insert CR at the end of a partial final line.
+.SH "SEE ALSO"
+addcr(1)
diff -Nur ucspi-tcp-0.88.old/hier.c ucspi-tcp-0.88.new/hier.c
--- ucspi-tcp-0.88.old/hier.c 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/hier.c 2017-03-28 00:07:10.698623245 +0000
@@ -2,8 +2,13 @@
void hier()
{
- h(auto_home,-1,-1,02755);
- d(auto_home,"bin",-1,-1,02755);
+ h(auto_home,-1,-1,0755);
+ d(auto_home,"bin",-1,-1,0755);
+ d(auto_home,"man",-1,-1,0755);
+ d(auto_home,"man/man1",-1,-1,0755);
+ d(auto_home,"man/man5",-1,-1,0755);
+ d(auto_home,"man/cat1",-1,-1,0755);
+ d(auto_home,"man/cat5",-1,-1,0755);
c(auto_home,"bin","tcpserver",-1,-1,0755);
c(auto_home,"bin","tcprules",-1,-1,0755);
@@ -22,4 +27,37 @@
c(auto_home,"bin","delcr",-1,-1,0755);
c(auto_home,"bin","fixcrio",-1,-1,0755);
c(auto_home,"bin","rblsmtpd",-1,-1,0755);
+
+ c(auto_home,"man/man1","addcr.1",-1,-1,0644);
+ c(auto_home,"man/cat1","addcr.0",-1,-1,0644);
+ c(auto_home,"man/man1","argv0.1",-1,-1,0644);
+ c(auto_home,"man/cat1","argv0.0",-1,-1,0644);
+ c(auto_home,"man/man1","date@.1",-1,-1,0644);
+ c(auto_home,"man/cat1","date@.0",-1,-1,0644);
+ c(auto_home,"man/man1","delcr.1",-1,-1,0644);
+ c(auto_home,"man/cat1","delcr.0",-1,-1,0644);
+ c(auto_home,"man/man1","finger@.1",-1,-1,0644);
+ c(auto_home,"man/cat1","finger@.0",-1,-1,0644);
+ c(auto_home,"man/man1","fixcrio.1",-1,-1,0644);
+ c(auto_home,"man/cat1","fixcrio.0",-1,-1,0644);
+ c(auto_home,"man/man1","http@.1",-1,-1,0644);
+ c(auto_home,"man/cat1","http@.0",-1,-1,0644);
+ c(auto_home,"man/man1","mconnect.1",-1,-1,0644);
+ c(auto_home,"man/cat1","mconnect.0",-1,-1,0644);
+ c(auto_home,"man/man1","recordio.1",-1,-1,0644);
+ c(auto_home,"man/cat1","recordio.0",-1,-1,0644);
+ c(auto_home,"man/man1","tcpcat.1",-1,-1,0644);
+ c(auto_home,"man/cat1","tcpcat.0",-1,-1,0644);
+ c(auto_home,"man/man1","tcpclient.1",-1,-1,0644);
+ c(auto_home,"man/cat1","tcpclient.0",-1,-1,0644);
+ c(auto_home,"man/man1","tcprules.1",-1,-1,0644);
+ c(auto_home,"man/cat1","tcprules.0",-1,-1,0644);
+ c(auto_home,"man/man1","tcprulescheck.1",-1,-1,0644);
+ c(auto_home,"man/cat1","tcprulescheck.0",-1,-1,0644);
+ c(auto_home,"man/man1","tcpserver.1",-1,-1,0644);
+ c(auto_home,"man/cat1","tcpserver.0",-1,-1,0644);
+ c(auto_home,"man/man1","who@.1",-1,-1,0644);
+ c(auto_home,"man/cat1","who@.0",-1,-1,0644);
+ c(auto_home,"man/man5","tcp-environ.5",-1,-1,0644);
+ c(auto_home,"man/cat5","tcp-environ.0",-1,-1,0644);
}
diff -Nur ucspi-tcp-0.88.old/http@.1 ucspi-tcp-0.88.new/http@.1
--- ucspi-tcp-0.88.old/http@.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/http@.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,52 @@
+.TH http@ 1
+.SH NAME
+http@ \- get a web page from a host through HTTP
+.SH SYNTAX
+.B http@
+[
+.I host
+[
+.I page
+[
+.I port
+]
+]
+]
+.SH DESCRIPTION
+.B http@
+connects to
+.I port
+on
+.IR host ,
+sends
+.B GET /\fIpage
+(with an extra CR)
+to
+.IR host ,
+and prints any data it receives,
+removing CR from the end of each line.
+
+If
+.I port
+is not supplied,
+.B http@
+uses port 80 (HTTP).
+
+If
+.I page
+is not supplied,
+.B http@
+sends
+.B GET /
+to
+.IR host .
+
+If
+.I host
+is not supplied,
+.B http@
+connects to the local host.
+.SH "SEE ALSO"
+addcr(1),
+delcr(1),
+tcpclient(1)
diff -Nur ucspi-tcp-0.88.old/mconnect.1 ucspi-tcp-0.88.new/mconnect.1
--- ucspi-tcp-0.88.old/mconnect.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/mconnect.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,36 @@
+.TH mconnect 1
+.SH NAME
+mconnect \- connect to the SMTP server on a host
+.SH SYNTAX
+.B mconnect
+[
+.I host
+[
+.I port
+]
+]
+.SH DESCRIPTION
+.B mconnect
+connects to
+.I port
+on
+.IR host .
+It sends its input to
+.IR host ,
+adding a CR to each line.
+Meanwhile it prints anything it receives from
+.IR host .
+
+If
+.I port
+is not supplied,
+.B mconnect
+uses port 25 (SMTP).
+
+If
+.I host
+is not supplied,
+.B mconnect
+connects to the local host.
+.SH "SEE ALSO"
+tcpclient(1)
diff -Nur ucspi-tcp-0.88.old/recordio.1 ucspi-tcp-0.88.new/recordio.1
--- ucspi-tcp-0.88.old/recordio.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/recordio.1 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,75 @@
+.TH recordio 1
+.SH NAME
+recordio \- record the input and output of a program
+.SH SYNTAX
+.B recordio
+.I program
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B recordio
+runs
+.I program
+with the given arguments.
+It prints lines to stderr
+showing the input and output of
+.IR program .
+
+At the beginning of each line on stderr,
+.B recordio
+inserts the
+.I program
+process ID,
+along with
+.B <
+for input or
+.B >
+for output.
+At the end of each line it inserts a space, a plus sign, or [EOF];
+a space indicates that there was a newline in the input or output,
+and [EOF] indicates the end of input or output.
+
+.B recordio
+prints every packet of input and output immediately.
+It does not attempt to combine packets into coherent stderr lines.
+For example,
+
+.EX
+ recordio sh -c 'cat /dev/fd/8 2>&1' > /dev/null
+.EE
+
+could produce
+
+.EX
+ 5135 > cat: /dev/fd/8: Bad file descriptor
+.br
+ 5135 > [EOF]
+.EE
+
+or
+
+.EX
+ 5135 > cat: +
+.br
+ 5135 > /dev/fd/8+
+.br
+ 5135 > : +
+.br
+ 5135 > Bad file descriptor
+.br
+ 5135 > [EOF]
+.EE
+
+.B recordio
+uses several lines for long packets
+to guarantee that each line is printed atomically to stderr.
+
+.B recordio
+runs as a child of
+.IR program .
+It exits when it sees the end of
+.IR program 's
+output.
+.SH "SEE ALSO"
+tcpserver(1)
diff -Nur ucspi-tcp-0.88.old/tcp-environ.5 ucspi-tcp-0.88.new/tcp-environ.5
--- ucspi-tcp-0.88.old/tcp-environ.5 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcp-environ.5 2017-03-28 00:07:10.698623245 +0000
@@ -0,0 +1,62 @@
+.TH tcp-environ 5
+.SH NAME
+tcp-environ \- TCP-related environment variables
+.SH DESCRIPTION
+The following environment variables
+describe a TCP connection.
+They are set up by
+.BR tcp-env ,
+.BR tcpclient ,
+and
+.BR tcpserver .
+Note that
+.BR TCPLOCALHOST ,
+.BR TCPREMOTEHOST ,
+and
+.B TCPREMOTEINFO
+can contain arbitrary characters.
+.TP 5
+PROTO
+The string
+.BR TCP .
+.TP 5
+TCPLOCALHOST
+The domain name of the local host,
+with uppercase letters converted to lowercase.
+If there is no currently available domain name
+for the local IP address,
+.B TCPLOCALHOST
+is not set.
+.TP 5
+TCPLOCALIP
+The IP address of the local host, in dotted-decimal form.
+.TP 5
+TCPLOCALPORT
+The local TCP port number, in decimal.
+.TP 5
+TCPREMOTEHOST
+The domain name of the remote host,
+with uppercase letters converted to lowercase.
+If there is no currently available domain name
+for the remote IP address,
+.B TCPREMOTEHOST
+is not set.
+.TP 5
+TCPREMOTEINFO
+A connection-specific string, perhaps a username,
+supplied by the remote host
+via 931/1413/IDENT/TAP.
+If the remote host did not supply connection information,
+.B TCPREMOTEINFO
+is not set.
+.TP 5
+TCPREMOTEIP
+The IP address of the remote host.
+.TP 5
+TCPREMOTEPORT
+The remote TCP port number.
+.SH "SEE ALSO"
+tcpclient(1),
+tcpserver(1),
+tcp-env(1),
+tcp(4)
diff -Nur ucspi-tcp-0.88.old/tcpcat.1 ucspi-tcp-0.88.new/tcpcat.1
--- ucspi-tcp-0.88.old/tcpcat.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcpcat.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,20 @@
+.TH tcpcat 1
+.SH NAME
+tcpcat \- print data from a TCP port
+.SH SYNTAX
+.B tcpcat
+.I host
+.I port
+.SH DESCRIPTION
+.B tcpcat
+connects to
+.I port
+on
+.I host
+and prints any data it receives.
+
+.B tcpcat
+can be used to transfer binary data.
+It does no conversions.
+.SH "SEE ALSO"
+tcpclient(1)
diff -Nur ucspi-tcp-0.88.old/tcpclient.1 ucspi-tcp-0.88.new/tcpclient.1
--- ucspi-tcp-0.88.old/tcpclient.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcpclient.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,151 @@
+.TH tcpclient 1
+.SH NAME
+tcpclient \- create an outgoing TCP connection
+.SH SYNOPSIS
+.B tcpclient
+[
+.B \-hHrRdDqQv
+]
+[
+.B \-i\fIlocalip
+]
+[
+.B \-p\fIlocalport
+]
+[
+.B \-T\fItimeoutconn
+]
+[
+.B \-l\fIlocalname
+]
+[
+.B \-t\fItimeoutinfo
+]
+.I host
+.I port
+.I program
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B tcpclient
+attempts to connect to a TCP server.
+If it is successful, it runs
+.I program
+with the given arguments,
+with descriptor 6 reading from the network
+and descriptor 7 writing to the network.
+
+The server's address is given by
+.I host
+and
+.IR port .
+.I host
+may be 0, referring to the local machine,
+or a dotted-decimal IP address,
+or a host name;
+if a host has several IP addresses,
+.B tcpclient
+tries each in turn.
+.I port
+may be a numeric port number
+or a port name.
+
+.B tcpclient
+sets up several environment variables,
+as described in
+.B tcp-environ(5).
+.SH OPTIONS
+.TP
+.B \-i\fIlocalip
+Use
+.I localip
+as the IP address for the local side of the connection;
+quit if
+.I localip
+is not available.
+.TP
+.B \-p\fIlocalport
+Use
+.I localport
+as the port number for the local side of the connection;
+quit if
+.I localport
+is not available.
+.TP
+.B \-T\fItimeoutconn
+Give up on the
+connection attempt
+after
+.I timeoutconn
+seconds. Default: 60.
+This timeout applies to each IP address tried.
+.TP
+.B \-d
+(Default.)
+Delay sending data for a fraction of a second whenever the
+remote host is responding slowly,
+to make better use of the network.
+.TP
+.B \-D
+Never delay sending data;
+enable TCP_NODELAY.
+This is appropriate for interactive connections.
+.TP
+.B \-q
+Quiet.
+Do not print any messages.
+.TP
+.B \-Q
+(Default.)
+Print error messages.
+.TP
+.B \-v
+Verbose.
+Print all available messages.
+.SH "DATA-GATHERING OPTIONS"
+.TP
+.B \-h
+(Default.)
+Look up the remote host name for
+.BR TCPREMOTEHOST .
+.TP
+.B \-H
+Do not look up the remote host name;
+unset
+.BR TCPREMOTEHOST .
+.TP
+.B \-l\fIlocalname
+Do not look up the local host name;
+use
+.I localname
+for
+.BR TCPLOCALHOST .
+.TP
+.B \-r
+(Default.)
+Attempt to obtain
+.B TCPREMOTEINFO
+from the remote host.
+.TP
+.B \-R
+Do not attempt to obtain
+.B TCPREMOTEINFO
+from the remote host.
+.TP
+.B \-t\fItimeoutinfo
+Give up on the
+.B TCPREMOTEINFO
+connection attempt
+after
+.I timeoutinfo
+seconds. Default: 26.
+.SH "SEE ALSO"
+date@(1),
+finger@(1),
+http@(1),
+mconnect(1),
+tcpcat(1),
+tcpserver(1),
+who@(1),
+tcp-environ(5)
diff -Nur ucspi-tcp-0.88.old/tcprules.1 ucspi-tcp-0.88.new/tcprules.1
--- ucspi-tcp-0.88.old/tcprules.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcprules.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,208 @@
+.TH tcprules 1
+.SH NAME
+tcprules \- compile rules for tcpserver
+.SH SYNOPSIS
+.B tcprules
+.I rules.cdb
+.I rules.tmp
+.SH OVERVIEW
+.B tcpserver
+optionally follows rules to decide whether a TCP connection is acceptable.
+For example, a rule of
+
+.EX
+ 18.23.0.32:deny
+.EE
+
+prohibits connections from IP address 18.23.0.32.
+
+.B tcprules
+reads rules from its standard input
+and writes them into
+.I rules.cdb
+in a binary format suited
+for quick access by
+.BR tcpserver .
+
+.B tcprules
+can be used while
+.B tcpserver
+is running:
+it ensures that
+.I rules.cdb
+is updated atomically.
+It does this by first writing the rules to
+.I rules.tmp
+and then moving
+.I rules.tmp
+on top of
+.IR rules.cdb .
+If
+.I rules.tmp
+already exists, it is destroyed.
+The directories containing
+.I rules.cdb
+and
+.I rules.tmp
+must be writable to
+.BR tcprules ;
+they must also be on the same filesystem.
+
+If there is a problem with the input,
+.B tcprules
+complains and leaves
+.I rules.cdb
+alone.
+
+The binary
+.I rules.cdb
+format is portable across machines.
+.SH "RULE FORMAT"
+A rule takes up one line.
+A file containing rules
+may also contain comments: lines beginning with # are ignored.
+
+Each rule contains an
+.BR address ,
+a colon,
+and a list of
+.BR instructions ,
+with no extra spaces.
+When
+.B tcpserver
+receives a connection from that address,
+it follows the instructions.
+.SH "ADDRESSES"
+.B tcpserver
+starts by looking for a rule with address
+.IR TCPREMOTEINFO\fB@\fITCPREMOTEIP .
+If it doesn't find one, or if
+.I TCPREMOTEINFO
+is not set, it tries the address
+.IR TCPREMOTEIP .
+If that doesn't work, it tries shorter and shorter prefixes of
+.I TCPREMOTEIP
+ending with a dot.
+If none of them work, it tries the empty string.
+
+For example, here are some rules:
+
+.EX
+ joe@127.0.0.1:first
+.br
+ 18.23.0.32:second
+.br
+ 127.:third
+.br
+ :fourth
+.EE
+
+If
+.I TCPREMOTEIP
+is
+.BR 10.119.75.38 ,
+.B tcpserver
+will follow the
+.B fourth
+instructions.
+
+If
+.I TCPREMOTEIP
+is
+.BR 18.23.0.32 ,
+.B tcpserver
+will follow the
+.B second
+instructions.
+
+If
+.I TCPREMOTEINFO
+is
+.B bill
+and
+.I TCPREMOTEIP
+is
+.BR 127.0.0.1 ,
+.B tcpserver
+will follow the
+.B third
+instructions.
+
+If
+.I TCPREMOTEINFO
+is
+.B joe
+and
+.I TCPREMOTEIP
+is
+.BR 127.0.0.1 ,
+.B tcpserver
+will follow the
+.B first
+instructions.
+.SH "ADDRESS RANGES"
+.B tcprules
+treats
+.B 1.2.3.37-53:ins
+as an abbreviation
+for the rules
+.BR 1.2.3.37:ins ,
+.BR 1.2.3.38:ins ,
+and so on up through
+.BR 1.2.3.53:ins .
+Similarly,
+.BR 10.2-3.:ins
+is an abbreviation for
+.B 10.2.:ins
+and
+.BR 10.3.:ins .
+.SH "INSTRUCTIONS"
+The instructions in a rule must begin with either
+.B allow
+or
+.BR deny .
+.B deny
+tells
+.B tcpserver
+to drop the connection without running anything.
+For example, the rule
+
+.EX
+ :deny
+.EE
+
+tells
+.B tcpserver
+to drop all connections that aren't handled by more specific rules.
+
+The instructions may continue with some environment variables,
+in the format
+.IR ,VAR="VALUE" .
+.B tcpserver
+adds
+.I VAR=VALUE
+to the current environment.
+For example,
+
+.EX
+ 10.0.:allow,RELAYCLIENT="@fix.me"
+.EE
+
+adds
+.B RELAYCLIENT=@fix.me
+to the environment.
+The quotes here may be replaced by any repeated character:
+
+.EX
+ 10.0.:allow,RELAYCLIENT=/@fix.me/
+.EE
+
+Any number of variables may be listed:
+
+.EX
+ 127.0.0.1:allow,RELAYCLIENT="",TCPLOCALHOST="movie.edu"
+.EE
+.SH "SEE ALSO"
+tcprulescheck(1),
+tcpserver(1),
+tcp-environ(5)
diff -Nur ucspi-tcp-0.88.old/tcprules.c ucspi-tcp-0.88.new/tcprules.c
--- ucspi-tcp-0.88.old/tcprules.c 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/tcprules.c 2017-03-28 00:07:10.702623179 +0000
@@ -94,6 +94,7 @@
int len;
int fd;
int i;
+ int e;
char ch;
fn = argv[1];
@@ -144,8 +145,16 @@
while (len)
switch(*x) {
case ',':
+ e = byte_chr(x + 1,len - 1,',');
i = byte_chr(x,len,'=');
- if (i == len) die_bad();
+ if (i > e) {
+ if (e < 2 || x[1] != '!') die_bad();
+ if (!stralloc_catb(&data,"-",1)) nomem();
+ if (!stralloc_catb(&data,x + 2,e - 1)) nomem();
+ if (!stralloc_0(&data)) nomem();
+ x += e + 1; len -= e + 1;
+ break;
+ }
if (!stralloc_catb(&data,"+",1)) nomem();
if (!stralloc_catb(&data,x + 1,i)) nomem();
x += i + 1; len -= i + 1;
diff -Nur ucspi-tcp-0.88.old/tcprulescheck.1 ucspi-tcp-0.88.new/tcprulescheck.1
--- ucspi-tcp-0.88.old/tcprulescheck.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcprulescheck.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,25 @@
+.TH tcprulescheck 1
+.SH NAME
+tcprulescheck \- try out rules for tcpserver
+.SH SYNTAX
+.B tcprulescheck
+.I rules.cdb
+.I tcpremoteip
+[
+.I tcpremoteinfo
+]
+.SH DESCRIPTION
+.B tcprulescheck
+says what
+.B tcpserver
+will do with a connection from
+IP address
+.IR tcpremoteip ,
+following the rules compiled into
+.I rules.cdb
+by
+.BR tcprules .
+.SH "SEE ALSO"
+tcprules(1),
+tcpserver(1),
+tcp-environ(5)
diff -Nur ucspi-tcp-0.88.old/tcprulescheck.c ucspi-tcp-0.88.new/tcprulescheck.c
--- ucspi-tcp-0.88.old/tcprulescheck.c 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/tcprulescheck.c 2017-03-28 00:07:10.702623179 +0000
@@ -22,6 +22,11 @@
buffer_puts(buffer_1,data + 1);
buffer_puts(buffer_1,"\n");
break;
+ case '-':
+ buffer_puts(buffer_1,"unset environment variable ");
+ buffer_puts(buffer_1,data + 1);
+ buffer_puts(buffer_1,"\n");
+ break;
}
++next0;
data += next0; datalen -= next0;
diff -Nur ucspi-tcp-0.88.old/tcpserver.1 ucspi-tcp-0.88.new/tcpserver.1
--- ucspi-tcp-0.88.old/tcpserver.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/tcpserver.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,318 @@
+.TH tcpserver 1
+.SH NAME
+tcpserver \- accept incoming TCP connections
+.SH SYNOPSIS
+.B tcpserver
+[
+.B \-1UXpPhHrRoOdDqQsSv
+]
+[
+.B \-c\fIlimit
+]
+[
+.B \-C\fI[address[/len]:]limit
+]
+[
+.B \-e\fIname=[var]
+]
+[
+.B \-x\fIrules.cdb
+]
+[
+.B \-B\fIbanner
+]
+[
+.B \-g\fIgid
+]
+[
+.B \-u\fIuid
+]
+[
+.B \-b\fIbacklog
+]
+[
+.B \-l\fIlocalname
+]
+[
+.B \-t\fItimeout
+]
+[
+.B \-n\fIcertfile
+]
+.I host
+.I port
+.I program
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B tcpserver
+waits for connections from TCP clients.
+For each connection, it runs
+.I program
+with the given arguments,
+with descriptor 0 reading from the network
+and descriptor 1 writing to the network.
+
+The server's address is given by
+.I host
+and
+.IR port .
+.I host
+can be 0, allowing connections from any host;
+or a particular IP address,
+allowing connections only to that address;
+or a host name, allowing connections to the first IP address
+for that host.
+.I port
+may be a numeric port number
+or a port name.
+If
+.I port
+is 0,
+.B tcpserver
+will choose a free port.
+
+.B tcpserver
+sets up several environment variables,
+as described in
+.B tcp-environ(5).
+
+.B tcpserver
+exits when it receives SIGTERM.
+.SH "OPTIONS"
+.TP
+.B \-c\fIlimit
+Do not handle more than
+.I limit
+simultaneous connections.
+If there are
+.I limit
+simultaneous copies of
+.I program
+running, defer acceptance of a new connection
+until one copy finishes.
+.I limit
+must be a positive integer.
+Default: 40.
+.TP
+.B \-C\fI[address[/len]:]limit
+Do not handle more than
+.I limit
+connections from the specified address or prefix.
+If there is no address specified a generic per IP
+.I limit
+is enforced.
+It is possible to specify multiple
+.IR limits .
+These limits are evaluated in sequential order, from first to last.
+The first matching
+.I limit
+decides what action is taken.
+The only exception is the generic per IP
+.I limit
+which is always evaluated last.
+.TP
+.B \-e\fIname=[var]
+If a per address limit is hit instead of dropping the connection set the
+environment variable
+.I name
+with
+.I var
+as optional data.
+This may be handy with the qmail-ldap patched qmail-smtpd where setting
+the environment 421GREETING will result in a restricted SMTP session always
+returning a temporary error.
+.TP
+.B \-x\fIrules.cdb
+Follow the rules compiled into
+.I rules.cdb
+by
+.BR tcprules .
+These rules may specify setting environment variables
+or rejecting connections from bad sources.
+
+.B tcpserver
+does not read
+.I rules.cdb
+into memory;
+you can rerun
+.B tcprules
+to change
+.BR tcpserver 's
+behavior on the fly.
+.TP
+.B \-B\fIbanner
+Write
+.I banner
+to the network immediately after each connection is made.
+.B tcpserver
+writes
+.I banner
+before looking up
+.BR TCPREMOTEHOST ,
+before looking up
+.BR TCPREMOTEINFO ,
+and before checking
+.IR rules.cdb .
+
+This feature can be used to reduce latency in protocols
+where the client waits for a greeting from the server.
+.TP
+.B \-g\fIgid
+Switch group ID to
+.I gid
+after preparing to receive connections.
+.I gid
+must be a positive integer.
+.TP
+.B \-u\fIuid
+Switch user ID to
+.I uid
+after preparing to receive connections.
+.I uid
+must be a positive integer.
+.TP
+.B \-U
+Same as
+.B \-g\fI$GID
+.BR \-u\fI$UID .
+Typically
+.I $GID
+and
+.I $UID
+are set by envuidgid.
+.TP
+.B \-1
+After preparing to receive connections,
+print the local port number to standard output.
+.TP
+.B \-b\fIbacklog
+Allow up to
+.I backlog
+simultaneous SYN_RECEIVEDs.
+Default: 20.
+On some systems,
+.I backlog
+is silently limited to 5.
+See
+.BR listen (2)
+for more details.
+.TP
+.B \-o
+Leave IP options alone.
+If the client is sending packets along an IP source route,
+send packets back along the same route.
+.TP
+.B \-O
+(Default.)
+Kill IP options.
+A client can still use source routing to connect and to send data,
+but packets will be sent back along the default route.
+.TP
+.B \-d
+(Default.)
+Delay sending data for a fraction of a second whenever the
+remote host is responding slowly,
+to make better use of the network.
+.TP
+.B \-D
+Never delay sending data;
+enable TCP_NODELAY.
+This is appropriate for interactive connections.
+.TP
+.B \-q
+Quiet.
+Do not print any messages.
+.TP
+.B \-Q
+(Default.)
+Print error messages.
+.TP
+.B \-s
+Enable SSL/TLS mode. This modus needs a SSL enabled build and a certificat.
+.TP
+.B \-S
+(Default.)
+Don't enable SSL/TLS mode.
+.TP
+.B \-n\fIcertfile
+Instead of the default ./cert.pem certificate us the specified
+.IR certfile .
+.TP
+.B \-v
+Verbose.
+Print all available messages.
+.TP
+.B \-X
+With
+.BR -x\fIcdb ,
+allow connections even if
+.I cdb
+does not exist.
+Normally the connection gets dropped.
+.SH "DATA-GATHERING OPTIONS"
+.TP
+.B \-p
+Paranoid.
+After looking up the remote host name,
+look up the IP addresses for that name,
+and make sure one of them matches
+.BR TCPREMOTEIP .
+If none of them do,
+unset
+.BR TCPREMOTEHOST .
+.TP
+.B \-P
+(Default.)
+Not paranoid.
+.TP
+.B \-h
+(Default.)
+Look up the remote host name and set
+.BR TCPREMOTEHOST .
+.TP
+.B \-H
+Do not look up the remote host name.
+.TP
+.B \-l\fIlocalname
+Do not look up the local host name;
+use
+.I localname
+for
+.BR TCPLOCALHOST .
+.TP
+.B \-r
+(Default.)
+Attempt to obtain
+.B TCPREMOTEINFO
+from the remote host.
+.TP
+.B \-R
+Do not attempt to obtain
+.B TCPREMOTEINFO
+from the remote host.
+.TP
+.B \-t\fItimeout
+Give up on the
+.B TCPREMOTEINFO
+connection attempt
+after
+.I timeout
+seconds. Default: 26.
+.SH ENVIRONMENT
+.TP
+.B SSL_CIPHER
+Specifies the ciphers that should be used in SSL/TLS mode.
+See
+.I openssl(1)
+for more information.
+.SH "SEE ALSO"
+argv0(1),
+fixcr(1),
+recordio(1),
+tcpclient(1),
+tcprules(1),
+listen(2),
+tcp-environ(5),
+openssl(1)
diff -Nur ucspi-tcp-0.88.old/tcpserver.c ucspi-tcp-0.88.new/tcpserver.c
--- ucspi-tcp-0.88.old/tcpserver.c 2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88.new/tcpserver.c 2017-03-28 01:33:49.096053314 +0000
@@ -1,6 +1,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <netdb.h>
+#include <openssl/ssl.h>
#include "uint16.h"
#include "str.h"
#include "byte.h"
@@ -36,6 +37,13 @@
int flagremotehost = 1;
int flagparanoid = 0;
unsigned long timeout = 26;
+#ifdef WITH_SSL
+int flagssl = 0;
+struct stralloc certfile = {0};
+#define CERTFILE "./cert.pem"
+
+void translate(SSL*, int, int, unsigned int);
+#endif
static stralloc tcpremoteinfo;
@@ -127,6 +135,9 @@
env(data + 1,data + 1 + split + 1);
}
break;
+ case '-':
+ env(data + 1, (char *)0);
+ break;
}
++next0;
data += next0; datalen -= next0;
@@ -238,10 +249,28 @@
void usage(void)
{
+#ifndef WITH_SSL
strerr_warn1("\
tcpserver: usage: tcpserver \
[ -1UXpPhHrRoOdDqQv ] \
[ -c limit ] \
+[ -C [address[/len]:]limit ] \
+[ -e name=var ] \
+[ -x rules.cdb ] \
+[ -B banner ] \
+[ -g gid ] \
+[ -u uid ] \
+[ -b backlog ] \
+[ -l localname ] \
+[ -t timeout ] \
+host port program",0);
+#else
+ strerr_warn1("\
+tcpserver: usage: tcpserver \
+[ -1UXpPhHrRoOdDqQsSv ] \
+[ -c limit ] \
+[ -C [address[/len]:]limit ] \
+[ -e name=var ] \
[ -x rules.cdb ] \
[ -B banner ] \
[ -g gid ] \
@@ -249,7 +278,9 @@
[ -b backlog ] \
[ -l localname ] \
[ -t timeout ] \
+[ -n certfile ] \
host port program",0);
+#endif
_exit(100);
}
@@ -274,12 +305,106 @@
_exit(0);
}
+struct conn {
+ int pid;
+ char remoteip[4];
+} *conns;
+
+struct ip_limelt {
+ char ip[4];
+ char mask[4];
+ unsigned long limit;
+ unsigned long count;
+};
+
+#include "gen_alloc.h"
+#include "gen_allocdefs.h"
+GEN_ALLOC_typedef(ip_limit,struct ip_limelt,l,len,a)
+GEN_ALLOC_readyplus(ip_limit, struct ip_limelt,l,len,a,i,n,x,10,
+ ip_limit_rp)
+
+ip_limit ipl = {0};
+unsigned long limit_ip = 0;
+
+void
+ip_limit_add(char *str)
+{
+ unsigned int n, len;
+ unsigned long ul = 0;
+ struct ip_limelt lim;
+
+ byte_zero(&lim, sizeof(lim));
+ n = str_chr(str, ':');
+ if (str[n] == ':') {
+ str[n] = 0;
+ scan_ulong(str + n + 1, &ul);
+ lim.limit = ul;
+ /* parse ip */
+ ul = 32;
+ n = str_chr(str, '/');
+ if (str[n] == '/')
+ scan_ulong(str + n + 1, &ul);
+ if (ul > 32)
+ strerr_die2x(111,FATAL,"ip prefix len > 32");
+ if (ip4_scan(str, lim.ip) == 0)
+ strerr_die2x(111,FATAL,"bad ip address");
+ for (n = 0; n < 4; n++)
+ if (ul > 8) {
+ lim.mask[n] = 0xff;
+ ul -= 8;
+ } else {
+ lim.mask[n] = 0xff << (8 - ul);
+ ul = 0;
+ }
+ if (!ip_limit_rp(&ipl,1))
+ strerr_die2x(111,FATAL,"out of memory");
+ ipl.l[ipl.len++] = lim;
+ } else {
+ scan_ulong(str, &ul);
+ limit_ip = ul;
+ }
+}
+
+int
+ip_limit_check(char ip[4], int d)
+{
+ unsigned long c;
+ unsigned int l;
+ int i;
+
+ for (l = 0; l < ipl.len; l++)
+ if ((ip[0] & ipl.l[l].mask[0]) == (ipl.l[l].ip[0] & ipl.l[l].mask[0]) &&
+ (ip[1] & ipl.l[l].mask[1]) == (ipl.l[l].ip[1] & ipl.l[l].mask[1]) &&
+ (ip[2] & ipl.l[l].mask[2]) == (ipl.l[l].ip[2] & ipl.l[l].mask[2]) &&
+ (ip[3] & ipl.l[l].mask[3]) == (ipl.l[l].ip[3] & ipl.l[l].mask[3])) {
+ if (ipl.l[l].count + d > ipl.l[l].limit)
+ return 1;
+ ipl.l[l].count += d;
+ return 0;
+ }
+
+ /* global per ip limit */
+ for (l = 0, c= 0; l < limit; l++)
+ if (!byte_diff(conns[l].remoteip, sizeof(ip), ip))
+ c++;
+ if (limit_ip != 0 && c + d > limit_ip)
+ return 1;
+
+ return 0;
+}
+
void sigchld()
{
int wstat;
int pid;
-
+ unsigned int i;
+
while ((pid = wait_nohang(&wstat)) > 0) {
+ for (i = 0; i < limit; i++)
+ if (conns[i].pid == pid) {
+ ip_limit_check(conns[i].remoteip, -1);
+ byte_zero(&conns[i], sizeof(struct conn));
+ }
if (verbosity >= 2) {
strnum[fmt_ulong(strnum,pid)] = 0;
strnum2[fmt_ulong(strnum2,wstat)] = 0;
@@ -296,14 +421,31 @@
int opt;
struct servent *se;
char *x;
+ char *iplimenv;
+ int flagiplim;
unsigned long u;
int s;
int t;
-
- while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof)
+ unsigned int i;
+ int pid;
+#ifdef WITH_SSL
+ BIO *sbio;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ int pi2c[2], pi4c[2];
+
+ ctx = NULL;
+
+ if (!stralloc_copys(&certfile, CERTFILE) || !stralloc_0(&certfile) )
+ strerr_die2x(111,FATAL,"out of memory");
+ while ((opt = getopt(argc,argv,"dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:C:e:n:pPoO")) != opteof)
+#else
+ while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:C:e:pPoO")) != opteof)
+#endif
switch(opt) {
case 'b': scan_ulong(optarg,&backlog); break;
case 'c': scan_ulong(optarg,&limit); break;
+ case 'C': ip_limit_add(optarg); break;
case 'X': flagallownorules = 1; break;
case 'x': fnrules = optarg; break;
case 'B': banner = optarg; break;
@@ -327,6 +469,18 @@
case 'g': scan_ulong(optarg,&gid); break;
case '1': flag1 = 1; break;
case 'l': localhost = optarg; break;
+ case 'e': iplimenv = optarg;
+ if (iplimenv[str_chr(iplimenv, '=')] != '=')
+ strerr_die2x(100,FATAL, "no '=' in ip limit env-var");
+ break;
+#ifdef WITH_SSL
+ case 's': flagssl = 1; break;
+ case 'S': flagssl = 0; break;
+ case 'n': if (!stralloc_copys(&certfile, optarg) ||
+ !stralloc_0(&certfile) )
+ strerr_die2x(111,FATAL,"out of memory");
+ break;
+#endif
default: usage();
}
argc -= optind;
@@ -334,6 +488,15 @@
if (!verbosity)
buffer_2->fd = -1;
+
+ if (limit == 0)
+ strerr_die2x(100,FATAL,"limit may not be set to 0");
+ if (limit > 65000)
+ strerr_die2x(100,FATAL,"limit way to high");
+ conns = (struct conn *)alloc(limit * sizeof(struct conn));
+ if (!conns)
+ strerr_die2x(111,FATAL,"out of memory");
+ byte_zero(conns, limit * sizeof(struct conn));
hostname = *argv++;
if (!hostname) usage();
@@ -366,6 +529,27 @@
strerr_die3x(111,FATAL,"no IP address for ",hostname);
byte_copy(localip,4,addresses.s);
+#ifdef WITH_SSL
+ if (flagssl == 1) {
+ /* setup SSL context (load key and cert into ctx) */
+ SSL_library_init();
+ ctx=SSL_CTX_new(SSLv23_server_method());
+ if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context");
+
+ /* set prefered ciphers */
+ if (env_get("SSL_CIPHER"))
+ if (SSL_CTX_set_cipher_list(ctx, env_get("SSL_CIPHER")) == 0)
+ strerr_die2x(111,FATAL,"unable to set cipher list");
+
+ if(SSL_CTX_use_RSAPrivateKey_file(ctx, certfile.s, SSL_FILETYPE_PEM) != 1)
+ strerr_die2x(111,FATAL,"unable to load RSA private key");
+ if(SSL_CTX_use_certificate_chain_file(ctx, certfile.s) != 1)
+ strerr_die2x(111,FATAL,"unable to load certificate");
+
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); /* add k.ohga */
+ }
+#endif
+
s = socket_tcp();
if (s == -1)
strerr_die2sys(111,FATAL,"unable to create socket: ");
@@ -404,9 +588,31 @@
if (t == -1) continue;
++numchildren; printstatus();
+
+ /* per ip handling */
+ flagiplim = 0;
+ if (ip_limit_check(remoteip, 1)) {
+ remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
+ if (iplimenv) {
+ strerr_warn4(DROP,"too many conections from ",remoteipstr,
+ " only flagged",0);
+ flagiplim = 1;
+ } else {
+ strerr_warn3(DROP,"too many conections from ",remoteipstr,0);
+ --numchildren; printstatus();
+ close(t);
+ continue;
+ }
+ }
- switch(fork()) {
+ switch(pid = fork()) {
case 0:
+ if (flagiplim) {
+ int split;
+ split = str_chr(iplimenv,'=');
+ iplimenv[split] = 0;
+ env(iplimenv,iplimenv + split + 1);
+ }
close(s);
doit(t);
if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1))
@@ -415,12 +621,162 @@
sig_unblock(sig_child);
sig_uncatch(sig_term);
sig_uncatch(sig_pipe);
+#ifdef WITH_SSL
+ if (flagssl == 1) {
+ if (pipe(pi2c) != 0)
+ strerr_die2sys(111,DROP,"unable to create pipe: ");
+ if (pipe(pi4c) != 0)
+ strerr_die2sys(111,DROP,"unable to create pipe: ");
+ switch(fork()) {
+ case 0:
+ close(0); close(1);
+ close(pi2c[1]);
+ close(pi4c[0]);
+ if ((fd_move(0,pi2c[0]) == -1) || (fd_move(1,pi4c[1]) == -1))
+ strerr_die2sys(111,DROP,"unable to set up descriptors: ");
+ /* signals are allready set in the parent */
+ pathexec(argv);
+ strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
+ case -1:
+ strerr_die2sys(111,DROP,"unable to fork: ");
+ default:
+ ssl = SSL_new(ctx);
+ if (!ssl)
+ strerr_die2x(111,DROP,"unable to set up SSL session");
+ sbio = BIO_new_socket(0,BIO_NOCLOSE);
+ if (!sbio)
+ strerr_die2x(111,DROP,"unable to set up BIO socket");
+
+ SSL_set_mode(ssl, SSL_MODE_SEND_FALLBACK_SCSV); /* add k.ohga */
+
+ SSL_set_bio(ssl,sbio,sbio);
+ close(pi2c[0]);
+ close(pi4c[1]);
+ translate(ssl, pi2c[1], pi4c[0], 3600);
+ _exit(0);
+ }
+ }
+#endif
pathexec(argv);
strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
case -1:
strerr_warn2(DROP,"unable to fork: ",&strerr_sys);
--numchildren; printstatus();
+ break;
+ default:
+ for (i = 0; i < limit; i++)
+ if (conns[i].pid == 0) {
+ conns[i].pid = pid;
+ byte_copy(conns[i].remoteip, sizeof(remoteip), remoteip);
+ break;
+ }
}
close(t);
}
}
+
+#ifdef WITH_SSL
+static int allwrite(int fd, char *buf, int len)
+{
+ int w;
+
+ while (len) {
+ w = write(fd,buf,len);
+ if (w == -1) {
+ if (errno == error_intr) continue;
+ return -1; /* note that some data may have been written */
+ }
+ if (w == 0) ; /* luser's fault */
+ buf += w;
+ len -= w;
+ }
+ return 0;
+}
+
+static int allwritessl(SSL* ssl, char *buf, int len)
+{
+ int w;
+
+ while (len) {
+ w = SSL_write(ssl,buf,len);
+ if (w == -1) {
+ if (errno == error_intr) continue;
+ return -1; /* note that some data may have been written */
+ }
+ if (w == 0) ; /* luser's fault */
+ buf += w;
+ len -= w;
+ }
+ return 0;
+}
+
+char tbuf[2048];
+
+void translate(SSL* ssl, int clearout, int clearin, unsigned int iotimeout)
+{
+ struct taia now;
+ struct taia deadline;
+ iopause_fd iop[2];
+ int flagexitasap;
+ int iopl;
+ int sslout, sslin;
+ int n, r;
+
+ sslin = SSL_get_fd(ssl);
+ sslout = SSL_get_fd(ssl);
+ if (sslin == -1 || sslout == -1)
+ strerr_die2x(111,DROP,"unable to set up SSL connection");
+
+ flagexitasap = 0;
+
+ if (SSL_accept(ssl)<=0)
+ strerr_die2x(111,DROP,"unable to accept SSL connection");
+
+ while (!flagexitasap) {
+ taia_now(&now);
+ taia_uint(&deadline,iotimeout);
+ taia_add(&deadline,&now,&deadline);
+
+ /* fill iopause struct */
+ iopl = 2;
+ iop[0].fd = sslin;
+ iop[0].events = IOPAUSE_READ;
+ iop[1].fd = clearin;
+ iop[1].events = IOPAUSE_READ;
+
+ /* do iopause read */
+ iopause(iop,iopl,&deadline,&now);
+ if (iop[0].revents) {
+ do {
+ /* data on sslin */
+ n = SSL_read(ssl, tbuf, sizeof(tbuf));
+ if ( n < 0 )
+ strerr_die2sys(111,DROP,"unable to read form network: ");
+ if ( n == 0 )
+ flagexitasap = 1;
+ r = allwrite(clearout, tbuf, n);
+ if ( r < 0 )
+ strerr_die2sys(111,DROP,"unable to write to client: ");
+ /*
+ * if the data payload was longer than sizeof(tbuf) then SSL will have
+ * bytes processed and pending. We need to pick them up and write them
+ * to clearout.
+ */
+ } while (SSL_pending(ssl));
+ }
+ if (iop[1].revents) {
+ /* data on clearin */
+ n = read(clearin, tbuf, sizeof(tbuf));
+ if ( n < 0 )
+ strerr_die2sys(111,DROP,"unable to read form client: ");
+ if ( n == 0 )
+ flagexitasap = 1;
+ r = allwritessl(ssl, tbuf, n);
+ if ( r < 0 )
+ strerr_die2sys(111,DROP,"unable to write to network: ");
+ }
+ if (!iop[0].revents && !iop[1].revents)
+ strerr_die2x(0, DROP,"timeout reached without input");
+ }
+}
+#endif
diff -Nur ucspi-tcp-0.88.old/who@.1 ucspi-tcp-0.88.new/who@.1
--- ucspi-tcp-0.88.old/who@.1 1970-01-01 00:00:00.000000000 +0000
+++ ucspi-tcp-0.88.new/who@.1 2017-03-28 00:07:10.702623179 +0000
@@ -0,0 +1,32 @@
+.TH who@ 1
+.SH NAME
+who@ \- print list of active users on a host
+.SH SYNTAX
+.B who@
+[
+.I host
+]
+.SH DESCRIPTION
+.B who@
+connects to TCP port 11 (Systat) on
+.I host
+and prints any data it receives.
+It removes CR and converts unprintable characters to a visible format.
+
+If
+.I host
+is not supplied,
+.B who@
+connects to the local host.
+
+Some computers respond to port 11 with a list of active users.
+For example, they may be running
+
+.EX
+ tcpserver 0 11 who &
+.EE
+.SH "SEE ALSO"
+cat(1),
+delcr(1),
+tcpclient(1),
+tcpserver(1)
@ohga
Copy link
Author

ohga commented Dec 6, 2017

tcpserver -s -n ./dr.pem -vRH -u 500 -c 12000 0 11935 nc -4 -n 127.0.0.1 1935 とかして使う。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment