2 * Bacula File Daemon restore.c Restorefiles.
4 * Kern Sibbald, November MM
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
44 #if defined(HAVE_CRYPTO)
45 const bool have_crypto = true;
47 const bool have_crypto = false;
50 /* Data received from Storage Daemon */
51 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
53 /* Forward referenced functions */
54 #if defined(HAVE_LIBZ)
55 static const char *zlib_strerror(int stat);
56 const bool have_libz = true;
58 const bool have_libz = false;
61 int verify_signature(JCR *jcr, SIGNATURE *sig);
62 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
63 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size);
64 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size);
66 #define RETRY 10 /* retry wait time */
69 * Close a bfd check that we are at the expected file offset.
70 * Makes some code in set_attributes().
72 int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
74 char ec1[50], ec2[50];
77 fsize = blseek(bfd, 0, SEEK_CUR);
78 bclose(bfd); /* first close file */
79 if (fsize > 0 && fsize != osize) {
80 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
81 jcr->last_fname, edit_uint64(osize, ec1),
82 edit_uint64(fsize, ec2));
89 * Restore the requested files.
92 void do_restore(JCR *jcr)
97 uint32_t VolSessionId, VolSessionTime;
100 char ec1[50]; /* Buffer printing huge values */
102 BFILE bfd; /* File content */
103 uint64_t fileAddr = 0; /* file write address */
104 uint32_t size; /* Size of file */
105 BFILE altbfd; /* Alternative data stream */
106 uint64_t alt_addr = 0; /* Write address for alternative stream */
107 intmax_t alt_size = 0; /* Size of alternate stream */
108 SIGNATURE *sig = NULL; /* Cryptographic signature (if any) for file */
109 CRYPTO_SESSION *cs = NULL; /* Cryptographic session data (if any) for file */
110 CIPHER_CONTEXT *cipher_ctx = NULL; /* Cryptographic cipher context (if any) for file */
111 uint32_t cipher_block_size = 0; /* Cryptographic algorithm block size for file */
112 int flags = 0; /* Options for extract_data() */
116 /* The following variables keep track of "known unknowns" */
117 int non_support_data = 0;
118 int non_support_attr = 0;
119 int non_support_rsrc = 0;
120 int non_support_finfo = 0;
121 int non_support_acl = 0;
122 int non_support_progname = 0;
124 /* Finally, set up for special configurations */
125 #ifdef HAVE_DARWIN_OS
126 intmax_t rsrc_len = 0; /* Original length of resource fork */
127 struct attrlist attrList;
129 memset(&attrList, 0, sizeof(attrList));
130 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
131 attrList.commonattr = ATTR_CMN_FNDRINFO;
134 sd = jcr->store_bsock;
135 set_jcr_job_status(jcr, JS_Running);
138 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
142 buf_size = client->max_network_buffer_size;
144 buf_size = 0; /* use default */
146 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
147 set_jcr_job_status(jcr, JS_ErrorTerminated);
150 jcr->buf_size = sd->msglen;
152 #ifdef stbernard_implemented
153 / #if defined(HAVE_WIN32)
154 bool bResumeOfmOnExit = FALSE;
155 if (isOpenFileManagerRunning()) {
156 if ( pauseOpenFileManager() ) {
157 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
158 bResumeOfmOnExit = TRUE;
161 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
165 char username[UNLEN+1];
166 DWORD usize = sizeof(username);
167 int privs = enable_backup_privileges(NULL, 1);
168 if (GetUserName(username, &usize)) {
169 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
171 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
177 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
178 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
179 jcr->compress_buf_size = compress_buf_size;
183 jcr->crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
187 * Get a record from the Storage daemon. We are guaranteed to
188 * receive records in the following order:
189 * 1. Stream record header
191 * a. Attributes (Unix or Win32)
192 * b. Possibly stream encryption session data (e.g., symmetric session key)
193 * or c. File data for the file
194 * or d. Alternate data stream (e.g. Resource Fork)
197 * or g. Possibly a cryptographic signature
198 * or h. Possibly MD5 or SHA1 record
201 * NOTE: We keep track of two bacula file descriptors:
202 * 1. bfd for file data.
203 * This fd is opened for non empty files when an attribute stream is
204 * encountered and closed when we find the next attribute stream.
205 * 2. alt_bfd for alternate data streams
206 * This fd is opened every time we encounter a new alternate data
207 * stream for the current file. When we find any other stream, we
209 * The expected size of the stream, alt_len, should be set when
215 jcr->acl_text = get_pool_memory(PM_MESSAGE);
217 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
218 /* Remember previous stream type */
219 prev_stream = stream;
221 /* First we expect a Stream Record Header */
222 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
223 &stream, &size) != 5) {
224 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
227 Dmsg4(30, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n",
228 jcr->JobFiles, file_index, stream, stream_to_ascii(stream));
230 /* * Now we expect the Stream Data */
231 if (bget_msg(sd) < 0) {
232 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
235 if (size != (uint32_t)sd->msglen) {
236 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
239 Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(stream),
240 sd->msglen, extract);
242 /* If we change streams, close and reset alternate data streams */
243 if (prev_stream != stream) {
244 if (is_bopen(&altbfd)) {
245 bclose_chksize(jcr, &altbfd, alt_size);
247 alt_size = -1; /* Use an impossible value and set a proper one below */
251 /* File Attributes stream */
253 case STREAM_UNIX_ATTRIBUTES:
254 case STREAM_UNIX_ATTRIBUTES_EX:
256 * If extracting, it was from previous stream, so
257 * close the output file and validate the signature.
260 if (size > 0 && !is_bopen(&bfd)) {
261 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
263 /* Flush and deallocate previous stream's cipher context */
264 if (cipher_ctx && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
265 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
266 crypto_cipher_free(cipher_ctx);
269 set_attributes(jcr, attr, &bfd);
272 /* Verify the cryptographic signature, if any */
275 // Failure is reported in verify_signature() ...
276 verify_signature(jcr, sig);
278 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
283 crypto_sign_free(sig);
287 crypto_session_free(cs);
290 Dmsg0(30, "Stop extracting.\n");
291 } else if (is_bopen(&bfd)) {
292 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
297 * Unpack and do sanity check fo attributes.
299 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
302 if (file_index != attr->file_index) {
303 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
304 file_index, attr->file_index);
305 Dmsg0(100, "File index error\n");
309 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
310 attr->attr, attr->attrEx);
312 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
314 if (!is_restore_stream_supported(attr->data_stream)) {
315 if (!non_support_data++) {
316 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
317 stream_to_ascii(attr->data_stream));
322 build_attr_output_fnames(jcr, attr);
325 * Now determine if we are extracting or not.
327 jcr->num_files_examined++;
328 Dmsg1(30, "Outfile=%s\n", attr->ofname);
330 stat = create_file(jcr, attr, &bfd, jcr->replace);
335 case CF_EXTRACT: /* File created and we expect file data */
338 case CF_CREATED: /* File created, but there is no content */
340 pm_strcpy(jcr->last_fname, attr->ofname);
341 jcr->last_type = attr->type;
345 print_ls_output(jcr, attr);
346 #ifdef HAVE_DARWIN_OS
347 /* Only restore the resource fork for regular files */
348 from_base64(&rsrc_len, attr->attrEx);
349 if (attr->type == FT_REG && rsrc_len > 0) {
354 /* set attributes now because file will not be extracted */
355 set_attributes(jcr, attr, &bfd);
362 case STREAM_ENCRYPTED_SESSION_DATA:
363 crypto_error_t cryptoerr;
365 /* Do we have any keys at all? */
366 if (!jcr->pki_recipients) {
367 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data."));
371 /* Decode and save session keys. */
372 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
374 case CRYPTO_ERROR_NONE:
377 case CRYPTO_ERROR_NORECIPIENT:
378 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
380 case CRYPTO_ERROR_DECRYPTION:
381 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
384 /* Shouldn't happen */
385 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
389 if (cryptoerr != CRYPTO_ERROR_NONE) {
395 /* Set up a decryption context */
396 if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
397 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
398 crypto_session_free(cs);
405 jcr->crypto_count = 0;
406 jcr->crypto_size = 0;
409 case STREAM_FILE_DATA:
410 case STREAM_SPARSE_DATA:
411 case STREAM_WIN32_DATA:
412 case STREAM_GZIP_DATA:
413 case STREAM_SPARSE_GZIP_DATA:
414 case STREAM_WIN32_GZIP_DATA:
415 case STREAM_ENCRYPTED_FILE_DATA:
416 case STREAM_ENCRYPTED_WIN32_DATA:
417 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
418 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
419 /* Force an expected, consistent stream type here */
420 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
421 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
422 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
425 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
429 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
430 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
431 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
435 if (stream == STREAM_ENCRYPTED_FILE_DATA
436 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
437 || stream == STREAM_ENCRYPTED_WIN32_DATA
438 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
442 if (is_win32_stream(stream) && !have_win32_api()) {
443 set_portable_backup(&bfd);
444 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
447 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
455 /* Resource fork stream - only recorded after a file to be restored */
456 /* Silently ignore if we cannot write - we already reported that */
457 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
459 case STREAM_MACOS_FORK_DATA:
460 #ifdef HAVE_DARWIN_OS
462 if (prev_stream != stream) {
463 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
464 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
469 Dmsg0(30, "Restoring resource fork\n");
472 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
483 case STREAM_HFSPLUS_ATTRIBUTES:
484 #ifdef HAVE_DARWIN_OS
485 Dmsg0(30, "Restoring Finder Info\n");
486 if (sd->msglen != 32) {
487 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
490 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
491 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
498 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
500 pm_strcpy(jcr->acl_text, sd->msg);
501 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
502 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
503 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
510 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
512 pm_strcpy(jcr->acl_text, sd->msg);
513 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
514 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
515 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
522 case STREAM_SIGNED_DIGEST:
523 /* Save signature. */
524 if ((sig = crypto_sign_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
525 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
529 case STREAM_MD5_DIGEST:
530 case STREAM_SHA1_DIGEST:
531 case STREAM_SHA256_DIGEST:
532 case STREAM_SHA512_DIGEST:
535 case STREAM_PROGRAM_NAMES:
536 case STREAM_PROGRAM_DATA:
537 if (!non_support_progname) {
538 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
539 non_support_progname++;
544 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
546 Dmsg1(30, "Found wierd stream %d\n", stream);
547 if (size > 0 && !is_bopen(&bfd)) {
548 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
550 /* Flush and deallocate cipher context */
552 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
553 crypto_cipher_free(cipher_ctx);
556 set_attributes(jcr, attr, &bfd);
558 /* Verify the cryptographic signature if any */
561 // Failure is reported in verify_signature() ...
562 verify_signature(jcr, sig);
564 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
569 } else if (is_bopen(&bfd)) {
570 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
573 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
574 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
576 } /* end switch(stream) */
578 } /* end while get_msg() */
580 /* If output file is still open, it was the last one in the
581 * archive since we just hit an end of file, so close the file.
583 if (is_bopen(&altbfd)) {
584 bclose_chksize(jcr, &altbfd, alt_size);
587 /* Flush and deallocate cipher context */
589 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
590 crypto_cipher_free(cipher_ctx);
593 set_attributes(jcr, attr, &bfd);
595 /* Verify the cryptographic signature on the last file, if any */
598 // Failure is reported in verify_signature() ...
599 verify_signature(jcr, sig);
601 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
606 if (is_bopen(&bfd)) {
610 set_jcr_job_status(jcr, JS_Terminated);
614 set_jcr_job_status(jcr, JS_ErrorTerminated);
617 /* Free Signature & Crypto Data */
619 crypto_sign_free(sig);
623 crypto_session_free(cs);
627 crypto_cipher_free(cipher_ctx);
630 if (jcr->compress_buf) {
631 free(jcr->compress_buf);
632 jcr->compress_buf = NULL;
633 jcr->compress_buf_size = 0;
635 if (jcr->crypto_buf) {
636 free_pool_memory(jcr->crypto_buf);
637 jcr->crypto_buf = NULL;
642 free_pool_memory(jcr->acl_text);
643 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
644 edit_uint64(jcr->JobBytes, ec1));
645 if (non_support_data > 1 || non_support_attr > 1) {
646 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
647 non_support_data, non_support_attr);
649 if (non_support_rsrc) {
650 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
652 if (non_support_finfo) {
653 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
655 if (non_support_acl) {
656 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
662 * Convert ZLIB error code into an ASCII message
664 static const char *zlib_strerror(int stat)
671 return _("Zlib errno");
673 return _("Zlib stream error");
675 return _("Zlib data error");
677 return _("Zlib memory error");
679 return _("Zlib buffer error");
680 case Z_VERSION_ERROR:
681 return _("Zlib version error");
687 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level)
689 JCR *jcr = (JCR *)pkt;
690 return (digest_file(jcr, ff_pkt, jcr->digest));
694 * Verify the signature for the last restored file
695 * Return value is either true (signature correct)
696 * or false (signature could not be verified).
697 * TODO landonf: Better signature failure handling.
699 int verify_signature(JCR *jcr, SIGNATURE *sig)
701 X509_KEYPAIR *keypair;
702 DIGEST *digest = NULL;
705 /* Iterate through the trusted signers */
706 foreach_alist(keypair, jcr->pki_signers) {
707 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
710 case CRYPTO_ERROR_NONE:
711 /* Signature found, digest allocated */
712 jcr->digest = digest;
714 /* Checksum the entire file */
715 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
716 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
720 /* Verify the signature */
721 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
722 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
723 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
724 crypto_digest_free(digest);
728 /* Valid signature */
729 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
730 crypto_digest_free(digest);
733 case CRYPTO_ERROR_NOSIGNER:
734 /* Signature not found, try again */
737 /* Something strange happened (that shouldn't happen!)... */
738 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
740 crypto_digest_free(digest);
747 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
748 crypto_digest_free(digest);
752 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
757 char ec1[50]; /* Buffer printing huge values */
760 * NOTE! We only use uLong and Byte because they are
761 * needed by the zlib routines, they should not otherwise
764 compress_len = jcr->compress_buf_size;
765 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
766 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
767 (const Byte *)*data, (uLong)*length)) != Z_OK) {
768 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
769 jcr->last_fname, zlib_strerror(stat));
772 *data = jcr->compress_buf;
773 *length = compress_len;
774 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
777 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
782 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
785 if (!processWin32BackupAPIBlock(bfd, data, length)) {
787 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
788 jcr->last_fname, be.strerror(bfd->berrno));
791 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
793 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
794 jcr->last_fname, be.strerror(bfd->berrno));
802 * In the context of jcr, write data to bfd.
803 * We write buflen bytes in buf at addr. addr is updated in place.
804 * The flags specify whether to use sparse files or compression.
805 * Return value is the number of bytes written, or -1 on errors.
807 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
808 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
810 char *wbuf; /* write buffer */
811 uint32_t wsize; /* write size */
812 uint32_t rsize; /* read size */
813 uint32_t decrypted_len = 0; /* Decryption output length */
814 char ec1[50]; /* Buffer printing huge values */
817 jcr->ReadBytes += rsize;
821 if (flags & FO_ENCRYPT) {
825 while (jcr->crypto_size > 0 && jcr->crypto_count > 0 && wsize > 0) {
826 uint32_t chunk_size = 16;
828 if (chunk_size > wsize) {
833 * Grow the crypto buffer, if necessary.
834 * crypto_cipher_update() will process only whole blocks,
835 * buffering the remaining input.
837 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + chunk_size + cipher_block_size);
839 /* Decrypt the input block */
840 if (!crypto_cipher_update(cipher,
841 (const u_int8_t *)wbuf,
843 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
845 /* Decryption failed. Shouldn't happen. */
846 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
850 jcr->crypto_count += decrypted_len;
854 if (jcr->crypto_count >= jcr->crypto_size) {
856 char *packet = &jcr->crypto_buf[4]; /* Decrypted, possibly decompressed output here. */
857 uint32_t packet_size = jcr->crypto_size - 4;
859 if (flags & FO_GZIP) {
860 if (!decompress_data(jcr, &packet, &packet_size)) {
864 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
867 if (!store_data(jcr, bfd, packet, packet_size, (flags & FO_WIN32DECOMP) != 0)) {
871 jcr->JobBytes += packet_size;
872 *addr += packet_size;
874 memmove(&jcr->crypto_buf[0], &jcr->crypto_buf[jcr->crypto_size], jcr->crypto_count - jcr->crypto_size);
875 jcr->crypto_count -= jcr->crypto_size;
876 jcr->crypto_size = 0;
881 * Grow the crypto buffer, if necessary.
882 * crypto_cipher_update() will process only whole blocks,
883 * buffering the remaining input.
885 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + wsize + cipher_block_size);
887 /* Decrypt the input block */
888 if (!crypto_cipher_update(cipher,
889 (const u_int8_t *)wbuf,
891 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
893 /* Decryption failed. Shouldn't happen. */
894 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
898 Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
900 if (decrypted_len == 0) {
901 /* No full block of data available, write more data */
905 jcr->crypto_count += decrypted_len;
907 if (jcr->crypto_size == 0 && jcr->crypto_count >= 4) {
908 unser_begin(&jcr->crypto_buf[0], sizeof(uint32_t));
909 unser_uint32(jcr->crypto_size);
910 jcr->crypto_size += 4;
913 if (jcr->crypto_size == 0 || jcr->crypto_count < jcr->crypto_size) {
917 wsize = jcr->crypto_size - 4;
918 wbuf = &jcr->crypto_buf[4]; /* Decrypted, possibly decompressed output here. */
921 if (flags & FO_SPARSE) {
925 unser_begin(wbuf, SPARSE_FADDR_SIZE);
927 if (*addr != faddr) {
929 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
931 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
932 edit_uint64(*addr, ec1), jcr->last_fname,
933 be.strerror(bfd->berrno));
937 wbuf += SPARSE_FADDR_SIZE;
938 wsize -= SPARSE_FADDR_SIZE;
941 if (flags & FO_GZIP) {
942 if (!decompress_data(jcr, &wbuf, &wsize)) {
946 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
949 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
953 jcr->JobBytes += wsize;
960 * In the context of jcr, flush any remaining data from the cipher context,
962 * Return value is true on success, false on failure.
964 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
966 uint32_t decrypted_len;
967 char *wbuf; /* write buffer */
968 uint32_t wsize; /* write size */
969 char ec1[50]; /* Buffer printing huge values */
971 /* Write out the remaining block and free the cipher context */
972 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + cipher_block_size);
974 if (!crypto_cipher_finalize(cipher, (uint8_t *)&jcr->crypto_buf[jcr->crypto_count], &decrypted_len)) {
975 /* Writing out the final, buffered block failed. Shouldn't happen. */
976 Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
979 if (decrypted_len == 0)
981 ASSERT(jcr->crypto_count == 0);
985 jcr->crypto_count += decrypted_len;
987 if (jcr->crypto_size == 0) {
988 ASSERT(jcr->crypto_count >= 4);
989 jcr->crypto_size = ntohl(*(uint32_t *)&jcr->crypto_buf[0]) + 4;
992 ASSERT(jcr->crypto_count == jcr->crypto_size);
994 wbuf = &jcr->crypto_buf[4];
995 wsize = jcr->crypto_size - 4;
997 if (flags & FO_GZIP) {
998 decompress_data(jcr, &wbuf, &wsize);
1000 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1003 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1007 jcr->JobBytes += wsize;