*** inn-2000-03-09_03-01-orig/INSTALL Thu Mar 9 20:00:05 2000 --- inn-2000-03-09_03-01/INSTALL Fri Mar 10 22:04:10 2000 *************** *** 241,246 **** --- 241,252 ---- through a network connection and don't need a local setgid inews to post. Installing inews setgid was the default prior to INN 2.3. + --with-ssl=PATH + Enables support for SSL, allowing you to get SSL or TLS encrypted + NNRP between your server and newsreaders. Sets the path of the + installed directory of OpenSSL. You must make a certificate and + private key. + For the most common installation, a standalone news server, a suggested set of options is: *************** *** 269,274 **** --- 275,287 ---- needed to raise resource limits and allow innd to bind to port 119. This will install INN under the install directory (/usr/local/news, unless you specified something else to the configure script.) + + If you use SSL support for nnrp, you must make a certificate and private + key once. Type: + + make cert + + You will need to run this command as root. You are now ready for the really fun part: configuring your copy of INN! *** inn-2000-03-09_03-01-orig/Makefile Thu Mar 9 20:00:06 2000 --- inn-2000-03-09_03-01/Makefile Fri Mar 10 21:42:57 2000 *************** *** 84,89 **** --- 84,96 ---- cd $$D && $(MAKE) install || exit 1 ; cd .. ; \ done + ## for starttls + cert: + $(SSLBIN)/openssl req -new -x509 -nodes \ + -out $(PATHLIB)/cert.pem -days 366 \ + -keyout $(PATHLIB)/cert.pem + chown news:news $(PATHLIB)/cert.pem + chmod 640 $(PATHLIB)/cert.pem ## Cleanup targets. clean deletes all compilation results but leaves the ## configure results. distclean or clobber removes everything not part of *** inn-2000-03-09_03-01-orig/Makefile.global.in Thu Mar 9 20:00:06 2000 --- inn-2000-03-09_03-01/Makefile.global.in Fri Mar 10 21:42:57 2000 *************** *** 84,89 **** --- 84,93 ---- PYTHONLIB = @PYTHON_LIB@ PYTHONINC = @PYTHON_INC@ + SSLLIB = @SSL_LIB@ + SSLINC = @SSL_INC@ + SSLBIN = @SSL_BIN@ + ## Missing functions. If non-empty, configure detected that your system ## was missing some standard functions, and INN will be providing its own ## replacements using the source and object files listed below. In some *** inn-2000-03-09_03-01-orig/configure.in Thu Mar 9 20:00:09 2000 --- inn-2000-03-09_03-01/configure.in Fri Mar 10 21:42:57 2000 *************** *** 590,595 **** --- 590,632 ---- AC_CHECK_FUNCS(ftello fseeko) fi + dnl + dnl Test for OpenSSL + dnl + AC_ARG_WITH(openssl, + [ --with-openssl=PATH use OpenSSL from PATH], + OPENSSL_DIR=$with_openssl) + case "$OPENSSL_DIR" in + no) OPENSSL_DIR="no";; + ""|yes) + for dir in ${prefix} /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do + if test -f "$dir/include/openssl/ssl.h"; then + OPENSSL_DIR="$dir" + break + fi + if test -f "$dir/include/ssl.h"; then + OPENSSL_DIR="$dir" + break + fi + done + ;; + esac + AC_MSG_CHECKING(for openssl) + AC_MSG_RESULT($OPENSSL_DIR) + if test "$OPENSSL_DIR" != "no"; then + SSL_INC="-I${OPENSSL_DIR}/include" + SSL_LIB="-L${OPENSSL_DIR}/lib -lssl -lcrypto" + SSL_BIN="${OPENSSL_DIR}/bin" + AC_DEFINE(HAVE_SSL) + else + SSL_LIB="" + SSL_INC="" + SSL_BIN="" + fi + AC_SUBST(SSL_LIB) + AC_SUBST(SSL_INC) + AC_SUBST(SSL_BIN) + dnl Special checks for header files. dnl Start by checking for standard C headers. AC_HEADER_STDC will set *************** *** 1229,1234 **** --- 1266,1272 ---- samples/nnrpd_auth.pl samples/nnrpd_auth.py samples/startup.tcl + samples/sasl.conf scripts/inncheck scripts/innreport scripts/innshellvars *** inn-2000-03-09_03-01-orig/include/config.h.in Thu Mar 9 20:00:40 2000 --- inn-2000-03-09_03-01/include/config.h.in Fri Mar 10 21:42:57 2000 *************** *** 210,215 **** --- 210,218 ---- /* Define to compile in TCL filter support. */ #undef DO_TCL + /* Define if nnrpd uses STARTTLS. */ + #undef HAVE_SSL + /* Mode that directories are created with. */ #undef GROUPDIR_MODE *** inn-2000-03-09_03-01-orig/include/nntp.h Tue Sep 23 02:54:44 1997 --- inn-2000-03-09_03-01/include/nntp.h Fri Mar 10 21:42:57 2000 *************** *** 124,129 **** --- 124,139 ---- #define NNTP_AUTH_REJECT_VAL 482 /* + ** Starttls commands (not official). + */ + #define NNTP_STARTTLS_NEXT "382" + #define NNTP_STARTTLS_NEXT_VAL 382 + #define NNTP_STARTTLS_DONE "483" + #define NNTP_STARTTLS_DONE_VAL 483 + #define NNTP_STARTTLS_BAD "580" + #define NNTP_STARTTLS_BAD_VAL 580 + + /* ** XGTITLE, from ANU news. */ #define NNTP_XGTITLE_BAD 481 /* Yes, 481. */ *** inn-2000-03-09_03-01-orig/include/paths.h.in Sat Dec 18 02:00:53 1999 --- inn-2000-03-09_03-01/include/paths.h.in Fri Mar 10 21:42:57 2000 *************** *** 65,70 **** --- 65,71 ---- #define _PATH_STORAGECTL "storage.conf" #define _PATH_OVERVIEWCTL "overview.ctl" #define _PATH_RADIUS_CONFIG "@ETCDIR@/radius.conf" + #define _PATH_SASL_CONFIG "@ETCDIR@/sasl.conf" /* Default prefix path is pathspool. */ #define _PATH_SPOOL "articles" *** inn-2000-03-09_03-01-orig/nnrpd/Makefile Thu Mar 9 20:00:58 2000 --- inn-2000-03-09_03-01/nnrpd/Makefile Fri Mar 10 21:42:57 2000 *************** *** 1,17 **** ## $Revision: 1.30 $ include ../Makefile.global ! CFLAGS = $(GCFLAGS) NNRPD = ${PATHBIN}/nnrpd SOURCES = \ article.c group.c commands.c misc.c newnews.c nnrpd.c \ ! perl.c perm.c post.c loadave.c track.c python.c OBJECTS = \ article.o group.o commands.o misc.o newnews.o \ ! perl.o perm.o post.o loadave.o track.o python.o ALL = nnrpd --- 1,19 ---- ## $Revision: 1.30 $ include ../Makefile.global ! CFLAGS = $(GCFLAGS) $(SSLINC) NNRPD = ${PATHBIN}/nnrpd SOURCES = \ article.c group.c commands.c misc.c newnews.c nnrpd.c \ ! perl.c perm.c post.c loadave.c track.c python.c tls.c \ ! sasl_config.c OBJECTS = \ article.o group.o commands.o misc.o newnews.o \ ! perl.o perm.o post.o loadave.o track.o python.o tls.o \ ! sasl_config.o ALL = nnrpd *************** *** 38,44 **** tags ctags: $(SOURCES) $(CTAGS) $(SOURCES) ../lib/*.c nnrpd.h ../include/*.h ! BIGLIST = $(OBJECTS) $(LIBSTORAGE) $(LIBINN) $(EXTSTORAGELIBS) $(PERLLIB) $(PYTHONLIB) $(LIBS) nnrpd: $(P) nnrpd.o $(OBJECTS) $(LIBSTORAGE) $(LIBINN) @rm -f $@ --- 40,46 ---- tags ctags: $(SOURCES) $(CTAGS) $(SOURCES) ../lib/*.c nnrpd.h ../include/*.h ! BIGLIST = $(OBJECTS) $(LIBSTORAGE) $(LIBINN) $(EXTSTORAGELIBS) $(PERLLIB) $(PYTHONLIB) $(SSLLIB) $(LIBS) nnrpd: $(P) nnrpd.o $(OBJECTS) $(LIBSTORAGE) $(LIBINN) @rm -f $@ *** inn-2000-03-09_03-01-orig/nnrpd/article.c Thu Mar 9 20:00:58 2000 --- inn-2000-03-09_03-01/nnrpd/article.c Fri Mar 10 21:42:57 2000 *************** *** 15,20 **** --- 15,28 ---- #include "nnrpd.h" #include "ov.h" + #ifdef HAVE_SSL + #include + #include + #include + #include + #include "tls.h" + extern SSL *tls_conn; + #endif /* ** Data structures for use in ARTICLE/HEAD/BODY/STAT common code. *************** *** 112,122 **** fflush(stdout); if (MaxBytesPerSecond != 0) return PushIOvRateLimited(); ! ! if (writev(STDOUT_FILENO, iov, queued_iov) <= 0) { queued_iov = 0; return FALSE; } queued_iov = 0; return TRUE; } --- 120,143 ---- fflush(stdout); if (MaxBytesPerSecond != 0) return PushIOvRateLimited(); ! #ifdef HAVE_SSL ! if (tls_conn) { ! if (SSL_writev(tls_conn, iov, queued_iov) <= 0) { ! queued_iov = 0; ! return FALSE; ! } ! } else { ! if (writev(STDOUT_FILENO, iov, queued_iov) <= 0) { queued_iov = 0; return FALSE; + } + } + #else + if (writev(STDOUT_FILENO, iov, queued_iov) <= 0) { + queued_iov = 0; + return FALSE; } + #endif queued_iov = 0; return TRUE; } *************** *** 143,152 **** --- 164,187 ---- BOOL PushIOb(void) { fflush(stdout); + #ifdef HAVE_SSL + if (tls_conn) { + if (SSL_write(tls_conn, _IO_buffer_, highwater) != highwater) { + highwater = 0; + return FALSE; + } + } else { + if (write(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) { + highwater = 0; + return FALSE; + } + } + #else if (write(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) { highwater = 0; return FALSE; } + #endif highwater = 0; return TRUE; } *************** *** 906,911 **** --- 941,947 ---- Reply("%d %s fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, av[1]); else Reply("%d %d fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, ARTnumber); + (void)fflush(stdout); if (PERMaccessconf->nnrpdoverstats) gettimeofday(&stv, NULL); while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) { *** inn-2000-03-09_03-01-orig/nnrpd/commands.c Thu Mar 9 20:00:58 2000 --- inn-2000-03-09_03-01/nnrpd/commands.c Fri Mar 10 21:42:57 2000 *************** *** 421,427 **** wildarg = av[2]; if (OVgroupstats(wildarg, &lo, &hi, NULL, &flag)) { Reply("%d %s.\r\n", NNTP_LIST_FOLLOWS_VAL, lp->Format); ! printf("%s %010d %010d %c\r\n.\r\n", wildarg, hi, lo, flag); return; } } --- 421,427 ---- wildarg = av[2]; if (OVgroupstats(wildarg, &lo, &hi, NULL, &flag)) { Reply("%d %s.\r\n", NNTP_LIST_FOLLOWS_VAL, lp->Format); ! Printf("%s %010d %010d %c\r\n.\r\n", wildarg, hi, lo, flag); return; } } *************** *** 867,873 **** POSTrejected++; } } - /* ** The "xpath" command. An uncommon extension. --- 867,872 ---- *** inn-2000-03-09_03-01-orig/nnrpd/misc.c Thu Mar 9 20:00:59 2000 --- inn-2000-03-09_03-01/nnrpd/misc.c Fri Mar 10 22:17:46 2000 *************** *** 14,19 **** --- 14,28 ---- #include "nnrpd.h" #include "dbz.h" + #ifdef HAVE_SSL + #include + #include + #include + #include + #include "tls.h" + #include "sasl_config.h" + #endif + STATIC BOOL setup = FALSE; STATIC FILE *hfp = NULL; STATIC ino_t ino = 0; *************** *** 22,27 **** --- 31,41 ---- #define CHARStoINT(c1, c2) (ASCtoNUM((c1)) * 10 + ASCtoNUM((c2))) #define DaysInYear(y) ((y) % 4 ? 365 : (y) % 100 ? 366 : (y) % 400 ? 365 : 366) + #ifdef HAVE_SSL + extern SSL *tls_conn; + extern int nnrpd_starttls_done; + #endif + /* ** Parse a string into a NULL-terminated array of words; return number *************** *** 545,551 **** --- 559,572 ---- } if (i == 0 || !FD_ISSET(STDIN, &rmask)) return RTtimeout; + #ifdef HAVE_SSL + if (tls_conn) + count = SSL_read(tls_conn, buffer, sizeof buffer); + else + count = read(STDIN, buffer, sizeof buffer); + #else count = read(STDIN, buffer, sizeof buffer); + #endif if (count < 0) { syslog(L_TRACE, "%s cant read %m", ClientHost); return RTtimeout; *************** *** 872,875 **** --- 893,951 ---- return 1; } + #ifdef HAVE_SSL + /* + ** The "STARTTLS" command. RFC2595. + */ + /* ARGSUSED0 */ + FUNCTYPE + CMDstarttls(ac, av) + int ac; + char *av[]; + { + SSL_CTX *ctx; + int result; + + openlog("starttls", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG); + sasl_config_read(); + + if (nnrpd_starttls_done == 1) + { + Reply("%d Already successfully executed STARTTLS\r\n", NNTP_STARTTLS_DONE_VAL); + return; + } + + result=tls_init_serverengine(5, /* depth to verify */ + 1, /* can client auth? */ + 0, /* required client to auth? */ + (char *)sasl_config_getstring("tls_ca_file", ""), + (char *)sasl_config_getstring("tls_ca_path", ""), + (char *)sasl_config_getstring("tls_cert_file", ""), + (char *)sasl_config_getstring("tls_key_file", "")); + + if (result == -1) { + Reply("%d Error initializing TLS\r\n", NNTP_STARTTLS_BAD_VAL); + + syslog(L_ERROR, "error initializing TLS: " + "[CA_file: %s] [CA_path: %s] [cert_file: %s] [key_file: %s]", + (char *) sasl_config_getstring("tls_ca_file", ""), + (char *) sasl_config_getstring("tls_ca_path", ""), + (char *) sasl_config_getstring("tls_cert_file", ""), + (char *) sasl_config_getstring("tls_key_file", "")); + return; + } + Reply("%d Begin TLS negotiation now\r\n", NNTP_STARTTLS_NEXT_VAL); + (void)fflush(stdout); + + /* must flush our buffers before starting tls */ + + result=tls_start_servertls(0, /* read */ + 1); /* write */ + if (result==-1) { + Reply("%d Starttls failed\r\n", NNTP_STARTTLS_BAD_VAL); + return; + } + nnrpd_starttls_done = 1; + } + #endif /* HAVE_SSL */ *** inn-2000-03-09_03-01-orig/nnrpd/nnrpd.c Thu Mar 9 20:00:59 2000 --- inn-2000-03-09_03-01/nnrpd/nnrpd.c Fri Mar 10 21:42:57 2000 *************** *** 24,29 **** --- 24,39 ---- # include #endif /* HAVE_GETSPNAM */ + #ifdef HAVE_SSL + #include + #include + #include + #include + #include "tls.h" + extern SSL *tls_conn; + int nnrpd_starttls_done = 0; + #endif + /* ** Here is some defensive code to protect the news server from hosts, ** mostly PC's, that sometimes make a connection and then never give *************** *** 91,96 **** --- 101,109 ---- extern FUNCTYPE CMDxpat(); extern FUNCTYPE CMDxpath(); extern FUNCTYPE CMD_unimp(); + #ifdef HAVE_SSL + extern FUNCTYPE CMDstarttls(); + #endif int LLOGenable; extern int TrackClient(); *************** *** 100,105 **** --- 113,122 ---- STATIC CMDENT CMDtable[] = { { "authinfo", CMDauthinfo, FALSE, 3, CMDany, "user Name|pass Password|generic " }, + #ifdef HAVE_SSL + { "starttls", CMDstarttls, FALSE, 1, 1, + NULL }, + #endif { "article", CMDfetch, TRUE, 1, 2, CMDfetchhelp }, { "body", CMDfetch, TRUE, 1, 2, *************** *** 500,509 **** char * p; char buff[2048]; ! VA_START(fmt); ! vprintf(fmt, args); ! va_end(args); ! if (Tracing) { oerrno = errno; VA_START(fmt); --- 517,538 ---- char * p; char buff[2048]; ! #ifdef HAVE_SSL ! if (tls_conn) { ! VA_START(fmt); ! vsprintf(buff,fmt, args); ! va_end(args); ! SSL_write(tls_conn, buff, strlen(buff)); ! } else { ! VA_START(fmt); ! vprintf(fmt, args); ! va_end(args); ! } ! #else ! VA_START(fmt); ! vprintf(fmt, args); ! va_end(args); ! #endif if (Tracing) { oerrno = errno; VA_START(fmt); *************** *** 520,525 **** --- 549,574 ---- errno = oerrno; } } + + #ifdef HAVE_SSL + void + Printf VA_PARAM(const char *, fmt) + { + va_list args; + char buff[2048]; + + if (tls_conn) { + VA_START(fmt); + vsprintf(buff,fmt, args); + va_end(args); + SSL_write(tls_conn, buff, strlen(buff)); + } else { + VA_START(fmt); + vprintf(fmt, args); + va_end(args); + } + } + #endif /* HAVE_SSL */ #endif /* VA_PARAM */ *** inn-2000-03-09_03-01-orig/nnrpd/nnrpd.h Thu Mar 9 20:00:59 2000 --- inn-2000-03-09_03-01/nnrpd/nnrpd.h Fri Mar 10 21:42:57 2000 *************** *** 44,50 **** ** Some convenient shorthands. */ typedef struct in_addr INADDR; - #define Printf printf /* --- 44,49 ---- *************** *** 209,214 **** --- 208,227 ---- # else # define Reply printf # endif + #endif + + #ifdef HAVE_SSL + # if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) + extern void Printf(const char *fmt, ...); + # else + # ifdef HAVE_VARARGS_H + extern void Printf(); + # else + # error Cannot use HAVE_SSL. + # endif + # endif + #else + # define Printf printf #endif char *HandleHeaders(char *article); *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/nnrpd/tls.c Fri Mar 10 22:15:32 2000 *************** *** 0 **** --- 1,606 ---- + /* tls.c --- TLSv1 functions + Copyright (C) 2000 Kenichi Okada + + Author: Kenichi Okada + Created: 2000-02-22 + + Keywords: TLS, OpenSSL + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Commentary: + + [RFC 2246] "The TLS Protocol Version 1.0" + by Christopher Allen and + Tim Dierks (1999/01) + + [RFC 2595] "Using TLS with IMAP, POP3 and ACAP" + by Chris Newman (1999/06) + + */ + + #include "config.h" + + #ifdef HAVE_SSL + + /* System library. */ + + #include + #include + #include + #include + #include + #include + + /* OpenSSL library. */ + + #include + #include + #include + #include + #include + #include + + /* Application-specific. */ + + #include "tls.h" + + /* We must keep some of the info available */ + static const char hexcodes[] = "0123456789ABCDEF"; + + static int verify_depth; + static int verify_error = X509_V_OK; + static int do_dump = 0; + static SSL_CTX *ctx = NULL; + SSL *tls_conn = NULL; + + #define CCERT_BUFSIZ 256 + static char peer_subject[CCERT_BUFSIZ]; + static char peer_issuer[CCERT_BUFSIZ]; + static char peer_CN[CCERT_BUFSIZ]; + static char issuer_CN[CCERT_BUFSIZ]; + static unsigned char md[EVP_MAX_MD_SIZE]; + static char fingerprint[EVP_MAX_MD_SIZE * 3]; + + int tls_serverengine = 0; + int tls_serveractive = 0; /* available or not */ + char *tls_peer_subject = NULL; + char *tls_peer_issuer = NULL; + char *tls_peer_fingerprint = NULL; + + int tls_clientactive = 0; /* available or not */ + char *tls_peer_CN = NULL; + char *tls_issuer_CN = NULL; + + char *tls_protocol = NULL; + const char *tls_cipher_name = NULL; + int tls_cipher_usebits = 0; + int tls_cipher_algbits = 0; + + + int tls_loglevel = 0; + + + /* taken from OpenSSL apps/s_cb.c + * tim - this seems to just be giving logging messages + */ + + static void apps_ssl_info_callback(SSL * s, int where, int ret) + { + char *str; + int w; + + if (tls_loglevel==0) return; + + w = where & ~SSL_ST_MASK; + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + + if (where & SSL_CB_LOOP) { + if (tls_serverengine && (tls_loglevel >= 2)) + Printf("%s:%s", str, SSL_state_string_long(s)); + } else if (where & SSL_CB_ALERT) { + str = (where & SSL_CB_READ) ? "read" : "write"; + if ((tls_serverengine && (tls_loglevel >= 2)) || + ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)) + Printf("SSL3 alert %s:%s:%s", str, + SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + Printf("%s:failed in %s", + str, SSL_state_string_long(s)); + else if (ret < 0) { + Printf("%s:error in %s", + str, SSL_state_string_long(s)); + } + } + } + + /* taken from OpenSSL apps/s_cb.c */ + + static RSA *tmp_rsa_cb(SSL * s, int export, int keylength) + { + static RSA *rsa_tmp = NULL; + + if (rsa_tmp == NULL) { + rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL); + } + return (rsa_tmp); + } + + /* taken from OpenSSL apps/s_cb.c */ + + static int verify_callback(int ok, X509_STORE_CTX * ctx) + { + char buf[256]; + X509 *err_cert; + int err; + int depth; + + syslog(L_NOTICE,"Doing a peer verify"); + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); + if ((tls_serveractive) && (tls_loglevel >= 1)) + Printf("Peer cert verify depth=%d %s", depth, buf); + if (ok==0) + { + syslog(L_NOTICE, "verify error:num=%d:%s", err, + X509_verify_cert_error_string(err)); + + if (verify_depth >= depth) { + ok = 0; + verify_error = X509_V_OK; + } else { + ok = 0; + verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG; + } + } + switch (ctx->error) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); + syslog(L_NOTICE, "issuer= %s", buf); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + syslog(L_NOTICE, "cert not yet valid"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + syslog(L_NOTICE, "cert has expired"); + break; + } + if ((tls_serveractive) && (tls_loglevel >= 1)) + Printf("verify return:%d", ok); + + return (ok); + } + + + /* + * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy + * and strcat by Matti Aarnio. + */ + + #define TRUNCATE + #define DUMP_WIDTH 16 + + static int tls_dump(const char *s, int len) + { + int ret = 0; + char buf[160 + 1]; + char *ss; + int i; + int j; + int rows; + int trunc; + unsigned char ch; + + trunc = 0; + + + #ifdef TRUNCATE + for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--) + trunc++; + #endif + + rows = (len / DUMP_WIDTH); + if ((rows * DUMP_WIDTH) < len) + rows++; + + for (i = 0; i < rows; i++) { + buf[0] = '\0'; /* start with empty string */ + ss = buf; + + sprintf(ss, "%04x ", i * DUMP_WIDTH); + ss += strlen(ss); + for (j = 0; j < DUMP_WIDTH; j++) { + if (((i * DUMP_WIDTH) + j) >= len) { + strcpy(ss, " "); + } else { + ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j)) + & 0xff; + sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' '); + ss += 3; + } + } + ss += strlen(ss); + *ss+= ' '; + for (j = 0; j < DUMP_WIDTH; j++) { + if (((i * DUMP_WIDTH) + j) >= len) + break; + ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j)) & 0xff; + *ss+= (((ch >= ' ') && (ch <= '~')) ? ch : '.'); + if (j == 7) *ss+= ' '; + } + *ss = 0; + /* + * if this is the last call then update the ddt_dump thing so that + * we will move the selection point in the debug window + */ + if (tls_loglevel>0) + Printf("%s", buf); + ret += strlen(buf); + } + #ifdef TRUNCATE + if (trunc > 0) { + sprintf(buf, "%04x - \n", len+ trunc); + if (tls_loglevel>0) + Printf("%s", buf); + ret += strlen(buf); + } + #endif + return (ret); + } + + /* + * Set up the cert things on the server side. We do need both the + * private key (in key_file) and the cert (in cert_file). + * Both files may be identical. + * + * This function is taken from OpenSSL apps/s_cb.c + */ + + static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file) + { + if (cert_file != NULL) { + if (SSL_CTX_use_certificate_file(ctx, cert_file, + SSL_FILETYPE_PEM) <= 0) { + syslog(L_ERROR, "unable to get certificate from '%s'", cert_file); + return (0); + } + if (key_file == NULL) + key_file = cert_file; + if (SSL_CTX_use_PrivateKey_file(ctx, key_file, + SSL_FILETYPE_PEM) <= 0) { + syslog(L_ERROR, "unable to get private key from '%s'", key_file); + return (0); + } + /* Now we know that a key and cert have been set against + * the SSL context */ + if (!SSL_CTX_check_private_key(ctx)) { + syslog(L_ERROR, "Private key does not match the certificate public key"); + return (0); + } + } + return (1); + } + + + + /* + * This is the setup routine for the SSL server. As smtpd might be called + * more than once, we only want to do the initialization one time. + * + * The skeleton of this function is taken from OpenSSL apps/s_server.c. + + * returns -1 on error + */ + + int tls_init_serverengine(int verifydepth, + int askcert, + int requirecert, + char *tls_CAfile, + char *tls_CApath, + char *tls_cert_file, + char *tls_key_file + ) + { + int off = 0; + int verify_flags = SSL_VERIFY_NONE; + char *CApath; + char *CAfile; + char *s_cert_file; + char *s_key_file; + + if (tls_serverengine) + return (0); /* already running */ + + if (tls_loglevel >= 2) + Printf("starting TLS engine"); + + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + + ctx = SSL_CTX_new(SSLv23_server_method()); + if (ctx == NULL) { + return (-1); + }; + + off |= SSL_OP_ALL; /* Work around all known bugs */ + SSL_CTX_set_options(ctx, off); + SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); + SSL_CTX_sess_set_cache_size(ctx, 128); + + if (strlen(tls_CAfile) == 0) + CAfile = NULL; + else + CAfile = tls_CAfile; + if (strlen(tls_CApath) == 0) + CApath = NULL; + else + CApath = tls_CApath; + + if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(ctx))) { + if (tls_loglevel >= 2) + Printf("TLS engine: cannot load CA data\n"); + return (-1); + } + + if (strlen(tls_cert_file) == 0) + s_cert_file = NULL; + else + s_cert_file = tls_cert_file; + if (strlen(tls_key_file) == 0) + s_key_file = NULL; + else + s_key_file = tls_key_file; + + if (!set_cert_stuff(ctx, s_cert_file, s_key_file)) { + if (tls_loglevel >= 2) + Printf("TLS engine: cannot load cert/key data\n"); + return (-1); + } + SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb); + + verify_depth = verifydepth; + if (askcert!=0) + verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + if (requirecert) + verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT + | SSL_VERIFY_CLIENT_ONCE; + SSL_CTX_set_verify(ctx, verify_flags, verify_callback); + + SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); + + tls_serverengine = 1; + return (0); + } + + + /* taken from OpenSSL apps/s_cb.c */ + + static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi, + long argl, long ret) + { + if (!do_dump) + return (ret); + + if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { + Printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int) argp, + argi, ret, (unsigned int) ret); + tls_dump(argp, (int) ret); + return (ret); + } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { + Printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int)argp, + argi, ret, (unsigned int) ret); + tls_dump(argp, (int) ret); + } + return (ret); + } + + /* + * This is the actual startup routine for the connection. We expect + * that the buffers are flushed and the "220 Ready to start TLS" was + * send to the client, so that we can immediately can start the TLS + * handshake process. + * + * layerbits and authid are filled in on sucess. authid is only + * filled in if the client authenticated + * + */ + int tls_start_servertls(int readfd, int writefd) + { + int sts; + int j; + unsigned int n; + SSL_SESSION *session; + SSL_CIPHER *cipher; + X509 *peer; + + if (!tls_serverengine) + { + /* should never happen */ + syslog(L_ERROR, "tls_engine not running"); + return (-1); + } + if (tls_loglevel >= 1) + Printf("setting up TLS connection"); + + if (tls_conn == NULL) + { + tls_conn = (SSL *) SSL_new(ctx); + } + if (tls_conn == NULL) + { + return (-1); + } + SSL_clear(tls_conn); + + + /* set the file descriptors for SSL to use */ + if (SSL_set_rfd(tls_conn, readfd)==0) + { + return (-1); + } + + if (SSL_set_wfd(tls_conn, writefd)==0) + { + return (-1); + } + + + /* + * This is the actual handshake routine. It will do all the negotiations + * and will check the client cert etc. + */ + SSL_set_accept_state(tls_conn); + + /* + * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called? + * Well there is a BIO below the SSL routines that is automatically + * created for us, so we can use it for debugging purposes. + */ + if (tls_loglevel >= 3) + BIO_set_callback(SSL_get_rbio(tls_conn), bio_dump_cb); + + /* Dump the negotiation for loglevels 3 and 4*/ + if (tls_loglevel >= 3) + do_dump = 1; + + if ((sts = SSL_accept(tls_conn)) <= 0) { /* xxx <= 0 */ + session = SSL_get_session(tls_conn); + + if (session) { + SSL_CTX_remove_session(ctx, session); + } + if (tls_conn) + SSL_free(tls_conn); + tls_conn = NULL; + return (-1); + } + /* Only loglevel==4 dumps everything */ + if (tls_loglevel < 4) + do_dump = 0; + + /* + * Lets see, whether a peer certificate is availabe and what is + * the actual information. We want to save it for later use. + */ + peer = SSL_get_peer_certificate(tls_conn); + + if (peer != NULL) { + + syslog(L_ERROR,"GOT CLIENT CERTIFICATE!!!\n"); + + X509_NAME_oneline(X509_get_subject_name(peer), + peer_subject, CCERT_BUFSIZ); + if (tls_loglevel >= 2) + Printf("subject=%s", peer_subject); + + syslog(L_ERROR, "subject=%s", peer_subject); + tls_peer_subject = peer_subject; + X509_NAME_oneline(X509_get_issuer_name(peer), + peer_issuer, CCERT_BUFSIZ); + if (tls_loglevel >= 2) + Printf("issuer=%s", peer_issuer); + tls_peer_issuer = peer_issuer; + if (X509_digest(peer, EVP_md5(), md, &n)) { + for (j = 0; j < (int) n; j++) + { + fingerprint[j * 3] = hexcodes[(md[j] & 0xf0) >> 4]; + fingerprint[(j * 3) + 1] = hexcodes[(md[j] & 0x0f)]; + if (j + 1 != (int) n) + fingerprint[(j * 3) + 2] = '_'; + else + fingerprint[(j * 3) + 2] = '\0'; + } + if (tls_loglevel >= 2) + Printf("fingerprint=%s", fingerprint); + syslog(L_ERROR,"fingerprint=%s", fingerprint); + tls_peer_fingerprint = fingerprint; + } + X509_NAME_get_text_by_NID(X509_get_subject_name(peer), + NID_commonName, peer_CN, CCERT_BUFSIZ); + tls_peer_CN = peer_CN; + X509_NAME_get_text_by_NID(X509_get_issuer_name(peer), + NID_commonName, issuer_CN, CCERT_BUFSIZ); + if (tls_loglevel >= 3) + Printf("subject_CN=%s, issuer_CN=%s", peer_CN, issuer_CN); + + syslog(L_ERROR,"subject_CN=%s, issuer_CN=%s", peer_CN, issuer_CN); + + tls_issuer_CN = issuer_CN; + /* xxx X509_free(peer);*/ + } + tls_protocol = SSL_get_version(tls_conn); + cipher = SSL_get_current_cipher(tls_conn); + + tls_cipher_name = SSL_CIPHER_get_name(cipher); + tls_cipher_usebits = SSL_CIPHER_get_bits(cipher, + &tls_cipher_algbits); + tls_serveractive = 1; + + syslog(L_NOTICE, "starttls: %s with cipher %s (%d/%d bits) no authentication", tls_protocol, tls_cipher_name, + tls_cipher_usebits, tls_cipher_algbits); + + return (0); + } + + ssize_t + SSL_writev (ssl, vector, count) + SSL *ssl; + const struct iovec *vector; + int count; + { + char *buffer; + register char *bp; + size_t bytes, to_copy; + int i; + /* Find the total number of bytes to be written. */ + bytes = 0; + for (i = 0; i < count; ++i) + bytes += vector[i].iov_len; + /* Allocate a temporary buffer to hold the data. */ + buffer = (char *) alloca (bytes); + /* Copy the data into BUFFER. */ + to_copy = bytes; + bp = buffer; + for (i = 0; i < count; ++i) + { + #define min(a, b) ((a) > (b) ? (b) : (a)) + size_t copy = min (vector[i].iov_len, to_copy); + (void) memcpy ((void *) bp, (void *) vector[i].iov_base, copy); + bp += copy; + to_copy -= copy; + if (to_copy == 0) + break; + } + return SSL_write (ssl, buffer, bytes); + } + + + #endif /* HAVE_SSL */ *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/nnrpd/tls.h Fri Mar 10 21:42:57 2000 *************** *** 0 **** --- 1,56 ---- + /* tls.h --- TLSv1 functions + Copyright (C) 2000 Kenichi Okada + + Author: Kenichi Okada + Created: 2000-02-22 + + Keywords: TLS, OpenSSL + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Commentary: + + [RFC 2246] "The TLS Protocol Version 1.0" + by Christopher Allen and + Tim Dierks (1999/01) + + [RFC 2595] "Using TLS with IMAP, POP3 and ACAP" + by Chris Newman (1999/06) + + */ + + #ifdef HAVE_SSL + + #ifndef TLS_H + #define TLS_H + + /* init tls */ + int tls_init_serverengine(int verifydepth, /* depth to verify */ + int askcert, /* 1 = verify client */ + int requirecert, /* 1 = another client verify? */ + char *tls_CAfile, + char *tls_CApath, + char *tls_cert_file, + char *tls_key_file); + + /* start tls negotiation */ + int tls_start_servertls(int readfd, int writefd); + + ssize_t SSL_writev (SSL *ssl, const struct iovec *vector, int count); + + #endif /* CYRUSTLS_H */ + + #endif /* HAVE_SSL */ *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/nnrpd/sasl_config.c Fri Mar 10 21:42:57 2000 *************** *** 0 **** --- 1,180 ---- + /* sasl_config.c -- Configuration routines + Copyright (C) 2000 Kenichi Okada + + Author: Kenichi Okada + Created: 2000-03-04 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + #include "config.h" + + #ifdef HAVE_SSL + + #include + #include + #include + #include + #include + #include + + #include "paths.h" + #include "sasl_config.h" + + extern char *xstrdup (const char *str); + + struct configlist { + char *key; + char *value; + }; + + static struct configlist *configlist; + static int nconfiglist; + + const char *sasl_config_getstring(key, def) + const char *key; + const char *def; + { + int opt; + + for (opt = 0; opt < nconfiglist; opt++) { + if (*key == configlist[opt].key[0] && + !strcmp(key, configlist[opt].key)) + return configlist[opt].value; + } + return def; + } + + int sasl_config_getint(key, def) + const char *key; + int def; + { + const char *val = sasl_config_getstring(key, (char *)0); + + if (!val) return def; + if (!isdigit(*val) && (*val != '-' || !isdigit(val[1]))) return def; + return atoi(val); + } + + int sasl_config_getswitch(key, def) + const char *key; + int def; + { + const char *val = sasl_config_getstring(key, (char *)0); + + if (!val) return def; + + if (*val == '0' || *val == 'n' || + (*val == 'o' && val[1] == 'f') || *val == 'f') { + return 0; + } + else if (*val == '1' || *val == 'y' || + (*val == 'o' && val[1] == 'n') || *val == 't') { + return 1; + } + return def; + } + + const char *sasl_config_partitiondir(partition) + const char *partition; + { + char buf[80]; + + if (strlen(partition) > 70) return 0; + strcpy(buf, "partition-"); + strcat(buf, partition); + + return sasl_config_getstring(buf, (char *)0); + } + + #define CONFIGLISTGROWSIZE 10 /* 100 */ + void + sasl_config_read() + { + FILE *infile; + int lineno = 0; + int alloced = 0; + char buf[4096]; + char *p, *key; + + infile = fopen(_PATH_SASL_CONFIG, "r"); + if (!infile) { + fprintf(stderr, "can't open configuration file %s\n", _PATH_SASL_CONFIG); + exit(1); + } + + while (fgets(buf, sizeof(buf), infile)) { + lineno++; + + if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + for (p = buf; *p && isspace(*p); p++); + if (!*p || *p == '#') continue; + + key = p; + while (*p && (isalnum(*p) || *p == '-' || *p == '_')) { + if (isupper(*p)) *p = tolower(*p); + p++; + } + if (*p != ':') { + fprintf(stderr, + "invalid option name on line %d of configuration file\n", + lineno); + exit(1); + } + *p++ = '\0'; + + while (*p && isspace(*p)) p++; + + if (!*p) { + fprintf(stderr, "empty option value on line %d of configuration file\n", + lineno); + exit(1); + } + + if (nconfiglist == alloced) { + alloced += CONFIGLISTGROWSIZE; + configlist = (struct configlist *) + xrealloc((char *)configlist, alloced*sizeof(struct configlist)); + } + + configlist[nconfiglist].key = xstrdup(key); + configlist[nconfiglist].value = xstrdup(p); + nconfiglist++; + } + fclose(infile); + } + + /* + * Call proc (expected to be todo_append in reconstruct.c) with + * information on each configured partition + */ + void + sasl_config_scanpartition(proc) + void (*proc)(); + { + int opt; + char *s; + + for (opt = 0; opt < nconfiglist; opt++) { + if (!strncmp(configlist[opt].key, "partition-", 10)) { + s = xstrdup(configlist[opt].value); + (*proc)(xstrdup(""), s, configlist[opt].key+10); + } + } + } + + #endif /* HAVE_SSL */ *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/nnrpd/sasl_config.h Fri Mar 10 21:42:57 2000 *************** *** 0 **** --- 1,41 ---- + /* sasl_config.h + Copyright (C) 2000 Kenichi Okada + + Author: Kenichi Okada + Created: 2000-03-04 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + #ifndef SASL_CONFIG_H + #define SASL_CONFIG_H + + #ifndef P + #ifdef __STDC__ + #define P(x) x + #else + #define P(x) () + #endif + #endif + + extern void sasl_config_read P((void)); + extern const char *sasl_config_getstring P((const char *key, const char *def)); + extern int sasl_config_getint P((const char *key, int def)); + extern int sasl_config_getswitch P((const char *key, int def)); + extern const char *sasl_config_partitiondir P((const char *partition)); + + #endif /* SASL_SASL_CONFIG_H */ *** inn-2000-03-09_03-01-orig/samples/Makefile Sat Dec 18 02:06:40 1999 --- inn-2000-03-09_03-01/samples/Makefile Fri Mar 10 21:42:57 2000 *************** *** 14,20 **** EXTRA = actsync.cfg checkgroups inn.conf innreport.conf \ innwatch.ctl newsfeeds nnrpd_auth.pl startup.tcl \ ! nnrpd_auth.py all: $(ALL) --- 14,20 ---- EXTRA = actsync.cfg checkgroups inn.conf innreport.conf \ innwatch.ctl newsfeeds nnrpd_auth.pl startup.tcl \ ! nnrpd_auth.py sasl.conf all: $(ALL) *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/samples/sasl.conf.in Fri Mar 10 21:42:57 2000 *************** *** 0 **** --- 1,3 ---- + tls_ca_path: @prefix@/lib + tls_cert_file: @prefix@/lib/cert.pem + tls_key_file: @prefix@/lib/cert.pem *** inn-2000-03-09_03-01-orig/site/Makefile Thu Mar 9 20:01:08 2000 --- inn-2000-03-09_03-01/site/Makefile Fri Mar 10 21:42:57 2000 *************** *** 45,50 **** --- 45,51 ---- PATH_BUFFINDEXED = ${PATHETC}/buffindexed.conf PATH_RADIUS_CONF = ${PATHETC}/radius.conf PATH_OVDB_CONF = ${PATHETC}/ovdb.conf + PATH_SASL_CONF = ${PATHETC}/sasl.conf ## Order: innd, control, expire, inews, sending, misc MOST = checkgroups default ihave newgroup \ *************** *** 63,69 **** innfeed.conf startup_innd.pl filter_innd.pl filter_nnrpd.pl \ filter_innd.py INN.py \ startup.tcl filter.tcl nnrpd_auth.pl news2mail.cf readers.conf \ ! radius.conf nnrpd_auth.py ovdb.conf ALL = $(MOST) $(REST) --- 64,70 ---- innfeed.conf startup_innd.pl filter_innd.pl filter_nnrpd.pl \ filter_innd.py INN.py \ startup.tcl filter.tcl nnrpd_auth.pl news2mail.cf readers.conf \ ! radius.conf nnrpd_auth.py ovdb.conf sasl.conf ALL = $(MOST) $(REST) *************** *** 91,97 **** $D$(PATH_PYTHON_FILTER_INND) $D$(PATH_PYTHON_INN_MODULE) \ $D$(PATH_TCL_STARTUP) $D$(PATH_TCL_FILTER) \ $D$(PATH_NNRPAUTH) $D$(PATHETC)/news2mail.cf $D$(PATH_READERSCONF) \ ! $D$(PATH_RADIUS_CONF) $D$(PATH_NNRPYAUTH) $D$(PATH_OVDB_CONF) ALL_INSTALLED = $(MOST_INSTALLED) $(REST_INSTALLED) --- 92,99 ---- $D$(PATH_PYTHON_FILTER_INND) $D$(PATH_PYTHON_INN_MODULE) \ $D$(PATH_TCL_STARTUP) $D$(PATH_TCL_FILTER) \ $D$(PATH_NNRPAUTH) $D$(PATHETC)/news2mail.cf $D$(PATH_READERSCONF) \ ! $D$(PATH_RADIUS_CONF) $D$(PATH_NNRPYAUTH) $D$(PATH_OVDB_CONF) \ ! $D$(PATH_SASL_CONF) ALL_INSTALLED = $(MOST_INSTALLED) $(REST_INSTALLED) *************** *** 202,207 **** --- 204,210 ---- $D$(PATH_ACTSYNC_IGN): actsync.ign ; $(COPY_RPRI) $? $@ $D$(PATH_MOTD): motd.news ; $(COPY_RPRI) $? $@ $D$(PATH_INNFEEDCTL): innfeed.conf ; $(COPY_RPRI) $? $@ + $D$(PATH_SASL_CONF): sasl.conf ; $(COPY_RPRI) $? $@ REASON = 'Installing site config files from site/Makefile' go pause: *************** *** 268,273 **** --- 271,277 ---- startup_innd.pl: ../samples/startup_innd.pl ; $(COPY) $? $@ version: ../samples/version ; $(COPY) $? $@ version.pl: ../samples/version.pl ; $(COPY) $? $@ + sasl.conf: ../samples/sasl.conf ; $(COPY) $? $@ ## Dependencies. Default list, below, is probably good enough. depend: Makefile $(SOURCES) *** /dev/null Tue Nov 23 00:21:32 1999 --- inn-2000-03-09_03-01/doc/pod/sasl.conf.pod Fri Mar 10 21:43:19 2000 *************** *** 0 **** --- 1,82 ---- + =head1 NAME + + sasl.conf - SASL Configuration file for nnrpd. + + =head1 DESCRIPTION + + The file F in I specifies Simple Authentication + and Security Layer (SASL), defined in RFC 2222, for nnrpd. + Now nnrpd implements only Security Layer support, which is an extension + of RFC 2595. This means you can get SSL or TLS encrypted NNRP between + your server and newsreaders. It requires OpenSSL 0.9.3 or newer + http://www.openssl.org/; it has been tested with versions 0.9.4 and 0.9.5. + + =head1 INSTALLATION + + To use SSL, a certificate and private key are needed that you can + create using the openssl binary. + Make certain that each keys are owned by your news user, news group, + and are mode 0640 or 0660. + + =head2 EXAMPLE + + openssl req -new -x509 -nodes -out /usr/local/news/lib/cert.pem\ + -days 366 -keyout /usr/local/news/lib/cert.pem + chown news:news /usr/local/news/lib/cert.pem + chmod 640 /usr/local/news/lib/cert.pem + + You also can make the keys by the root user as follows. + + make cert + + =head1 CONFIGURATION + + Comments begin with a number sign (C<#>) and continue through the + end of the line. Blank lines and comments are ignored. + All other lines specify parameters, and should be of the following form: + + Each line of the F in I has the form + +