]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Fix encryption deblocking bug, which caused some restored files
authorKern Sibbald <kern@sibbald.com>
Fri, 16 Feb 2007 15:20:56 +0000 (15:20 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 16 Feb 2007 15:20:56 +0000 (15:20 +0000)
     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
bacula/src/filed/restore.c
bacula/technotes-2.0

index f33afb4b72a4187dd41db17f47e8c98ebbfb2ab6..1f970301f9df1f8686a661085395497cfcbf2361 100644 (file)
@@ -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);
       }
index 81c991e01247484ddcb128a34620f47a59fd6352..f9ddc5fa7e7ddf69019bf7939d298804ce224ab9 100644 (file)
@@ -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;
 }
index 135375ab0e31b9e2b454bddefc2deffa96fe3170..c9a9d2964c439088990c411ccba8c63389f6c746 100644 (file)
@@ -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