2 * Bacula File Daemon restore.c Restorefiles.
4 * Kern Sibbald, November MM
10 Copyright (C) 2000-2005 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as amended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
31 /* Data received from Storage Daemon */
32 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
34 /* Forward referenced functions */
36 static const char *zlib_strerror(int stat);
39 int verify_signature(JCR *jcr, SIGNATURE *sig);
40 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
41 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size);
42 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size);
44 #define RETRY 10 /* retry wait time */
47 * Close a bfd check that we are at the expected file offset.
48 * Makes some code in set_attributes().
50 int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize)
52 char ec1[50], ec2[50];
55 fsize = blseek(bfd, 0, SEEK_CUR);
56 bclose(bfd); /* first close file */
57 if (fsize > 0 && fsize != osize) {
58 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
59 jcr->last_fname, edit_uint64(osize, ec1),
60 edit_uint64(fsize, ec2));
67 * Restore the requested files.
70 void do_restore(JCR *jcr)
75 uint32_t VolSessionId, VolSessionTime;
78 char ec1[50]; /* Buffer printing huge values */
80 BFILE bfd; /* File content */
81 uint64_t fileAddr = 0; /* file write address */
82 uint32_t size; /* Size of file */
83 BFILE altbfd; /* Alternative data stream */
84 uint64_t alt_addr = 0; /* Write address for alternative stream */
85 intmax_t alt_size = 0; /* Size of alternate stream */
86 SIGNATURE *sig = NULL; /* Cryptographic signature (if any) for file */
87 CRYPTO_SESSION *cs = NULL; /* Cryptographic session data (if any) for file */
88 CIPHER_CONTEXT *cipher_ctx = NULL; /* Cryptographic cipher context (if any) for file */
89 size_t cipher_block_size = 0; /* Cryptographic algorithm block size for file */
90 int flags = 0; /* Options for extract_data() */
94 /* The following variables keep track of "known unknowns" */
95 int non_support_data = 0;
96 int non_support_attr = 0;
97 int non_support_rsrc = 0;
98 int non_support_finfo = 0;
99 int non_support_acl = 0;
100 int non_support_progname = 0;
102 /* Finally, set up for special configurations */
103 #ifdef HAVE_DARWIN_OS
104 intmax_t rsrc_len = 0; /* Original length of resource fork */
105 struct attrlist attrList;
107 memset(&attrList, 0, sizeof(attrList));
108 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
109 attrList.commonattr = ATTR_CMN_FNDRINFO;
112 sd = jcr->store_bsock;
113 set_jcr_job_status(jcr, JS_Running);
116 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
120 buf_size = client->max_network_buffer_size;
122 buf_size = 0; /* use default */
124 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
125 set_jcr_job_status(jcr, JS_ErrorTerminated);
128 jcr->buf_size = sd->msglen;
130 #ifdef stbernard_implemented
131 / #if defined(HAVE_WIN32)
132 bool bResumeOfmOnExit = FALSE;
133 if (isOpenFileManagerRunning()) {
134 if ( pauseOpenFileManager() ) {
135 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
136 bResumeOfmOnExit = TRUE;
139 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
143 char username[UNLEN+1];
144 DWORD usize = sizeof(username);
145 int privs = enable_backup_privileges(NULL, 1);
146 if (GetUserName(username, &usize)) {
147 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
149 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
155 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
156 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
157 jcr->compress_buf_size = compress_buf_size;
161 jcr->crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
165 * Get a record from the Storage daemon. We are guaranteed to
166 * receive records in the following order:
167 * 1. Stream record header
169 * a. Attributes (Unix or Win32)
170 * b. Possibly stream encryption session data (e.g., symmetric session key)
171 * or c. File data for the file
172 * or d. Alternate data stream (e.g. Resource Fork)
175 * or g. Possibly a cryptographic signature
176 * or h. Possibly MD5 or SHA1 record
179 * NOTE: We keep track of two bacula file descriptors:
180 * 1. bfd for file data.
181 * This fd is opened for non empty files when an attribute stream is
182 * encountered and closed when we find the next attribute stream.
183 * 2. alt_bfd for alternate data streams
184 * This fd is opened every time we encounter a new alternate data
185 * stream for the current file. When we find any other stream, we
187 * The expected size of the stream, alt_len, should be set when
193 jcr->acl_text = get_pool_memory(PM_MESSAGE);
195 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
196 /* Remember previous stream type */
197 prev_stream = stream;
199 /* First we expect a Stream Record Header */
200 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
201 &stream, &size) != 5) {
202 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
205 Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
207 /* * Now we expect the Stream Data */
208 if (bget_msg(sd) < 0) {
209 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
212 if (size != (uint32_t)sd->msglen) {
213 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
216 Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
218 /* If we change streams, close and reset alternate data streams */
219 if (prev_stream != stream) {
220 if (is_bopen(&altbfd)) {
221 bclose_chksize(jcr, &altbfd, alt_size);
223 alt_size = -1; /* Use an impossible value and set a proper one below */
227 /* File Attributes stream */
229 case STREAM_UNIX_ATTRIBUTES:
230 case STREAM_UNIX_ATTRIBUTES_EX:
231 Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
233 * If extracting, it was from previous stream, so
234 * close the output file and validate the signature.
237 if (size > 0 && !is_bopen(&bfd)) {
238 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
240 /* Flush and deallocate previous stream's cipher context */
241 if (cipher_ctx && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
242 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
243 crypto_cipher_free(cipher_ctx);
246 set_attributes(jcr, attr, &bfd);
249 /* Verify the cryptographic signature, if any */
252 // Failure is reported in verify_signature() ...
253 verify_signature(jcr, sig);
255 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
260 crypto_sign_free(sig);
264 crypto_session_free(cs);
267 Dmsg0(30, "Stop extracting.\n");
268 } else if (is_bopen(&bfd)) {
269 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
274 * Unpack and do sanity check fo attributes.
276 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
279 if (file_index != attr->file_index) {
280 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
281 file_index, attr->file_index);
282 Dmsg0(100, "File index error\n");
286 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
287 attr->attr, attr->attrEx);
289 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
291 if (!is_restore_stream_supported(attr->data_stream)) {
292 if (!non_support_data++) {
293 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
294 stream_to_ascii(attr->data_stream));
299 build_attr_output_fnames(jcr, attr);
302 * Now determine if we are extracting or not.
304 jcr->num_files_examined++;
305 Dmsg1(30, "Outfile=%s\n", attr->ofname);
307 stat = create_file(jcr, attr, &bfd, jcr->replace);
312 case CF_EXTRACT: /* File created and we expect file data */
315 case CF_CREATED: /* File created, but there is no content */
317 pm_strcpy(jcr->last_fname, attr->ofname);
318 jcr->last_type = attr->type;
322 print_ls_output(jcr, attr);
323 #ifdef HAVE_DARWIN_OS
324 /* Only restore the resource fork for regular files */
325 from_base64(&rsrc_len, attr->attrEx);
326 if (attr->type == FT_REG && rsrc_len > 0) {
331 /* set attributes now because file will not be extracted */
332 set_attributes(jcr, attr, &bfd);
339 case STREAM_ENCRYPTED_SESSION_DATA:
340 crypto_error_t cryptoerr;
342 Dmsg1(30, "Stream=Encrypted Session Data, size: %d\n", sd->msglen);
344 /* Decode and save session keys. */
345 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (size_t)sd->msglen, jcr->pki_recipients, &cs);
347 case CRYPTO_ERROR_NONE:
350 case CRYPTO_ERROR_NORECIPIENT:
351 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
353 case CRYPTO_ERROR_DECRYPTION:
354 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
357 /* Shouldn't happen */
358 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
362 if (cryptoerr != CRYPTO_ERROR_NONE) {
368 /* Set up a decryption context */
369 if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
370 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
371 crypto_session_free(cs);
379 case STREAM_FILE_DATA:
380 case STREAM_SPARSE_DATA:
381 case STREAM_WIN32_DATA:
382 case STREAM_GZIP_DATA:
383 case STREAM_SPARSE_GZIP_DATA:
384 case STREAM_WIN32_GZIP_DATA:
385 case STREAM_ENCRYPTED_FILE_DATA:
386 case STREAM_ENCRYPTED_WIN32_DATA:
387 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
388 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
389 /* Force an expected, consistent stream type here */
390 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
391 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
392 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
395 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
399 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
400 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
401 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
405 if (stream == STREAM_ENCRYPTED_FILE_DATA
406 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
407 || stream == STREAM_ENCRYPTED_WIN32_DATA
408 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
412 if (is_win32_stream(stream) && !have_win32_api()) {
413 set_portable_backup(&bfd);
414 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
417 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
425 /* Resource fork stream - only recorded after a file to be restored */
426 /* Silently ignore if we cannot write - we already reported that */
427 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
429 case STREAM_MACOS_FORK_DATA:
430 #ifdef HAVE_DARWIN_OS
432 if (prev_stream != stream) {
433 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
434 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
439 Dmsg0(30, "Restoring resource fork\n");
442 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
453 case STREAM_HFSPLUS_ATTRIBUTES:
454 #ifdef HAVE_DARWIN_OS
455 Dmsg0(30, "Restoring Finder Info\n");
456 if (sd->msglen != 32) {
457 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
460 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
461 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
468 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
470 pm_strcpy(jcr->acl_text, sd->msg);
471 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
472 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
473 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
480 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
482 pm_strcpy(jcr->acl_text, sd->msg);
483 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
484 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
485 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
492 case STREAM_SIGNED_DIGEST:
493 /* Save signature. */
494 if ((sig = crypto_sign_decode((uint8_t *)sd->msg, (size_t)sd->msglen)) == NULL) {
495 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
499 case STREAM_MD5_DIGEST:
500 case STREAM_SHA1_DIGEST:
501 case STREAM_SHA256_DIGEST:
502 case STREAM_SHA512_DIGEST:
505 case STREAM_PROGRAM_NAMES:
506 case STREAM_PROGRAM_DATA:
507 if (!non_support_progname) {
508 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
509 non_support_progname++;
514 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
516 Dmsg1(30, "Found wierd stream %d\n", stream);
517 if (size > 0 && !is_bopen(&bfd)) {
518 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
520 /* Flush and deallocate cipher context */
522 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
523 crypto_cipher_free(cipher_ctx);
526 set_attributes(jcr, attr, &bfd);
528 /* Verify the cryptographic signature if any */
531 // Failure is reported in verify_signature() ...
532 verify_signature(jcr, sig);
534 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
539 } else if (is_bopen(&bfd)) {
540 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
543 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
544 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
546 } /* end switch(stream) */
548 } /* end while get_msg() */
550 /* If output file is still open, it was the last one in the
551 * archive since we just hit an end of file, so close the file.
553 if (is_bopen(&altbfd)) {
554 bclose_chksize(jcr, &altbfd, alt_size);
557 /* Flush and deallocate cipher context */
559 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
560 crypto_cipher_free(cipher_ctx);
563 set_attributes(jcr, attr, &bfd);
565 /* Verify the cryptographic signature on the last file, if any */
568 // Failure is reported in verify_signature() ...
569 verify_signature(jcr, sig);
571 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
576 if (is_bopen(&bfd)) {
580 set_jcr_job_status(jcr, JS_Terminated);
584 set_jcr_job_status(jcr, JS_ErrorTerminated);
587 /* Free Signature & Crypto Data */
589 crypto_sign_free(sig);
593 crypto_session_free(cs);
597 crypto_cipher_free(cipher_ctx);
600 if (jcr->compress_buf) {
601 free(jcr->compress_buf);
602 jcr->compress_buf = NULL;
603 jcr->compress_buf_size = 0;
605 if (jcr->crypto_buf) {
606 free_pool_memory(jcr->crypto_buf);
607 jcr->crypto_buf = NULL;
612 free_pool_memory(jcr->acl_text);
613 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
614 edit_uint64(jcr->JobBytes, ec1));
615 if (non_support_data > 1 || non_support_attr > 1) {
616 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
617 non_support_data, non_support_attr);
619 if (non_support_rsrc) {
620 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
622 if (non_support_finfo) {
623 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
625 if (non_support_acl) {
626 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
633 * Convert ZLIB error code into an ASCII message
635 static const char *zlib_strerror(int stat)
642 return _("Zlib errno");
644 return _("Zlib stream error");
646 return _("Zlib data error");
648 return _("Zlib memory error");
650 return _("Zlib buffer error");
651 case Z_VERSION_ERROR:
652 return _("Zlib version error");
659 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) {
660 JCR *jcr = (JCR *) pkt;
661 return (digest_file(jcr, ff_pkt, jcr->digest));
665 * Verify the signature for the last restored file
666 * Return value is either true (signature correct)
667 * or false (signature could not be verified).
668 * TODO landonf: Better signature failure handling.
670 int verify_signature(JCR *jcr, SIGNATURE *sig)
672 X509_KEYPAIR *keypair;
673 DIGEST *digest = NULL;
676 /* Iterate through the trusted signers */
677 foreach_alist(keypair, jcr->pki_signers) {
678 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
681 case CRYPTO_ERROR_NONE:
682 /* Signature found, digest allocated */
683 jcr->digest = digest;
685 /* Checksum the entire file */
686 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
687 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
691 /* Verify the signature */
692 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
693 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
694 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
695 crypto_digest_free(digest);
699 /* Valid signature */
700 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
701 crypto_digest_free(digest);
704 case CRYPTO_ERROR_NOSIGNER:
705 /* Signature not found, try again */
708 /* Something strange happened (that shouldn't happen!)... */
709 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
711 crypto_digest_free(digest);
718 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
719 crypto_digest_free(digest);
724 * In the context of jcr, write data to bfd.
725 * We write buflen bytes in buf at addr. addr is updated in place.
726 * The flags specify whether to use sparse files or compression.
727 * Return value is the number of bytes written, or -1 on errors.
729 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
730 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
733 char *wbuf; /* write buffer */
734 uint32_t wsize; /* write size */
735 uint32_t rsize; /* read size */
736 char ec1[50]; /* Buffer printing huge values */
737 const void *cipher_input; /* Decryption input */
738 size_t cipher_input_len; /* Decryption input length */
739 size_t decrypted_len = 0; /* Decryption output length */
741 if (flags & FO_SPARSE) {
745 wbuf = buf + SPARSE_FADDR_SIZE;
746 rsize = buflen - SPARSE_FADDR_SIZE;
747 ser_begin(buf, SPARSE_FADDR_SIZE);
749 if (*addr != faddr) {
751 if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
753 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
754 edit_uint64(*addr, ec1), jcr->last_fname,
755 be.strerror(bfd->berrno));
765 cipher_input_len = wsize;
767 if (flags & FO_GZIP) {
771 * NOTE! We only use uLong and Byte because they are
772 * needed by the zlib routines, they should not otherwise
775 compress_len = jcr->compress_buf_size;
776 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
777 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
778 (const Byte *)wbuf, (uLong)rsize)) != Z_OK) {
779 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
780 jcr->last_fname, zlib_strerror(stat));
783 wbuf = jcr->compress_buf;
784 wsize = compress_len;
785 cipher_input = jcr->compress_buf; /* decrypt decompressed data */
786 cipher_input_len = compress_len;
787 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
789 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
793 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
796 if (flags & FO_ENCRYPT) {
800 * Grow the crypto buffer, if necessary.
801 * crypto_cipher_update() will process only whole blocks,
802 * buffering the remaining input.
804 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_input_len + cipher_block_size);
807 /* Encrypt the input block */
808 if (!crypto_cipher_update(cipher, cipher_input, cipher_input_len, jcr->crypto_buf, &decrypted_len)) {
809 /* Decryption failed. Shouldn't happen. */
810 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
814 if (decrypted_len == 0) {
815 /* No full block of data available, write more data */
819 Dmsg2(400, "decrypted len=%d undecrypted len=%d\n",
820 decrypted_len, cipher_input_len);
821 wsize = decrypted_len;
822 wbuf = jcr->crypto_buf; /* Decrypted, possibly decompressed output here. */
826 if (flags & FO_WIN32DECOMP) {
827 if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
829 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
830 jcr->last_fname, be.strerror(bfd->berrno));
833 } else if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
835 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
836 jcr->last_fname, be.strerror(bfd->berrno));
840 if (decrypted_len && decrypted_len > wsize) {
841 /* If more than wsize is output, it was previously buffered
842 * and reported, and should not be reported again */
843 wsize = wsize - decrypted_len;
847 jcr->JobBytes += wsize;
848 jcr->ReadBytes += rsize;
855 * In the context of jcr, flush any remaining data from the cipher context,
857 * Return value is true on success, false on failure.
859 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
861 size_t decrypted_len;
863 /* Write out the remaining block and free the cipher context */
864 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_block_size);
866 if (!crypto_cipher_finalize(cipher, jcr->crypto_buf, &decrypted_len)) {
867 /* Writing out the final, buffered block failed. Shouldn't happen. */
868 Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
871 if (flags & FO_WIN32DECOMP) {
872 if (!processWin32BackupAPIBlock(bfd, jcr->crypto_buf, decrypted_len)) {
874 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
875 jcr->last_fname, be.strerror(bfd->berrno));
878 } else if (bwrite(bfd, jcr->crypto_buf, decrypted_len) != (ssize_t)decrypted_len) {
880 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
881 jcr->last_fname, be.strerror(bfd->berrno));