imapfeed patches

Ken Murchison ken at oceana.com
Fri Jun 28 20:13:05 UTC 2002



"Jeffrey M. Vinocur" wrote:
> 
> Your patch got eaten by the list manager.  Please resend uncompressed :-/

Sorry.  Here you go.

FWIW, I worked closely with the folks at CMU on this.  In fact they
proposed the adding of the To: header to faciliate wide replies.  I like
the idea and hope I implemented it correctly.

-- 
Kenneth Murchison     Oceana Matrix Ltd.
Software Engineer     21 Princeton Place
716-662-8973 x26      Orchard Park, NY 14127
--PGP Public Key--    http://www.oceana.com/~ken/ksm.pgp

-- Attached file included as plaintext by Ecartis --
-- File: imapfeed.patches

diff -ur ../inn-CURRENT-20020621.orig/Makefile.global.in ./Makefile.global.in
--- ../inn-CURRENT-20020621.orig/Makefile.global.in	Fri Jun 21 05:01:18 2002
+++ ./Makefile.global.in	Mon Jun 24 11:09:35 2002
@@ -127,6 +127,12 @@
 SSLINC          = @SSL_INC@
 SSLBIN          = @SSL_BIN@
 
+##  SASL support.  Additional flags and libraries used when compiling or
+##  linking code that contains SASL support.
+
+SASLLIB         = @SASL_LIB@
+SASLINC         = @SASL_INC@
+
 ##  Missing functions.  If non-empty, configure detected that your system
 ##  was missing some standard functions, and INN will be providing its own
 ##  replacements from the lib directory.
diff -ur ../inn-CURRENT-20020621.orig/configure.in ./configure.in
--- ../inn-CURRENT-20020621.orig/configure.in	Fri Jun 21 05:00:04 2002
+++ ./configure.in	Wed Jun 26 12:41:16 2002
@@ -413,6 +413,49 @@
 AC_SUBST(SSL_LIB)])
 INN_LIB_OPENSSL
 
+dnl Check for whether the user wants to compile with SASL, and if so what
+dnl the path to the various components of it is.
+AC_DEFUN([INN_LIB_SASL],
+[AC_ARG_WITH(sasl,
+    [  --with-sasl=PATH     Enable SASL (for imapfeed and NNTP AUTH support)],
+    SASL_DIR=$with_sasl,
+    SASL_DIR=no)
+AC_MSG_CHECKING(if SASL is desired)
+if test x"$SASL_DIR" = xno ; then
+    AC_MSG_RESULT(no)
+    SASL_INC=
+    SASL_LIB=
+else
+    AC_MSG_RESULT(yes)
+    AC_MSG_CHECKING(for SASL location)
+    if test x"$SASL_DIR" = xyes ; then
+        for dir in $prefix /usr/local/sasl /usr/lib/sasl /usr/sasl /usr/pkg \
+                   /usr/local /usr ; do
+            if test -f "$dir/include/sasl/sasl.h" ; then
+                SASL_DIR=$dir
+                break
+            fi
+        done
+    fi
+    if test x"$SASL_DIR" = xyes ; then
+        AC_MSG_ERROR(Can not find SASL)
+    else
+        AC_MSG_RESULT($SASL_DIR)
+	SASL_INC="-I${SASL_DIR}/include"
+
+        inn_save_LIBS=$LIBS
+        LIBS="$LIBS -L${SASL_DIR}/lib"
+	AC_CHECK_LIB(sasl, sasl_getprop,
+                     [SASL_LIB="-L${SASL_DIR}/lib -lsasl2"],
+                     [AC_MSG_ERROR(Can not find SASL)],)
+        LIBS=$inn_save_LIBS
+        AC_DEFINE(HAVE_SASL, 1, [Define if SASL is available.])
+    fi
+fi
+AC_SUBST(SASL_INC)
+AC_SUBST(SASL_LIB)])
+INN_LIB_SASL
+
 dnl Checks for embedded interpretors.
 dnl
 dnl FIXME: These should ideally be combined with the later logic to
diff -ur ../inn-CURRENT-20020621.orig/doc/man/innfeed.conf.5 ./doc/man/innfeed.conf.5
--- ../inn-CURRENT-20020621.orig/doc/man/innfeed.conf.5	Fri Jun 21 05:00:20 2002
+++ ./doc/man/innfeed.conf.5	Tue Jun 25 16:01:32 2002
@@ -518,11 +518,25 @@
 This is the appropriate password for authname.
 .TP
 .B deliver-username
