From 82f0dfcc877bc15ff101fe82aed8f9146d811997 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 16 Feb 2007 15:20:56 +0000 Subject: [PATCH] kes Fix encryption deblocking bug, which caused some restored files to be truncated. This fixes bug #763. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.0@4188 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/filed/backup.c | 2 ++ bacula/src/filed/restore.c | 45 ++++++++++++++++++++++++++++---------- bacula/technotes-2.0 | 2 ++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index f33afb4b72..1f970301f9 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -434,6 +434,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) /* Set up the encryption context, send the session data to the SD */ if (jcr->pki_encrypt) { /* Send our header */ + Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA); bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA); /* Grow the bsock buffer to fit our message if necessary */ @@ -446,6 +447,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) sd->msglen = jcr->pki_session_encoded_size; jcr->JobBytes += sd->msglen; + Dmsg1(100, "Send data len=%d\n", sd->msglen); bnet_send(sd); bnet_sig(sd, BNET_EOD); } diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 81c991e012..f9ddc5fa7e 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -1006,16 +1006,14 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, if (!decompress_data(jcr, &wbuf, &wsize)) { return -1; } - } else { - Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); } if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) { return -1; } - jcr->JobBytes += wsize; *addr += wsize; + Dmsg2(30, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); /* Clean up crypto buffers */ if (flags & FO_ENCRYPT) { @@ -1045,7 +1043,9 @@ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ char ec1[50]; /* Buffer printing huge values */ + bool second_pass = false; +again: /* Write out the remaining block and free the cipher context */ cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len + cipher_ctx->block_size); @@ -1056,6 +1056,7 @@ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname); } + Dmsg2(30, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len); /* If nothing new was decrypted, and our output buffer is empty, return */ if (decrypted_len == 0 && cipher_ctx->buf_len == 0) { return true; @@ -1067,16 +1068,18 @@ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE); wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE; wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */ + cipher_ctx->buf_len -= cipher_ctx->packet_len; + Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len); - if (cipher_ctx->buf_len != cipher_ctx->packet_len) { +#ifdef xxx + Dmsg2(30, "check buf_len=%d pkt_len=%d\n", cipher_ctx->buf_len, cipher_ctx->packet_len); + if (second_pass && cipher_ctx->buf_len != cipher_ctx->packet_len) { Jmsg2(jcr, M_FATAL, 0, _("Unexpected number of bytes remaining at end of file, received %u, expected %u\n"), cipher_ctx->packet_len, cipher_ctx->buf_len); return false; } - - cipher_ctx->buf_len = 0; - cipher_ctx->packet_len = 0; +#endif if (flags & FO_SPARSE) { if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) { @@ -1085,16 +1088,36 @@ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, } if (flags & FO_GZIP) { - decompress_data(jcr, &wbuf, &wsize); - } else { - Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); + if (!decompress_data(jcr, &wbuf, &wsize)) { + return false; + } } + Dmsg0(30, "Call store_data\n"); if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) { return false; } - jcr->JobBytes += wsize; + Dmsg2(30, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); + + /* Move any remaining data to start of buffer */ + if (cipher_ctx->buf_len > 0) { + Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len); + memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], + cipher_ctx->buf_len); + } + /* The packet was successfully written, reset the length so that the next + * packet length may be re-read by unser_crypto_packet_len() */ + cipher_ctx->packet_len = 0; + + if (cipher_ctx->buf_len >0 && !second_pass) { + second_pass = true; + goto again; + } + + /* Stop decryption */ + cipher_ctx->buf_len = 0; + cipher_ctx->packet_len = 0; return true; } diff --git a/bacula/technotes-2.0 b/bacula/technotes-2.0 index 135375ab0e..c9a9d2964c 100644 --- a/bacula/technotes-2.0 +++ b/bacula/technotes-2.0 @@ -2,6 +2,8 @@ General: 16Feb07 +kes Fix encryption deblocking bug, which caused some restored files + to be truncated. This fixes bug #763. kes Add FD event sequence order prepared by Eric -- for RunScripts. kes Fix 12am/pm bug as reported in bug #782. 15Feb07 -- 2.39.5