Article delegate-en/3477 of [1-5169] on the server localhost:119
  upper oldest olders older1 this newer1 newers latest
search
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
[Reference:<_A3476@delegate-en.ML_>]
Newsgroups: mail-lists.delegate-en

[DeleGate-En] Re: Pop3proxy -- Timeout with malformed MimeMessages
31 Aug 2006 03:31:20 GMT feedback@delegate.org (Yutaka Sato)
The DeleGate Project


Hi,

In message <_A3476@delegate-en.ML_> on 08/31/06(01:23:48) I wrote:
 |In message <_A3475@delegate-en.ML_> on 08/31/06(00:37:08) I wrote:
 | | |Delegate strips away all the spaces and sends then only 0E0D0A.
 | | |The client wait  for 0D0A0E0D0A   as EOF-mark,
 | | |so after  60 sec he has a timeout and disconnects the session.
 | |
 | |The problem is caused because DeleGate uses fgets() and fputs() to
 | |get and put the message on POP.
 | |A simple workaround to escape the problem is encoding '\0' into
 | |0xC0 0x80 (or \300\200, UTF-8 string which represents zero) at
 | |the input, and decoding it at the output.  It can be done like the
 | |enclosed patch (a patch to be applied to DeleGate/9.2.4-pre19).
 |
 |Sorry, I found that the patch is not enough for POP, and encoding
 |a character into multi-bytes might cause another problem on the
 |buffer boundary.
 |So just ignoring '\0' might be the practical workaround as the
 |enclosed patch.

I released 9.2.4-pre20 with the workaround.  It simply ignores '\0' in
a messege by default.
You can test to relay '\0' as is with an option MIMECONV="zero:utf8"

Cheers,
Yutaka
--
  9 9   Yutaka Sato <y.sato@delegate.org> http://delegate.org/y.sato/
 ( ~ )  National Institute of Advanced Industrial Science and Technology
_<   >_ 1-1-4 Umezono, Tsukuba, Ibaraki, 305-8568 Japan
Do the more with the less -- B. Fuller


diff -cr delegate9.2.4-pre19/include/ystring.h delegate9.2.4-pre20/include/ystring.h
*** delegate9.2.4-pre19/include/ystring.h	Wed Aug  9 10:23:12 2006
--- delegate9.2.4-pre20/include/ystring.h	Thu Aug 31 08:36:58 2006
***************
*** 228,233 ****
--- 228,248 ----
  int Xfprintf(FILE *fp,PCStr(fmt),...);
  #define fprintf	Xfprintf
    
+ extern int FGSZ_flags;
+ #define FGSZ_ISSET	1
+ #define FGSZ_NONE	2
+ #define FGSZ_KILL	4
+ #define FGSZ_UTF8	8
+ 
+ #ifdef DOFGSZ
+ #undef fgets
+ #undef fputs
+ const char *fgetsZ(PVStr(str),int siz,FILE *fp);
+ int fputsZ(PCStr(str),FILE *fp);
+ #define fgets(s,z,f)	fgetsZ(AVStr(s),z,f)
+ #define fputs(s,f)	fputsZ(s,f)
+ #endif
+ 
  /*
  #ifdef __cplusplus
  class CString {
diff -cr delegate9.2.4-pre19/mimekit/mime.c delegate9.2.4-pre20/mimekit/mime.c
*** delegate9.2.4-pre19/mimekit/mime.c	Wed Aug 23 17:46:50 2006
--- delegate9.2.4-pre20/mimekit/mime.c	Thu Aug 31 09:41:58 2006
***************
*** 19,24 ****
--- 19,25 ----
  	950312	encode/decode parts in a multipart message
  //////////////////////////////////////////////////////////////////////#*/
  
+ #define DOFGSZ
  #include "mime.h"
  #ifdef MIMEKIT
  #define strid_alloc(s)	stralloc(s)
***************
*** 157,162 ****
--- 158,173 ----
  				MIME_CONV &= ~C_ENCODE(C_HEAD_SPENC); else
  	if( streq(spec,"charcode") )
  				MIME_CONV = C_DECODE(C_CHAR)|C_ENCODE(C_CHAR);
