Subject: Re: rfc2228 in ftpd
To: Tomas Svensson <ts@unix1.net>
From: Aidan Cully <aidan@kublai.com>
List: tech-security
Date: 06/24/2002 07:20:59
On Mon, Jun 24, 2002 at 10:22:11AM +0200, Tomas Svensson wrote:
> Sunday, June 23, 2002, 5:59:52 PM, you wrote:
> 
> AC> fflush is unnecessary with the sec_file structure...  We're using
> AC> read()s and write()s directly, so we have control over the buffering
> AC> strategy.  ferror may be a problem...  It needs investigation.
> 
> How is this buffering strategy, send everything when you get a
> newline? Then implementing a sec_fflush would be better.

I check if we're sending commands or data, and use the appropriate
buffering strategy.  You'll notice in the sec_fwrite routine in
secure-common.c:
	if ((f->mode & SEC_OPEN_CMD) != 0) {
	    if (sec_send_cmd(f) < 0)
		return -1;
	} else {
	    if (f->buffer.used == f->buffer.size && sec_send_data(f) < 0)
		return -1;
	}
sec_send_cmd looks for the newline, and calls f->io.io against a
line at a time.  f->io.io, in this case, points to sec_server_io(),
which knows about the 631, 632, and 633 reply codes.

> Also, is there any buffering at all when not using encryption? From
> sec_fwrite:
> 
>     if(f->io.prot == PROT_CLEAR)
>         return (*f->io.io)(&f->io, data, length); 

Yes, on data...  It looks like I may have overlooked command buffers
when I wrote that, but the simple fix is to change
if (f->io.prot == PROT_CLEAR)
to
if ((f->mode & SEC_OPEN_CMD) == 0 && f->io.prot == PROT_CLEAR)
.  For data, f->io.io points to a routine named 'datawrite' in
ftpd.c, which handles buffering and ratelimiting I/O.  Using this
structure is how I was able to get rid of those
/* XXXLUKEM: rate limit ascii send */ comments...  Everything
eventually gets to datawrite() (or dataread()) which handles
ratelimiting.

--aidan