-The username is who you want to "act" as, that is, who is actually going to be using the server.
+The username is who you want to "act" as, that is, who is actually
+going to be using the server.
 .TP
 .B deliver-realm
-In this case, the "realm" is the realm in which the specified authname is valid.  Currently this is only needed by the DIGEST-MD5 SASL
+In this case, the "realm" is the realm in which the specified authname
+is valid.  Currently this is only needed by the DIGEST-MD5 SASL
 mechanism.
+.TP
+.B deliver-rcpt-to
+A printf-style format string for creating the envelope recipient address.
+The pattern MUST include a single string specifier which will be
+replaced with the newgroup (e.g "bb+%s").  The default is "+%s".
+.TP
+.B deliver-to-header
+An optional printf-style format string for creating a To: header to be
+prepended to the article.  The pattern MUST include a single string
+specifier which will be replaced with the newgroup (e.g
+"post+%s at domain").  If not specified, the To: header will not be
+prepended.
 .RE
 .\"..................................................
 .SH "PEER VALUES"
diff -ur ../inn-CURRENT-20020621.orig/include/config.h.in ./include/config.h.in
--- ../inn-CURRENT-20020621.orig/include/config.h.in	Fri Jun 21 05:00:36 2002
+++ ./include/config.h.in	Mon Jun 24 11:08:05 2002
@@ -408,6 +408,9 @@
 /* Define if BerkeleyDB is available. */
 #undef USE_BERKELEY_DB
 
+/* Define if SASL is available. */
+#undef HAVE_SASL
+
 /* Define if OpenSSL is available. */
 #undef HAVE_SSL
 
diff -ur ../inn-CURRENT-20020621.orig/innfeed/Makefile ./innfeed/Makefile
--- ../inn-CURRENT-20020621.orig/innfeed/Makefile	Fri Jun 21 05:00:41 2002
+++ ./innfeed/Makefile	Mon Jun 24 11:46:49 2002
@@ -3,7 +3,7 @@
 include ../Makefile.global
 
 top	        = ..
-CFLAGS		= $(GCFLAGS)
+CFLAGS		= $(GCFLAGS) $(SASLINC)
 
 ALL		= innfeed procbatch startinnfeed imapfeed
 
@@ -43,7 +43,8 @@
 
 ##  Compilation rules.
 
-INNFEEDLIBS	= $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
+INNFEEDLIBS	= $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) \
+		  $(SASLLIB) $(LIBS)
 
 config_y.c config_y.h: configfile.y
 	$(YACC) -d $?
diff -ur ../inn-CURRENT-20020621.orig/innfeed/imap_connection.c ./innfeed/imap_connection.c
--- ../inn-CURRENT-20020621.orig/innfeed/imap_connection.c	Fri Jun 21 05:00:43 2002
+++ ./innfeed/imap_connection.c	Wed Jun 26 13:25:02 2002
@@ -21,10 +21,6 @@
    untagged IMAP messages
 */
 
-#ifdef HAVE_SASL
-# include <sasl.h>
-#endif
-
 #include "config.h"
 #include "clibrary.h"
 #include "portable/socket.h"
@@ -48,6 +44,10 @@
 #include "msgs.h"
 #include "configfile.h"
 
+#ifdef HAVE_SASL
+# include <sasl/sasl.h>
+#endif
+
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 1024
 #endif
@@ -60,9 +60,6 @@
 # define LMTP_PORT 2003
 #endif
 
-/* The name to prepend to deliver directly to newsgroup bboards */
-#define NEWS_USERNAME "bb"
-
 #define IMAP_TAGLENGTH 6
 
 #define QUEUE_MAX_SIZE 250
@@ -76,6 +73,8 @@
 extern char *deliver_authname;
 extern char *deliver_password;
 extern char *deliver_realm;
+extern char *deliver_rcpt_to;
+extern char *deliver_to_header;
 
 
 char hostname[MAXHOSTNAMELEN];