+ 	else
+ 	if( streq(spec,"zero:none") ){
+ 		FGSZ_flags = FGSZ_NONE;
+ 	}else
+ 	if( streq(spec,"zero:utf8") ){
+ 		FGSZ_flags = FGSZ_UTF8;
+ 	}else
+ 	if( streq(spec,"zero:kill") ){
+ 		FGSZ_flags = FGSZ_KILL;
+ 	}
  	else	syslog_ERROR("#### ERROR: unknown MIMECONV=%s\n",spec);
  	return 0;
  }
***************
*** 598,604 ****
--- 609,618 ----
  			}
  			skipping = 0;
  
+ 			/*
  			wordscanY(hp,AVStr(cur_field),sizeof(cur_field),"^: \t\r\n");
+ 			*/
+ 			wordscanY(hp,AVStr(cur_field),sizeof(cur_field),"^: \300\t\r\n");
  			conv_field = strncasecmp(hp,"Subject:",8) == 0
  				  || strncasecmp(hp,"From:",5) == 0;
  
***************
*** 910,916 ****
--- 924,936 ----
  	if( tmpa == NULL )
  		return -1;
  	if( leng == 0 )
+ 	{
+ 		if( out_thru && rcode != MP_EOR ){
+ 			/* it is put already */
+ 			truncVStr(endline);
+ 		}
  		goto EXIT;
+ 	}
  
  	/* guess the end-of-line character(string) of the message ... */
  	if( beol = strpbrk(tmpa,"\r\n") ){
diff -cr delegate9.2.4-pre19/mimekit/rfc822.c delegate9.2.4-pre20/mimekit/rfc822.c
*** delegate9.2.4-pre19/mimekit/rfc822.c	Thu May  4 03:11:12 2006
--- delegate9.2.4-pre20/mimekit/rfc822.c	Thu Aug 31 08:23:54 2006
***************
*** 19,24 ****
--- 19,25 ----
  	950312	encode/decode parts in a multipart message
  	951029	extracted from mime.c of DeleGate
  //////////////////////////////////////////////////////////////////////#*/
+ #define DOFGSZ
  #include "mime.h"
  char *nextField(PCStr(field),int ignEOH);
  void RFC822_strip_lwsp(PCStr(src),PVStr(dst),int size);
diff -cr delegate9.2.4-pre19/rary/String.c delegate9.2.4-pre20/rary/String.c
*** delegate9.2.4-pre19/rary/String.c	Wed Aug  9 22:52:47 2006
--- delegate9.2.4-pre20/rary/String.c	Thu Aug 31 09:23:58 2006
***************
*** 2280,2282 ****
--- 2280,2329 ----
  		((char*)str)[len0-i] = ch; /**/
  	}
  }
+ 
+ /* represent zero in UTF-8 {0xC0 0x80} without string terminator '\0' */
+ int FGSZ_flags = FGSZ_KILL;
+ const char *fgetsZ(PVStr(str),int siz,FILE *fp){
+ 	int ch;
+ 	refQStr(sp,str);
+ 	const char *sx;
+ 
+ 	sx = &str[siz-2];
+ 	for( sp = str; sp < sx; ){
+ 		ch = getc(fp);
+ 		if( ch == EOF )
+ 			break;
+ 		if( ch == 0 ){
+ 			if( FGSZ_flags & FGSZ_KILL ){
+ 			}else
+ 			if( FGSZ_flags & FGSZ_UTF8 ){
+ 				setVStrPtrInc(sp,0xC0);
+ 				setVStrPtrInc(sp,0x80);
+ 			}else{
+ 				setVStrPtrInc(sp,ch);
+ 			}
+ 		}else{
+ 			setVStrPtrInc(sp,ch);
+ 			if( ch == '\n' )
+ 				break;
+ 		}
+ 	}
+ 	setVStrEnd(sp,0);
+ 	if( sp == str && feof(fp) )
+ 		return NULL;
+ 	return str;
+ }
+ int fputsZ(PCStr(str),FILE *fp){
+ 	const unsigned char *sp;
+ 	unsigned char ch;
+ 
+ 	for( sp = (const unsigned char*)str; ch = *sp; sp++ ){
+ 		if( (FGSZ_flags & FGSZ_UTF8) && ch == 0xC0 && sp[1] == 0x80 ){
+ 			putc(0,fp);
+ 			sp++;
+ 		}else{
+ 			putc(ch,fp);
+ 		}
+ 	}
+ 	return 0;
+ }

  admin search upper oldest olders older1 this newer1 newers latest
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
@_@V