2 * Bacula File Daemon restore.c Restorefiles.
4 * Kern Sibbald, November MM
10 Copyright (C) 2000-2006 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 #if defined(HAVE_CRYPTO)
32 const bool have_crypto = true;
34 const bool have_crypto = false;
37 /* Data received from Storage Daemon */
38 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
40 /* Forward referenced functions */
41 #if defined(HAVE_LIBZ)
42 static const char *zlib_strerror(int stat);
43 const bool have_libz = true;
45 const bool have_libz = false;
48 int verify_signature(JCR *jcr, SIGNATURE *sig);
49 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
50 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size);
51 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size);
53 #define RETRY 10 /* retry wait time */
56 * Close a bfd check that we are at the expected file offset.
57 * Makes some code in set_attributes().
59 int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
61 char ec1[50], ec2[50];
64 fsize = blseek(bfd, 0, SEEK_CUR);
65 bclose(bfd); /* first close file */
66 if (fsize > 0 && fsize != osize) {
67 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
68 jcr->last_fname, edit_uint64(osize, ec1),
69 edit_uint64(fsize, ec2));
76 * Restore the requested files.
79 void do_restore(JCR *jcr)
84 uint32_t VolSessionId, VolSessionTime;
87 char ec1[50]; /* Buffer printing huge values */
89 BFILE bfd; /* File content */
90 uint64_t fileAddr = 0; /* file write address */
91 uint32_t size; /* Size of file */
92 BFILE altbfd; /* Alternative data stream */
93 uint64_t alt_addr = 0; /* Write address for alternative stream */
94 intmax_t alt_size = 0; /* Size of alternate stream */
95 SIGNATURE *sig = NULL; /* Cryptographic signature (if any) for file */
96 CRYPTO_SESSION *cs = NULL; /* Cryptographic session data (if any) for file */
97 CIPHER_CONTEXT *cipher_ctx = NULL; /* Cryptographic cipher context (if any) for file */
98 uint32_t cipher_block_size = 0; /* Cryptographic algorithm block size for file */
99 int flags = 0; /* Options for extract_data() */
103 /* The following variables keep track of "known unknowns" */
104 int non_support_data = 0;
105 int non_support_attr = 0;
106 int non_support_rsrc = 0;
107 int non_support_finfo = 0;
108 int non_support_acl = 0;
109 int non_support_progname = 0;
111 /* Finally, set up for special configurations */
112 #ifdef HAVE_DARWIN_OS
113 intmax_t rsrc_len = 0; /* Original length of resource fork */
114 struct attrlist attrList;
116 memset(&attrList, 0, sizeof(attrList));
117 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
118 attrList.commonattr = ATTR_CMN_FNDRINFO;
121 sd = jcr->store_bsock;
122 set_jcr_job_status(jcr, JS_Running);
125 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
129 buf_size = client->max_network_buffer_size;
131 buf_size = 0; /* use default */
133 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
134 set_jcr_job_status(jcr, JS_ErrorTerminated);
137 jcr->buf_size = sd->msglen;
139 #ifdef stbernard_implemented
140 / #if defined(HAVE_WIN32)
141 bool bResumeOfmOnExit = FALSE;
142 if (isOpenFileManagerRunning()) {
143 if ( pauseOpenFileManager() ) {
144 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
145 bResumeOfmOnExit = TRUE;
148 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
152 char username[UNLEN+1];
153 DWORD usize = sizeof(username);
154 int privs = enable_backup_privileges(NULL, 1);
155 if (GetUserName(username, &usize)) {
156 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
158 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
164 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
165 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
166 jcr->compress_buf_size = compress_buf_size;
170 jcr->crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
174 * Get a record from the Storage daemon. We are guaranteed to
175 * receive records in the following order:
176 * 1. Stream record header
178 * a. Attributes (Unix or Win32)
179 * b. Possibly stream encryption session data (e.g., symmetric session key)
180 * or c. File data for the file
181 * or d. Alternate data stream (e.g. Resource Fork)
184 * or g. Possibly a cryptographic signature
185 * or h. Possibly MD5 or SHA1 record
188 * NOTE: We keep track of two bacula file descriptors:
189 * 1. bfd for file data.
190 * This fd is opened for non empty files when an attribute stream is
191 * encountered and closed when we find the next attribute stream.
192 * 2. alt_bfd for alternate data streams
193 * This fd is opened every time we encounter a new alternate data
194 * stream for the current file. When we find any other stream, we
196 * The expected size of the stream, alt_len, should be set when
202 jcr->acl_text = get_pool_memory(PM_MESSAGE);
204 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
205 /* Remember previous stream type */
206 prev_stream = stream;
208 /* First we expect a Stream Record Header */
209 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
210 &stream, &size) != 5) {
211 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
214 Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
216 /* * Now we expect the Stream Data */
217 if (bget_msg(sd) < 0) {
218 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
221 if (size != (uint32_t)sd->msglen) {
222 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
225 Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
227 /* If we change streams, close and reset alternate data streams */
228 if (prev_stream != stream) {
229 if (is_bopen(&altbfd)) {
230 bclose_chksize(jcr, &altbfd, alt_size);
232 alt_size = -1; /* Use an impossible value and set a proper one below */
236 /* File Attributes stream */
238 case STREAM_UNIX_ATTRIBUTES:
239 case STREAM_UNIX_ATTRIBUTES_EX:
240 Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
242 * If extracting, it was from previous stream, so
243 * close the output file and validate the signature.
246 if (size > 0 && !is_bopen(&bfd)) {
247 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
249 /* Flush and deallocate previous stream's cipher context */
250 if (cipher_ctx && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
251 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
252 crypto_cipher_free(cipher_ctx);
255 set_attributes(jcr, attr, &bfd);
258 /* Verify the cryptographic signature, if any */
261 // Failure is reported in verify_signature() ...
262 verify_signature(jcr, sig);
264 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
269 crypto_sign_free(sig);
273 crypto_session_free(cs);
276 Dmsg0(30, "Stop extracting.\n");
277 } else if (is_bopen(&bfd)) {
278 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
283 * Unpack and do sanity check fo attributes.
285 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
288 if (file_index != attr->file_index) {
289 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
290 file_index, attr->file_index);
291 Dmsg0(100, "File index error\n");
295 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
296 attr->attr, attr->attrEx);
298 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
300 if (!is_restore_stream_supported(attr->data_stream)) {
301 if (!non_support_data++) {
302 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
303 stream_to_ascii(attr->data_stream));
308 build_attr_output_fnames(jcr, attr);
311 * Now determine if we are extracting or not.
313 jcr->num_files_examined++;
314 Dmsg1(30, "Outfile=%s\n", attr->ofname);
316 stat = create_file(jcr, attr, &bfd, jcr->replace);
321 case CF_EXTRACT: /* File created and we expect file data */
324 case CF_CREATED: /* File created, but there is no content */
326 pm_strcpy(jcr->last_fname, attr->ofname);
327 jcr->last_type = attr->type;
331 print_ls_output(jcr, attr);
332 #ifdef HAVE_DARWIN_OS
333 /* Only restore the resource fork for regular files */
334 from_base64(&rsrc_len, attr->attrEx);
335 if (attr->type == FT_REG && rsrc_len > 0) {
340 /* set attributes now because file will not be extracted */
341 set_attributes(jcr, attr, &bfd);
348 case STREAM_ENCRYPTED_SESSION_DATA:
349 crypto_error_t cryptoerr;
351 Dmsg1(30, "Stream=Encrypted Session Data, size: %d\n", sd->msglen);
353 /* Do we have any keys at all? */
354 if (!jcr->pki_recipients) {
355 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data."));
359 /* Decode and save session keys. */
360 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
362 case CRYPTO_ERROR_NONE:
365 case CRYPTO_ERROR_NORECIPIENT:
366 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
368 case CRYPTO_ERROR_DECRYPTION:
369 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
372 /* Shouldn't happen */
373 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
377 if (cryptoerr != CRYPTO_ERROR_NONE) {
383 /* Set up a decryption context */
384 if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
385 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
386 crypto_session_free(cs);
393 jcr->crypto_count = 0;
394 jcr->crypto_size = 0;
397 case STREAM_FILE_DATA:
398 case STREAM_SPARSE_DATA:
399 case STREAM_WIN32_DATA:
400 case STREAM_GZIP_DATA:
401 case STREAM_SPARSE_GZIP_DATA:
402 case STREAM_WIN32_GZIP_DATA:
403 case STREAM_ENCRYPTED_FILE_DATA:
404 case STREAM_ENCRYPTED_WIN32_DATA:
405 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
406 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
407 /* Force an expected, consistent stream type here */
408 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
409 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
410 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
413 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
417 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
418 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
419 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
423 if (stream == STREAM_ENCRYPTED_FILE_DATA
424 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
425 || stream == STREAM_ENCRYPTED_WIN32_DATA
426 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
430 if (is_win32_stream(stream) && !have_win32_api()) {
431 set_portable_backup(&bfd);
432 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
435 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
443 /* Resource fork stream - only recorded after a file to be restored */
444 /* Silently ignore if we cannot write - we already reported that */
445 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
447 case STREAM_MACOS_FORK_DATA:
448 #ifdef HAVE_DARWIN_OS
450 if (prev_stream != stream) {
451 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
452 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
457 Dmsg0(30, "Restoring resource fork\n");
460 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
471 case STREAM_HFSPLUS_ATTRIBUTES:
472 #ifdef HAVE_DARWIN_OS
473 Dmsg0(30, "Restoring Finder Info\n");
474 if (sd->msglen != 32) {
475 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
478 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
479 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
486 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
488 pm_strcpy(jcr->acl_text, sd->msg);
489 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
490 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
491 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
498 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
500 pm_strcpy(jcr->acl_text, sd->msg);
501 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
502 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
503 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
510 case STREAM_SIGNED_DIGEST:
511 /* Save signature. */
512 if ((sig = crypto_sign_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
513 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
517 case STREAM_MD5_DIGEST:
518 case STREAM_SHA1_DIGEST:
519 case STREAM_SHA256_DIGEST:
520 case STREAM_SHA512_DIGEST:
523 case STREAM_PROGRAM_NAMES:
524 case STREAM_PROGRAM_DATA:
525 if (!non_support_progname) {
526 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
527 non_support_progname++;
532 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
534 Dmsg1(30, "Found wierd stream %d\n", stream);
535 if (size > 0 && !is_bopen(&bfd)) {
536 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
538 /* Flush and deallocate cipher context */
540 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
541 crypto_cipher_free(cipher_ctx);
544 set_attributes(jcr, attr, &bfd);
546 /* Verify the cryptographic signature if any */
549 // Failure is reported in verify_signature() ...
550 verify_signature(jcr, sig);
552 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
557 } else if (is_bopen(&bfd)) {
558 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
561 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
562 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
564 } /* end switch(stream) */
566 } /* end while get_msg() */
568 /* If output file is still open, it was the last one in the
569 * archive since we just hit an end of file, so close the file.
571 if (is_bopen(&altbfd)) {
572 bclose_chksize(jcr, &altbfd, alt_size);
575 /* Flush and deallocate cipher context */
577 flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
578 crypto_cipher_free(cipher_ctx);
581 set_attributes(jcr, attr, &bfd);
583 /* Verify the cryptographic signature on the last file, if any */
586 // Failure is reported in verify_signature() ...
587 verify_signature(jcr, sig);
589 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
594 if (is_bopen(&bfd)) {
598 set_jcr_job_status(jcr, JS_Terminated);
602 set_jcr_job_status(jcr, JS_ErrorTerminated);
605 /* Free Signature & Crypto Data */
607 crypto_sign_free(sig);
611 crypto_session_free(cs);
615 crypto_cipher_free(cipher_ctx);
618 if (jcr->compress_buf) {
619 free(jcr->compress_buf);
620 jcr->compress_buf = NULL;
621 jcr->compress_buf_size = 0;
623 if (jcr->crypto_buf) {
624 free_pool_memory(jcr->crypto_buf);
625 jcr->crypto_buf = NULL;
630 free_pool_memory(jcr->acl_text);
631 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
632 edit_uint64(jcr->JobBytes, ec1));
633 if (non_support_data > 1 || non_support_attr > 1) {
634 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
635 non_support_data, non_support_attr);
637 if (non_support_rsrc) {
638 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
640 if (non_support_finfo) {
641 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
643 if (non_support_acl) {
644 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
650 * Convert ZLIB error code into an ASCII message
652 static const char *zlib_strerror(int stat)
659 return _("Zlib errno");
661 return _("Zlib stream error");
663 return _("Zlib data error");
665 return _("Zlib memory error");
667 return _("Zlib buffer error");
668 case Z_VERSION_ERROR:
669 return _("Zlib version error");
675 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level)
677 JCR *jcr = (JCR *)pkt;
678 return (digest_file(jcr, ff_pkt, jcr->digest));
682 * Verify the signature for the last restored file
683 * Return value is either true (signature correct)
684 * or false (signature could not be verified).
685 * TODO landonf: Better signature failure handling.
687 int verify_signature(JCR *jcr, SIGNATURE *sig)
689 X509_KEYPAIR *keypair;
690 DIGEST *digest = NULL;
693 /* Iterate through the trusted signers */
694 foreach_alist(keypair, jcr->pki_signers) {
695 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
698 case CRYPTO_ERROR_NONE:
699 /* Signature found, digest allocated */
700 jcr->digest = digest;
702 /* Checksum the entire file */
703 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
704 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
708 /* Verify the signature */
709 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
710 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
711 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
712 crypto_digest_free(digest);
716 /* Valid signature */
717 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
718 crypto_digest_free(digest);
721 case CRYPTO_ERROR_NOSIGNER:
722 /* Signature not found, try again */
725 /* Something strange happened (that shouldn't happen!)... */
726 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
728 crypto_digest_free(digest);
735 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
736 crypto_digest_free(digest);
740 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
745 char ec1[50]; /* Buffer printing huge values */
748 * NOTE! We only use uLong and Byte because they are
749 * needed by the zlib routines, they should not otherwise
752 compress_len = jcr->compress_buf_size;
753 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
754 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
755 (const Byte *)*data, (uLong)*length)) != Z_OK) {
756 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
757 jcr->last_fname, zlib_strerror(stat));
760 *data = jcr->compress_buf;
761 *length = compress_len;
762 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
765 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
770 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
773 if (!processWin32BackupAPIBlock(bfd, data, length)) {
775 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
776 jcr->last_fname, be.strerror(bfd->berrno));
779 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
781 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
782 jcr->last_fname, be.strerror(bfd->berrno));
790 * In the context of jcr, write data to bfd.
791 * We write buflen bytes in buf at addr. addr is updated in place.
792 * The flags specify whether to use sparse files or compression.
793 * Return value is the number of bytes written, or -1 on errors.
795 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
796 uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
798 char *wbuf; /* write buffer */
799 uint32_t wsize; /* write size */
800 uint32_t rsize; /* read size */
801 uint32_t decrypted_len = 0; /* Decryption output length */
802 char ec1[50]; /* Buffer printing huge values */
805 jcr->ReadBytes += rsize;
809 if (flags & FO_ENCRYPT) {
813 while (jcr->crypto_size > 0 && jcr->crypto_count > 0 && wsize > 0) {
814 uint32_t chunk_size = 16;
816 if (chunk_size > wsize) {
821 * Grow the crypto buffer, if necessary.
822 * crypto_cipher_update() will process only whole blocks,
823 * buffering the remaining input.
825 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + chunk_size + cipher_block_size);
827 /* Decrypt the input block */
828 if (!crypto_cipher_update(cipher,
829 (const u_int8_t *)wbuf,
831 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
833 /* Decryption failed. Shouldn't happen. */
834 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
838 jcr->crypto_count += decrypted_len;
842 if (jcr->crypto_count >= jcr->crypto_size) {
844 char *packet = &jcr->crypto_buf[4]; /* Decrypted, possibly decompressed output here. */
845 uint32_t packet_size = jcr->crypto_size - 4;
847 if (flags & FO_GZIP) {
848 if (!decompress_data(jcr, &packet, &packet_size)) {
852 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
855 if (!store_data(jcr, bfd, packet, packet_size, (flags & FO_WIN32DECOMP) != 0)) {
859 jcr->JobBytes += packet_size;
860 *addr += packet_size;
862 memmove(&jcr->crypto_buf[0], &jcr->crypto_buf[jcr->crypto_size], jcr->crypto_count - jcr->crypto_size);
863 jcr->crypto_count -= jcr->crypto_size;
864 jcr->crypto_size = 0;
869 * Grow the crypto buffer, if necessary.
870 * crypto_cipher_update() will process only whole blocks,
871 * buffering the remaining input.
873 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + wsize + cipher_block_size);
875 /* Decrypt the input block */
876 if (!crypto_cipher_update(cipher,
877 (const u_int8_t *)wbuf,
879 (u_int8_t *)&jcr->crypto_buf[jcr->crypto_count],
881 /* Decryption failed. Shouldn't happen. */
882 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
886 Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
888 if (decrypted_len == 0) {
889 /* No full block of data available, write more data */
893 jcr->crypto_count += decrypted_len;
895 if (jcr->crypto_size == 0 && jcr->crypto_count >= 4) {
896 unser_begin(&jcr->crypto_buf[0], sizeof(uint32_t));
897 unser_uint32(jcr->crypto_size);
898 jcr->crypto_size += 4;
901 if (jcr->crypto_size == 0 || jcr->crypto_count < jcr->crypto_size) {
905 wsize = jcr->crypto_size - 4;
906 wbuf = &jcr->crypto_buf[4]; /* Decrypted, possibly decompressed output here. */
909 if (flags & FO_SPARSE) {
913 unser_begin(wbuf, SPARSE_FADDR_SIZE);
915 if (*addr != faddr) {
917 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
919 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
920 edit_uint64(*addr, ec1), jcr->last_fname,
921 be.strerror(bfd->berrno));
925 wbuf += SPARSE_FADDR_SIZE;
926 wsize -= SPARSE_FADDR_SIZE;
929 if (flags & FO_GZIP) {
930 if (!decompress_data(jcr, &wbuf, &wsize)) {
934 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
937 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
941 jcr->JobBytes += wsize;
948 * In the context of jcr, flush any remaining data from the cipher context,
950 * Return value is true on success, false on failure.
952 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, uint32_t cipher_block_size)
954 uint32_t decrypted_len;
955 char *wbuf; /* write buffer */
956 uint32_t wsize; /* write size */
957 char ec1[50]; /* Buffer printing huge values */
959 /* Write out the remaining block and free the cipher context */
960 jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, jcr->crypto_count + cipher_block_size);
962 if (!crypto_cipher_finalize(cipher, (uint8_t *)&jcr->crypto_buf[jcr->crypto_count], &decrypted_len)) {
963 /* Writing out the final, buffered block failed. Shouldn't happen. */
964 Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
967 if (decrypted_len == 0)
969 ASSERT(jcr->crypto_count == 0);
973 jcr->crypto_count += decrypted_len;
975 if (jcr->crypto_size == 0) {
976 ASSERT(jcr->crypto_count >= 4);
977 jcr->crypto_size = ntohl(*(uint32_t *)&jcr->crypto_buf[0]) + 4;
980 ASSERT(jcr->crypto_count == jcr->crypto_size);
982 wbuf = &jcr->crypto_buf[4];
983 wsize = jcr->crypto_size - 4;
985 if (flags & FO_GZIP) {
986 decompress_data(jcr, &wbuf, &wsize);
988 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
991 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
995 jcr->JobBytes += wsize;