@@ -1331,11 +1330,39 @@
   return ret;
 }
 
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID	0
+#endif
+#ifndef NI_MAXHOST
+#define NI_MAXHOST	1025
+#endif
+#ifndef NI_MAXSERV
+#define NI_MAXSERV	32
+#endif
+
+static int iptostring(const struct sockaddr *addr, socklen_t addrlen,
+		     char *out, unsigned outlen) {
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    
+    if(!addr || !out) return SASL_BADPARAM;
+
+    getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
+		NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
+
+    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
+	return SASL_BUFOVER;
+
+    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
+
+    return SASL_OK;
+}
+
 static conn_ret SetSASLProperties(sasl_conn_t *conn, int sock, int minssf, int maxssf)
 {
   int saslresult;
   sasl_security_properties_t *secprops=NULL;
   int addrsize=sizeof(struct sockaddr_in);
+  char localip[60], remoteip[60];
   struct sockaddr_in saddr_l;
   struct sockaddr_in saddr_r;
 
@@ -1350,16 +1377,24 @@
   if (getpeername(sock,(struct sockaddr *)&saddr_r,&addrsize)!=0)
     return RET_FAIL;
 
-  if (sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r)!=SASL_OK)
+  if (iptostring((struct sockaddr *)&saddr_r, sizeof(struct sockaddr_in),
+		remoteip, sizeof(remoteip)))
+    return RET_FAIL;
+
+  if (sasl_setprop(conn, SASL_IPREMOTEPORT, remoteip)!=SASL_OK)
     return RET_FAIL;
   
   addrsize=sizeof(struct sockaddr_in);
   if (getsockname(sock,(struct sockaddr *) &saddr_l,&addrsize)!=0)
     return RET_FAIL;
 
-  if (sasl_setprop(conn, SASL_IP_LOCAL, &saddr_l)!=SASL_OK)
+  if (iptostring((struct sockaddr *)&saddr_l, sizeof(struct sockaddr_in),
+		 localip, sizeof(localip)))
     return RET_FAIL;
-
+    
+  if (sasl_setprop(conn, SASL_IPLOCALPORT, localip)!=SASL_OK)
+    return RET_FAIL;
+  
   return RET_OK;
 }
 #endif /* HAVE_SASL */
@@ -1503,6 +1538,8 @@
     saslresult=sasl_client_new("lmtp",
 			       serverName,
 			       NULL,
+			       NULL,
+			       NULL,
 			       0,
 			       &cxn->saslconn_lmtp);
 
@@ -1593,6 +1630,8 @@
     saslresult=sasl_client_new("imap",
 			       serverName,
 			       NULL,
+			       NULL,
+			       NULL,
 			       0,
 			       &cxn->imap_saslconn);
 
@@ -2083,10 +2122,8 @@
     int saslresult;
     
     const char *mechusing;
-    char *out;
+    const char *out;
     unsigned int outlen;
-    char *in;
-    unsigned int inlen;
     char *inbase64;
     int inbase64len;
     int status;
@@ -2099,7 +2136,7 @@
 
     saslresult=sasl_client_start(cxn->saslconn_lmtp, 
 				 cxn->lmtp_capabilities->saslmechs,
-				 NULL, &client_interact,
+				 &client_interact,
 				 &out, &outlen,
 				 &mechusing);
 
@@ -2119,10 +2156,15 @@
 
     p = (char *) malloc(strlen(mechusing)+(outlen*2+10)+30);
 
