Download | Plain Text | No Line Numbers
- --- FILES 14 Jun 2002 08:47:30 -0000 1.1.1.1
- +++ FILES 5 Apr 2004 15:34:57 -0000 1.2
- @@ -216,6 +216,7 @@
- warn-auto.sh
- warn-shsgr
- x86cpuid.c
- +fixcrio.1
- dns_ip6.c
- dns_ipq6.c
- dns_nd6.c
- --- Makefile 14 Jun 2002 08:47:30 -0000 1.1.1.1
- +++ Makefile 5 Apr 2004 15:34:57 -0000 1.3
- @@ -1,5 +1,13 @@
- # 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
- @@ -755,7 +763,7 @@
- load tcpserver.o rules.o remoteinfo6.o timeoutconn6.o cdb.a dns.a \
- time.a unix.a byte.a socket.lib
- ./load tcpserver rules.o remoteinfo6.o timeoutconn6.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.o: \
- compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
- @@ -764,7 +772,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 uint32.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 \
- @@ -967,3 +975,18 @@
-
- clean:
- rm -f `cat TARGETS`
- +
- +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"
- +
- +
- --- /dev/null 1 Jan 1970 00:00:00 -0000
- +++ fixcrio.1 5 Apr 2004 15:34:57 -0000 1.1
- @@ -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)
- --- hier.c 14 Jun 2002 08:47:32 -0000 1.1.1.1
- +++ hier.c 5 Apr 2004 15:34:57 -0000 1.2
- @@ -26,6 +26,7 @@
- c(auto_home,"bin","fixcrio",-1,-1,0755);
- c(auto_home,"bin","rblsmtpd",-1,-1,0755);
-
- + c(auto_home,"man/man1","fixcrio.1",-1,-1,0644);
- c(auto_home,"man/man1","tcpclient.1",-1,-1,0644);
- c(auto_home,"man/man1","tcpserver.1",-1,-1,0644);
- c(auto_home,"man/man1","tcprules.1",-1,-1,0644);
- }
- --- tcprules.c 14 Jun 2002 08:47:30 -0000 1.1.1.1
- +++ tcprules.c 16 Mar 2004 15:12:26 -0000 1.2
- @@ -94,6 +94,7 @@
- int len;
- int fd;
- int i;
- + int e;
- char ch;
-
- fn = argv[1];
- @@ -154,8 +155,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;
- --- tcprulescheck.c 14 Jun 2002 08:47:30 -0000 1.1.1.1
- +++ tcprulescheck.c 16 Mar 2004 15:12:27 -0000 1.2
- @@ -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;
- --- tcpserver.1.orig 1 Jan 1970 00:00:00 -0000
- +++ tcpserver.1 6 Apr 2004 11:49:45 -0000 1.2
- @@ -4,7 +4,7 @@
- .SH SYNOPSIS
- .B tcpserver
- [
- -.B \-146jpPhHrRoOdDqQv
- +.B \-146UXpPhHrRoOdDqQsSv
- ]
- [
- .B \-c\fIlimit
- @@ -31,6 +31,9 @@
- .B \-t\fItimeout
- ]
- [
- +.B \-n\fIcertfile
- +]
- +[
- .B \-I\fIinterface
- ]
- .I host
- @@ -204,11 +207,31 @@
- (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.
- .SH "DATA-GATHERING OPTIONS"
- .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,
- @@ -256,6 +279,13 @@
- 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),
- @@ -264,3 +294,4 @@
- tcprules(1),
- listen(2),
- tcp-environ(5)
- +openssl(1)
- --- tcpserver.c 14 Jun 2002 08:47:30 -0000 1.1.1.1
- +++ tcpserver.c 1 Apr 2005 15:13:15 -0000 1.8
- @@ -1,6 +1,8 @@
- #include <sys/types.h>
- #include <sys/param.h>
- #include <netdb.h>
- +#include <openssl/ssl.h>
- +#include <fcntl.h>
- #include "uint16.h"
- #include "str.h"
- #include "byte.h"
- @@ -39,6 +40,13 @@
- int flagparanoid = 0;
- unsigned long timeout = 26;
- uint32 netif = 0;
- +#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;
-
- @@ -130,6 +138,9 @@
- env(data + 1,data + 1 + split + 1);
- }
- break;
- + case '-':
- + env(data + 1, (char *)0);
- + break;
- }
- ++next0;
- data += next0; datalen -= next0;
- @@ -271,6 +282,7 @@
-
- void usage(void)
- {
- +#ifndef WITH_SSL
- strerr_warn1("\
- tcpserver: usage: tcpserver \
- [ -461UXpPhHrRoOdDqQv ] \
- @@ -282,8 +294,23 @@
- [ -b backlog ] \
- [ -l localname ] \
- [ -t timeout ] \
- +host port program",0);
- +#else
- + strerr_warn1("\
- +tcpserver: usage: tcpserver \
- +[ -461UXpPhHrRoOdDqQsSv ] \
- +[ -c limit ] \
- +[ -x rules.cdb ] \
- +[ -B banner ] \
- +[ -g gid ] \
- +[ -u uid ] \
- +[ -b backlog ] \
- +[ -l localname ] \
- +[ -t timeout ] \
- +[ -n certfile ] \
- [ -I interface ] \
- host port program",0);
- +#endif
- _exit(100);
- }
-
- @@ -334,7 +361,20 @@
- int s;
- int t;
-
- +#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,"46dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:n:I:pPoO")) != opteof)
- +#else
- while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:pPoO")) != opteof)
- +#endif
- switch(opt) {
- case 'b': scan_ulong(optarg,&backlog); break;
- case 'c': scan_ulong(optarg,&limit); break;
- @@ -364,6 +404,14 @@
- case '4': noipv6 = 1; break;
- case '6': forcev6 = 1; break;
- case 'l': localhost = optarg; 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;
- @@ -371,6 +419,11 @@
-
- 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");
-
- hostname = *argv++;
- if (!hostname) usage();
- @@ -412,6 +465,25 @@
- noipv6=1;
- }
-
- +#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_tcp6();
- if (s == -1)
- strerr_die2sys(111,FATAL,"unable to create socket: ");
- @@ -461,6 +533,39 @@
- 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:
- @@ -470,3 +575,186 @@
- close(t);
- }
- }
- +
- +#ifdef WITH_SSL
- +int ssl_timeoutio(int (*func)(), long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
- +{
- + int n;
- + const long end = t + time(NULL);
- +
- + do {
- + fd_set fds;
- + struct timeval tv;
- +
- + const int r = buf ? func(ssl, buf, len) : func(ssl);
- + if (r > 0)
- + return r;
- +
- + t = end - time(NULL);
- + if (t < 0)
- + break;
- + tv.tv_sec = t;
- + tv.tv_usec = 0;
- +
- + FD_ZERO(&fds);
- + switch (SSL_get_error(ssl, r))
- + {
- + default:
- + return r; /* some other error */
- + case SSL_ERROR_WANT_READ:
- + FD_SET(rfd, &fds);
- + n = select(rfd + 1, &fds, NULL, NULL, &tv);
- + break;
- + case SSL_ERROR_WANT_WRITE:
- + FD_SET(wfd, &fds);
- + n = select(wfd + 1, NULL, &fds, NULL, &tv);
- + break;
- + }
- +
- + /* n is the number of descriptors that changed status */
- + }
- + while (n > 0);
- +
- + if (n != -1) errno = error_timeout;
- + return -1;
- +}
- +
- +int ssl_timeoutaccept(long t, int rfd, int wfd, SSL *ssl)
- +{
- + int r;
- +
- + /* if connection is established, keep NDELAY */
- + if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1)
- + return -1;
- + r = ssl_timeoutio(SSL_accept, t, rfd, wfd, ssl, NULL, 0);
- +
- + if (r <= 0) {
- + ndelay_off(rfd);
- + ndelay_off(wfd);
- + }
- + else
- + SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
- +
- + return r;
- +}
- +
- +int ssl_timeoutread(long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
- +{
- + if (!buf)
- + return 0;
- + if (SSL_pending(ssl))
- + return SSL_read(ssl, buf, len);
- + return ssl_timeoutio(SSL_read, t, rfd, wfd, ssl, buf, len);
- +}
- +
- +int ssl_timeoutwrite(long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
- +{
- + if (!buf)
- + return 0;
- + return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len);
- +}
- +
- +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(long t, int rfd, int wfd, SSL* ssl, char *buf, int len)
- +{
- + int w;
- +
- + while (len) {
- + w = ssl_timeoutwrite(t, rfd, wfd, 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_timeoutaccept(timeout, sslin, sslout, 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_timeoutread(iotimeout, sslin, sslout, 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(iotimeout, sslin, sslout, 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
-