Search
j0ke.net Open Build Service
>
Projects
>
server:mail
>
ucspi-tcp
> ucspi-tcp-0.88-ssl.diff
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File ucspi-tcp-0.88-ssl.diff of Package ucspi-tcp (Revision 3)
Currently displaying revision
3
,
show latest
diff -ruN ucspi-tcp-0.88-orig/addcr.1 ucspi-tcp-0.88/addcr.1 --- ucspi-tcp-0.88-orig/addcr.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/addcr.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/argv0.1 ucspi-tcp-0.88/argv0.1 --- ucspi-tcp-0.88-orig/argv0.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/argv0.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/date@.1 ucspi-tcp-0.88/date@.1 --- ucspi-tcp-0.88-orig/date@.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/date@.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/delcr.1 ucspi-tcp-0.88/delcr.1 --- ucspi-tcp-0.88-orig/delcr.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/delcr.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/error.h ucspi-tcp-0.88/error.h --- ucspi-tcp-0.88-orig/error.h 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/error.h 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/FILES ucspi-tcp-0.88/FILES --- ucspi-tcp-0.88-orig/FILES 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/FILES 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/finger@.1 ucspi-tcp-0.88/finger@.1 --- ucspi-tcp-0.88-orig/finger@.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/finger@.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/fixcrio.1 ucspi-tcp-0.88/fixcrio.1 --- ucspi-tcp-0.88-orig/fixcrio.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/fixcrio.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/hier.c ucspi-tcp-0.88/hier.c --- ucspi-tcp-0.88-orig/hier.c 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/hier.c 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/http@.1 ucspi-tcp-0.88/http@.1 --- ucspi-tcp-0.88-orig/http@.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/http@.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/Makefile ucspi-tcp-0.88/Makefile --- ucspi-tcp-0.88-orig/Makefile 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/Makefile 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/mconnect.1 ucspi-tcp-0.88/mconnect.1 --- ucspi-tcp-0.88-orig/mconnect.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/mconnect.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/recordio.1 ucspi-tcp-0.88/recordio.1 --- ucspi-tcp-0.88-orig/recordio.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/recordio.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/TARGETS ucspi-tcp-0.88/TARGETS --- ucspi-tcp-0.88-orig/TARGETS 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/TARGETS 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcpcat.1 ucspi-tcp-0.88/tcpcat.1 --- ucspi-tcp-0.88-orig/tcpcat.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcpcat.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcpclient.1 ucspi-tcp-0.88/tcpclient.1 --- ucspi-tcp-0.88-orig/tcpclient.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcpclient.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcp-environ.5 ucspi-tcp-0.88/tcp-environ.5 --- ucspi-tcp-0.88-orig/tcp-environ.5 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcp-environ.5 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcprules.1 ucspi-tcp-0.88/tcprules.1 --- ucspi-tcp-0.88-orig/tcprules.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcprules.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcprules.c ucspi-tcp-0.88/tcprules.c --- ucspi-tcp-0.88-orig/tcprules.c 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/tcprules.c 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcprulescheck.1 ucspi-tcp-0.88/tcprulescheck.1 --- ucspi-tcp-0.88-orig/tcprulescheck.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcprulescheck.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcprulescheck.c ucspi-tcp-0.88/tcprulescheck.c --- ucspi-tcp-0.88-orig/tcprulescheck.c 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/tcprulescheck.c 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcpserver.1 ucspi-tcp-0.88/tcpserver.1 --- ucspi-tcp-0.88-orig/tcpserver.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/tcpserver.1 2005-12-05 12:24:50.000000000 +0100 @@ -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 -ruN ucspi-tcp-0.88-orig/tcpserver.c ucspi-tcp-0.88/tcpserver.c --- ucspi-tcp-0.88-orig/tcpserver.c 2000-03-18 16:18:42.000000000 +0100 +++ ucspi-tcp-0.88/tcpserver.c 2005-12-05 12:24:50.000000000 +0100 @@ -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,25 @@ 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"); + } +#endif + s = socket_tcp(); if (s == -1) strerr_die2sys(111,FATAL,"unable to create socket: "); @@ -404,9 +586,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 +619,159 @@ 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_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 -ruN ucspi-tcp-0.88-orig/who@.1 ucspi-tcp-0.88/who@.1 --- ucspi-tcp-0.88-orig/who@.1 1970-01-01 01:00:00.000000000 +0100 +++ ucspi-tcp-0.88/who@.1 2005-12-05 12:24:50.000000000 +0100 @@ -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)