-    if (out!=NULL)
+    if (!out)
     {
-
-	/* convert to base64 */
+	/* no initial client response */
+	sprintf (p, "AUTH %s\r\n",mechusing);
+    } else if (!outlen) {
+	/* empty initial client response */
+	sprintf (p, "AUTH %s =\r\n",mechusing);
+    } else {
+	/* initial client response - convert to base64 */
 	inbase64 = (char *) malloc(outlen*2+10);
 
 	saslresult = sasl_encode64(out, outlen,
@@ -2130,8 +2172,6 @@
 	if (saslresult != SASL_OK) return RET_FAIL;
 
 	sprintf (p, "AUTH %s %s\r\n",mechusing,inbase64);
-    } else {
-	sprintf (p, "AUTH %s\r\n",mechusing);
     }
 
     result = WriteToWire_lmtpstr(cxn, p, strlen(p));
@@ -2174,7 +2214,7 @@
 
   /* decode this line */      
   saslresult = sasl_decode64(str, strlen(str), 
-			     *line, (unsigned *) linelen);
+			     *line, strlen(str)+1, (unsigned *) linelen);
   if (saslresult != SASL_OK) {
       d_printf(0,"?:?:LMTP base64 decoding error\n");
       return STAT_NO;
@@ -2360,7 +2400,7 @@
     int saslresult;
     char in[4096];
     unsigned int inlen;
-    char *out;
+    const char *out;
     unsigned int outlen;
     char *inbase64;
     unsigned int inbase64len;
@@ -2368,7 +2408,7 @@
     /* base64 decode it */
 
     saslresult = sasl_decode64(str, strlen(str), 
-			       in, &inlen);
+			       in, strlen(str)+1, &inlen);
     if (saslresult != SASL_OK) {
 	d_printf(0,"%s:%d:IMAP base64 decoding error\n",
 		 hostPeerName (cxn->myHost), cxn->ident) ;
@@ -2404,8 +2444,6 @@
     strcpy(inbase64 + inbase64len, "\r\n");
     inbase64len+=2;
     
-    if (out!=NULL) free(out);
-		    
     /* send to server */
     result = WriteToWire_imapstr(cxn,inbase64, inbase64len);
     
@@ -2423,21 +2461,19 @@
     char *p;
 
 #ifdef HAVE_SASL
-    char *out;
-    unsigned int outlen;
-    char *in;
-    unsigned int inlen;
     char *inbase64;
     int inbase64len;
-    int saslresult;
+    int saslresult=SASL_NOMECH;
 
     sasl_interact_t *client_interact=NULL;
 
-    saslresult=sasl_client_start(cxn->imap_saslconn, 
-				 cxn->imap_capabilities->saslmechs,
-				 NULL, &client_interact,
-				 &out, &outlen,
-				 &mechusing);
+    if (cxn->imap_capabilities->saslmechs) {
+	saslresult=sasl_client_start(cxn->imap_saslconn, 
+				     cxn->imap_capabilities->saslmechs,
+				     &client_interact,
+				     NULL, NULL,
+				     &mechusing);
+    }
 
 
 
@@ -2750,8 +2786,10 @@
           
     }
 
-    d_printf(1,"?:?:IMAP parsed capabilities: saslmechs = %s\n",
-	     (*caps)->saslmechs);
+    if ((*caps)->saslmechs) {
+	d_printf(1,"?:?:IMAP parsed capabilities: saslmechs = %s\n",
+		 (*caps)->saslmechs);
+    }
 
     return RET_OK;
 }
@@ -3185,7 +3223,7 @@
     int inlen;
     char *in;
     int outlen;
-    char *out;
+    const char *out;
     char *inbase64;
     int inbase64len;
     imt_stat status;
@@ -3406,7 +3444,6 @@
 		    saslresult = sasl_encode64(out, outlen,
 					       inbase64, outlen*2+10, 
 					       (unsigned *) &inbase64len);
-		    free(out);
 		    
 		    if (saslresult != SASL_OK)
 		    {
@@ -3616,7 +3653,8 @@
 {
     int size = strlen(*out);
     int fsize = size;
-    int newsize = size + 9+strlen(NEWS_USERNAME)+1+newrcptlen+3;
+    int newsize = size + 9+strlen(deliver_rcpt_to)+newrcptlen+3;
+    char c;
 
     /* see if we need to grow the string */
     if (newsize > *outalloc)
@@ -3626,11 +3664,13 @@
 	ASSERT(*out);
     }
 
-    sprintf((*out)+size,"RCPT TO:<%s+",NEWS_USERNAME);
-    size+=9+strlen(NEWS_USERNAME)+1;
-    
-    memcpy((*out)+size, newrcpt, newrcptlen);
-    size+=newrcptlen;
+    strcpy((*out)+size,"RCPT TO:<");
+    size+=9;
+
+    c=newrcpt[newrcptlen];
+    newrcpt[newrcptlen]='\0';
+    size+=sprintf((*out)+size,deliver_rcpt_to,newrcpt);
+    newrcpt[newrcptlen]=c;
 
     strcpy((*out)+size,">\r\n");    
 
@@ -3688,6 +3728,80 @@
     return ret;
 }
 
