[Dovecot] Plugin like zlib
Hi everyone.
I rebuild a plugin, based on zlib plugin. The changes between this plugin and zlib, is the zlib stuffs is replaced by open, read, lseek, close. With "plain-text" files, its works ok. So, my file is encrypt, and the result from decrypt file is different from fread. Like zlib, i read from fread the size variable, but the value added in seek_offset and pos is the result from decrypt, and it can be dfferent from fread. Like zlib, my file size is different from email. In zlib the file is smaller than the email. In my file, the file is bigger than the email.
OK, lets go to the problem now.
when the email arrives in the new folder, by imap, the stat (read my file by "while (i_stream_emexis_read(stream) > 0)" like zlib) and the seek works fine....the email is readed and the final stat size is the decrypted size of my email (smaller than original file).
When I receive the email, clicking in "Send/Receive", The read function is aborted because the size to read (like zlib) is negative. I put some debug in my plugin, and print some stuffs about the functions.
Email decryt size = 49556 Email encrypt size = 49568
Attachements: mail-arrived, is when the email arrives, and it's ok the read. mail-receive, is when the email is received, and have the error. maillog is the /var/log/mail
The bigger difference from zlib is the i_stream_zlib_read part....
do {
ret = read(zstream->fd ,crypttext, size);
fprintf(zstream->debug,"DENTRO DA READ RET = %d -- ERRNO = %d -- STR
= |%s|\n", ret, errno, strerror(errno)); if(ret > 0){ EVP_DecryptUpdate(&ctx, plaintext, &plain_len, crypttext, ret); memcpy(stream->w_buffer + stream->pos , plaintext, plain_len);
bzero (plaintext, DEFAULT_MAX_BUFFER_SIZE);
EVP_DecryptFinal(&ctx, plaintext, &plain_len_final);
memcpy(stream->w_buffer + stream->pos + plain_len , plaintext,
plain_len_final); } } while (ret < 0 && errno == EINTR && stream->istream.blocking);
*retc *= plain_len + plain_len_final;
if (ret == 0 ) {
/* EOF */
stream->istream.eof = TRUE;
return -1;
}
if (ret < 0) {
if (errno == EAGAIN) {
i_assert(!stream->istream.blocking);
ret = 0;
// } else { // i_assert(errno != 0); // stream->istream.stream_errno = errno; // return -1; } }
fprintf(zstream->debug,"READ RET = %d -- ERRNO = %d -- STR = |%s|\n",
ret, errno, strerror(errno)); fprintf(zstream->debug,"stream->pos = %d -- zstream->seek_offset = %d\n", stream->pos, zstream->seek_offset);
zstream->seek_offset += *retc*;
stream->pos += *retc*;
i_assert(ret > 0);
fprintf(zstream->debug,"READ RET DECRYPT = %d -- stream->pos = %d --
zstream->seek_offset = %d\n", ret, stream->pos, zstream->seek_offset); fprintf(zstream->debug,"********************** FINISH READ *********************\n"); fflush(zstream->debug);
return *retc;*
The* retc* is the result from decrypt.
In mail-receive file (line 38), there is the error, at some point along the read/send email, the stream->pos (its returned by i_stream_compress, with stream->pos -= stream->skip) is changed out from context and the size to read is negative, but i don't understand why.
Someone can help me find out what happens ?
On Thu, 2010-03-11 at 19:33 -0300, Alex Baule wrote:
do { ret = read(zstream->fd ,crypttext, size); fprintf(zstream->debug,"DENTRO DA READ RET = %d -- ERRNO = %d -- STR
= |%s|\n", ret, errno, strerror(errno)); if(ret > 0){ EVP_DecryptUpdate(&ctx, plaintext, &plain_len, crypttext, ret); memcpy(stream->w_buffer + stream->pos , plaintext, plain_len);
bzero (plaintext, DEFAULT_MAX_BUFFER_SIZE); EVP_DecryptFinal(&ctx, plaintext, &plain_len_final); memcpy(stream->w_buffer + stream->pos + plain_len , plaintext,
plain_len_final);
I think you should do some kind of internal buffering here that contains the unused part of crypttext, and reuse it for next DecryptUpdate(). v1.x's zlib plugin lets zlib library take care of that, so it makes the code a lot simpler.
Maybe you should look at hg version of v2.0 and its istream-bzlib.c. That's probably a lot closer to what you need to do. (But note that there are some other istream changes in v2.0, so you can't just use the same code with v1.x without some more changes.)
And I don't think you should call EVP_DecryptFinal() until you've seen EOF from the parent fd?
participants (2)
-
Alex Baule
-
Timo Sirainen