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.\n"));
373 /* Decode and save session keys. */
374 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
376 case CRYPTO_ERROR_NONE:
379 case CRYPTO_ERROR_NORECIPIENT:
380 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
382 case CRYPTO_ERROR_DECRYPTION:
383 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
386 /* Shouldn't happen */
387 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
391 if (cryptoerr != CRYPTO_ERROR_NONE) {
397 /* Set up a decryption context */
398 if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
399 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
400 crypto_session_free(cs);
407 jcr->crypto_count = 0;
408 jcr->crypto_size = 0;
411 case STREAM_FILE_DATA:
412 case STREAM_SPARSE_DATA:
413 case STREAM_WIN32_DATA:
414 case STREAM_GZIP_DATA:
415 case STREAM_SPARSE_GZIP_DATA:
416 case STREAM_WIN32_GZIP_DATA:
417 case STREAM_ENCRYPTED_FILE_DATA:
418 case STREAM_ENCRYPTED_WIN32_DATA:
419 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
420 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
421 /* Force an expected, consistent stream type here */
422 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
423 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
424 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
427 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
431 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
432 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
433 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
437 if (stream == STREAM_ENCRYPTED_FILE_DATA
438 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
439 || stream == STREAM_ENCRYPTED_WIN32_DATA
440 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
444 if (is_win32_stream(stream) && !have_win32_api()) {
445 set_portable_backup(&bfd);
446 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
449 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
457 /* Resource fork stream - only recorded after a file to be restored */
458 /* Silently ignore if we cannot write - we already reported that */
459 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
461 case STREAM_MACOS_FORK_DATA:
462 #ifdef HAVE_DARWIN_OS
464 if (prev_stream != stream) {
465 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
466 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
471 Dmsg0(30, "Restoring resource fork\n");
474 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
485 case STREAM_HFSPLUS_ATTRIBUTES:
486 #ifdef HAVE_DARWIN_OS
487 Dmsg0(30, "Restoring Finder Info\n");
488 if (sd->msglen != 32) {
489 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
492 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
493 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
500 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
502 pm_strcpy(jcr->acl_text, sd->msg);
503 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
504 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
505 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
512 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
514 pm_strcpy(jcr->acl_text, sd->msg);
515 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
516 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
517 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
524 case STREAM_SIGNED_DIGEST:
525 /* Save signature. */
526 if (extract && (sig = crypto_sign_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
527 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
531 case STREAM_MD5_DIGEST:
532 case STREAM_SHA1_DIGEST:
533 case STREAM_SHA256_DIGEST:
534 case STREAM_SHA512_DIGEST:
537 case STREAM_PROGRAM_NAMES:
538 case STREAM_PROGRAM_DATA:
539 if (!non_support_progname) {
540 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
541 non_support_progname++;
546 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
548 Dmsg1(30, "Found wierd stream %d\n", stream);
549 if (size > 0 && !is_bopen(&bfd)) {
550 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
552 /* Flush and deallocate cipher context */
554 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
555 crypto_cipher_free(cipher_ctx);
558 set_attributes(jcr, attr, &bfd);
560 /* Verify the cryptographic signature if any */
563 // Failure is reported in verify_signature() ...
564 verify_signature(jcr, sig);
566 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
571 } else if (is_bopen(&bfd)) {
572 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
575 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
576 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
578 } /* end switch(stream) */
580 } /* end while get_msg() */
582 /* If output file is still open, it was the last one in the
583 * archive since we just hit an end of file, so close the file.
585 if (is_bopen(&altbfd)) {
586 bclose_chksize(jcr, &altbfd, alt_size);
589 /* Flush and deallocate cipher context */
591 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
592 crypto_cipher_free(cipher_ctx);
595 set_attributes(jcr, attr, &bfd);
597 /* Verify the cryptographic signature on the last file, if any */
600 // Failure is reported in verify_signature() ...
601 verify_signature(jcr, sig);
603 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
608 if (is_bopen(&bfd)) {
612 set_jcr_job_status(jcr, JS_Terminated);
616 set_jcr_job_status(jcr, JS_ErrorTerminated);
619 /* Free Signature & Crypto Data */
621 crypto_sign_free(sig);
625 crypto_session_free(cs);
629 crypto_cipher_free(cipher_ctx);
632 if (jcr->compress_buf) {
633 free(jcr->compress_buf);
634 jcr->compress_buf = NULL;
635 jcr->compress_buf_size = 0;
637 if (jcr->crypto_buf) {
638 free_pool_memory(jcr->crypto_buf);
639 jcr->crypto_buf = NULL;
644 free_pool_memory(jcr->acl_text);
645 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
646 edit_uint64(jcr->JobBytes, ec1));
647 if (non_support_data > 1 || non_support_attr > 1) {
648 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
649 non_support_data, non_support_attr);
651 if (non_support_rsrc) {
652 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
654 if (non_support_finfo) {
655 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
657 if (non_support_acl) {
658 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
664 * Convert ZLIB error code into an ASCII message
666 static const char *zlib_strerror(int stat)
673 return _("Zlib errno");
675 return _("Zlib stream error");
677 return _("Zlib data error");
679 return _("Zlib memory error");
681 return _("Zlib buffer error");
682 case Z_VERSION_ERROR:
683 return _("Zlib version error");
689 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level)
691 JCR *jcr = (JCR *)pkt;
692 return (digest_file(jcr, ff_pkt, jcr->digest));
696 * Verify the signature for the last restored file
697 * Return value is either true (signature correct)
698 * or false (signature could not be verified).
699 * TODO landonf: Better signature failure handling.
701 int verify_signature(JCR *jcr, SIGNATURE *sig)
703 X509_KEYPAIR *keypair;
704 DIGEST *digest = NULL;
707 /* Iterate through the trusted signers */
708 foreach_alist(keypair, jcr->pki_signers) {
709 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
712 case CRYPTO_ERROR_NONE:
713 /* Signature found, digest allocated */
714 jcr->digest = digest;
716 /* Checksum the entire file */
717 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
718 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
722 /* Verify the signature */
723 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
724 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
725 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
726 crypto_digest_free(digest);
730 /* Valid signature */
731 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
732 crypto_digest_free(digest);
735 case CRYPTO_ERROR_NOSIGNER:
736 /* Signature not found, try again */
739 /* Something strange happened (that shouldn't happen!)... */
740 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
742 crypto_digest_free(digest);
749 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
750 crypto_digest_free(digest);
754 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
759 char ec1[50]; /* Buffer printing huge values */
762 * NOTE! We only use uLong and Byte because they are
763 * needed by the zlib routines, they should not otherwise
766 compress_len = jcr->compress_buf_size;
767 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
768 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
769 (const Byte *)*data, (uLong)*length)) != Z_OK) {
770 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
771 jcr->last_fname, zlib_strerror(stat));
774 *data = jcr->compress_buf;
775 *length = compress_len;
776 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
779 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
784 static void unser_crypto_size(JCR *jcr)
787 if (jcr->crypto_size == 0 && jcr->crypto_count >= CRYPTO_LEN_SIZE) {
788 unser_begin(&jcr->crypto_buf[0], CRYPTO_LEN_SIZE);
789 unser_uint32(jcr->crypto_size);
790 jcr->crypto_size += CRYPTO_LEN_SIZE;
794 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
797 if (!processWin32BackupAPIBlock(bfd, data, length)) {
799 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
800 jcr->last_fname, be.strerror(bfd->berrno));
803 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
805 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
806 jcr->last_fname, be.strerror(bfd->berrno));
814 * In the context of jcr, write data to bfd.
815 * We write buflen bytes in buf at addr. addr is updated in place.
816 * The flags specify whether to use sparse files or compression.
817 * Return value is the number of bytes written, or -1 on errors.
819 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
820 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
822 char *wbuf; /* write buffer */
823 uint32_t wsize; /* write size */
824 uint32_t rsize; /* read size */
825 uint32_t decrypted_len = 0; /* Decryption output length */
826 char ec1[50]; /* Buffer printing huge values */
829 jcr->ReadBytes += rsize;
833 if (flags & FO_ENCRYPT) {
836 while (jcr->crypto_size > 0 && jcr->crypto_count > 0 && wsize > 0) {
837 uint32_t chunk_size = 16;
839 if (chunk_size > wsize) {
844 * Grow the crypto buffer, if necessary.
845 * crypto_cipher_update() will process only whole blocks,
846 * buffering the remaining input.
848 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + chunk_size + cipher_block_size);
850 /* Decrypt the input block */
851 if (!crypto_cipher_update(cipher,
852 (const u_int8_t *)wbuf,
854 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
856 /* Decryption failed. Shouldn't happen. */
857 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
861 jcr->crypto_count += decrypted_len;
865 if (jcr->crypto_count >= jcr->crypto_size) {
866 char *packet = &jcr->crypto_buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
867 uint32_t packet_size = jcr->crypto_size - CRYPTO_LEN_SIZE;
869 if (flags & FO_GZIP) {
870 if (!decompress_data(jcr, &packet, &packet_size)) {
874 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
877 if (!store_data(jcr, bfd, packet, packet_size, (flags & FO_WIN32DECOMP) != 0)) {
881 jcr->JobBytes += packet_size;
882 *addr += packet_size;
884 memmove(&jcr->crypto_buf[0], &jcr->crypto_buf[jcr->crypto_size], jcr->crypto_count - jcr->crypto_size);
885 jcr->crypto_count -= jcr->crypto_size;
886 jcr->crypto_size = 0;
891 * Grow the crypto buffer, if necessary.
892 * crypto_cipher_update() will process only whole blocks,
893 * buffering the remaining input.
895 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + wsize + cipher_block_size);
897 /* Decrypt the input block */
898 if (!crypto_cipher_update(cipher,
899 (const u_int8_t *)wbuf,
901 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
903 /* Decryption failed. Shouldn't happen. */
904 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
908 Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
910 if (decrypted_len == 0) {
911 /* No full block of data available, write more data */
915 jcr->crypto_count += decrypted_len;
917 unser_crypto_size(jcr);
918 wsize = jcr->crypto_size - CRYPTO_LEN_SIZE;
919 Dmsg1(10, "Decrypt size=%d\n", wsize);
920 wbuf = &jcr->crypto_buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
922 if (jcr->crypto_size == 0 || jcr->crypto_count < jcr->crypto_size) {
928 if (flags & FO_SPARSE) {
932 unser_begin(wbuf, SPARSE_FADDR_SIZE);
934 if (*addr != faddr) {
936 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
938 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
939 edit_uint64(*addr, ec1), jcr->last_fname,
940 be.strerror(bfd->berrno));
944 wbuf += SPARSE_FADDR_SIZE;
945 wsize -= SPARSE_FADDR_SIZE;
948 if (flags & FO_GZIP) {
949 if (!decompress_data(jcr, &wbuf, &wsize)) {
953 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
956 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
960 jcr->JobBytes += wsize;
967 * In the context of jcr, flush any remaining data from the cipher context,
969 * Return value is true on success, false on failure.
971 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
973 uint32_t decrypted_len;
974 char *wbuf; /* write buffer */
975 uint32_t wsize; /* write size */
976 char ec1[50]; /* Buffer printing huge values */
978 /* Write out the remaining block and free the cipher context */
979 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count +
982 if (!crypto_cipher_finalize(cipher, (uint8_t *)&jcr->crypto_buf[jcr->crypto_count],
984 /* Writing out the final, buffered block failed. Shouldn't happen. */
985 Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
988 /* If nothing new was decrypted, and our output buffer is empty, return */
989 if (decrypted_len == 0 && jcr->crypto_count == 0) {
993 jcr->crypto_count += decrypted_len;
995 unser_crypto_size(jcr);
996 wsize = jcr->crypto_size - CRYPTO_LEN_SIZE;
997 Dmsg1(10, "Unser size=%d\n", wsize);
998 wbuf = &jcr->crypto_buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1000 ASSERT(jcr->crypto_count == jcr->crypto_size);
1002 if (flags & FO_GZIP) {
1003 decompress_data(jcr, &wbuf, &wsize);
1005 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1008 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1012 jcr->JobBytes += wsize;