+static void addto(char *newrcpt, int newrcptlen, char *sep,
+		  char **out, int *outalloc)
+{
+    int size = strlen(*out);
+    int fsize = size;
+    int newsize = size + strlen(sep)+1+strlen(deliver_to_header)+newrcptlen+1;
+    char c;
+
+    /* see if we need to grow the string */
+    if (newsize > *outalloc)
+    {
+	(*outalloc)+=200;
+	(*out) = realloc(*out, *outalloc);
+	ASSERT(*out);
+    }
+
+    size+=sprintf((*out)+size,"%s<",sep);
+
+    c = newrcpt[newrcptlen];
+    newrcpt[newrcptlen]='\0';
+    size+=sprintf((*out)+size,deliver_to_header,newrcpt);
+    newrcpt[newrcptlen]=c;
+
+    strcpy((*out)+size,">");    
+}
+
+/*
+ * Takes the newsgroups header value and makes it into a To: header
+ *
+ *  in     - newsgroups header start
+ *  in_end - end of newsgroups header
+ */
+
+static char *BuildToHeader(char *in, char *in_end)
+{
+    int retalloc = 400;
+    char *ret = malloc(retalloc);
+    char *str = in;
+    char *laststart = in;
+    char *sep = "";
+
+    /* start it off with the header name */     
+    strcpy(ret,"To: ");
+    
+    while ( str !=  in_end)
+    {
+	if ((*str) == ',')
+	{
+	    /* eliminate leading whitespace */
+	    while (((*laststart) ==' ') || ((*laststart)=='\t'))
+	    {
+		laststart++;
+	    }
+
+	    addto(laststart, str - laststart, sep, &ret, &retalloc);
+	    laststart = str+1;
+
+	    /* separate multiple addresses with a comma */
+	    sep = ", ";
+	}
+
+	str++;
+    }
+
+    if (laststart<str)
+    {
+	addto(laststart, str - laststart, sep, &ret, &retalloc);
+    }
+
+    /* terminate the header */
+    strcat(ret, "\n\r");
+    return ret;
+}
+
 /*************************** END LMTP reading functions ****************************/
 
 
@@ -3882,7 +3996,7 @@
        send:
          rset
          mail from
-	 rctp to
+	 rcpt to
 	 data
     */
 
@@ -3921,6 +4035,34 @@
 	return;
     }
 
+    /* prepend To: header to article */
+    if (deliver_to_header) {
+	char *to_list, *to_list_end;
+	int i, len;
+
+	result = FindHeader(cxn->current_bufs, "Followup-To", 
+			    &to_list, &to_list_end);
+
+	if ((result != RET_OK) || (to_list == NULL)) {
+	    result = FindHeader(cxn->current_bufs, "Newsgroups", 
+				&to_list, &to_list_end);
+	}
+
+	/* free's original to_list */
+	to_list = BuildToHeader(to_list, to_list_end);
+
+	len = bufferArrayLen(cxn->current_bufs);
+	cxn->current_bufs = REALLOC(cxn->current_bufs, Buffer, len+2);
+	cxn->current_bufs[len+1] = NULL;
+
+	for (i = len; i > 0; i--) {
+	    cxn->current_bufs[i] = cxn->current_bufs[i-1];
+	}
+
+	cxn->current_bufs[0] = newBufferByCharP(to_list, strlen(to_list+1),
+						strlen(to_list));
+    }
+
     hostArticleOffered (cxn->myHost, cxn);
 }
 
diff -ur ../inn-CURRENT-20020621.orig/innfeed/main.c ./innfeed/main.c
--- ../inn-CURRENT-20020621.orig/innfeed/main.c	Fri Jun 21 05:00:43 2002
+++ ./innfeed/main.c	Tue Jun 25 15:22:54 2002
@@ -85,10 +85,12 @@
 void (*gPrintInfo) (void) ;
 char *dflTapeDir;
 /* these are used by imapfeed */
-char *deliver_username = NULL;
-char *deliver_authname = NULL;
-char *deliver_password = NULL;
-char *deliver_realm    = NULL;
+char *deliver_username  = NULL;
+char *deliver_authname  = NULL;
+char *deliver_password  = NULL;
+char *deliver_realm     = NULL;
+char *deliver_rcpt_to   = "+%s";
+char *deliver_to_header = NULL;
 
 /* imports */
 extern char *versionInfo ;
@@ -840,6 +842,18 @@
       /* don't need to free */
     }
 
+  if (getString (topScope,"deliver-rcpt-to",&p, NO_INHERIT))
+    {
+      deliver_rcpt_to = p;
+      /* don't need to free */
+    }
+
+  if (getString (topScope,"deliver-to-header",&p, NO_INHERIT))
+    {
+      deliver_to_header = p;
+      /* don't need to free */
+    }
+
   
 
   return 1 ;




More information about the inn-bugs mailing list