2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Bacula File Daemon restore.c Restorefiles.
31 * Kern Sibbald, November MM
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 typedef struct restore_cipher_ctx {
62 CIPHER_CONTEXT *cipher;
65 POOLMEM *buf; /* Pointer to descryption buffer */
66 int32_t buf_len; /* Count of bytes currently in buf */
67 int32_t packet_len; /* Total bytes in packet */
70 int verify_signature(JCR *jcr, SIGNATURE *sig);
71 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
72 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
73 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
75 #define RETRY 10 /* retry wait time */
78 * Close a bfd check that we are at the expected file offset.
79 * Makes some code in set_attributes().
81 int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
83 char ec1[50], ec2[50];
86 fsize = blseek(bfd, 0, SEEK_CUR);
87 bclose(bfd); /* first close file */
88 if (fsize > 0 && fsize != osize) {
89 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
90 jcr->last_fname, edit_uint64(osize, ec1),
91 edit_uint64(fsize, ec2));
98 * Restore the requested files.
101 void do_restore(JCR *jcr)
106 uint32_t VolSessionId, VolSessionTime;
107 bool extract = false;
109 char ec1[50]; /* Buffer printing huge values */
110 BFILE bfd; /* File content */
111 uint64_t fileAddr = 0; /* file write address */
112 uint32_t size; /* Size of file */
113 BFILE altbfd; /* Alternative data stream */
114 uint64_t alt_addr = 0; /* Write address for alternative stream */
115 intmax_t alt_size = 0; /* Size of alternate stream */
116 SIGNATURE *sig = NULL; /* Cryptographic signature (if any) for file */
117 CRYPTO_SESSION *cs = NULL; /* Cryptographic session data (if any) for file */
118 RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
119 RESTORE_CIPHER_CTX alt_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
120 int flags = 0; /* Options for extract_data() */
121 int alt_flags = 0; /* Options for extract_data() */
125 /* The following variables keep track of "known unknowns" */
126 int non_support_data = 0;
127 int non_support_attr = 0;
128 int non_support_rsrc = 0;
129 int non_support_finfo = 0;
130 int non_support_acl = 0;
131 int non_support_progname = 0;
133 /* Finally, set up for special configurations */
134 #ifdef HAVE_DARWIN_OS
135 intmax_t rsrc_len = 0; /* Original length of resource fork */
136 struct attrlist attrList;
138 memset(&attrList, 0, sizeof(attrList));
139 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
140 attrList.commonattr = ATTR_CMN_FNDRINFO;
143 sd = jcr->store_bsock;
144 set_jcr_job_status(jcr, JS_Running);
147 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
151 buf_size = client->max_network_buffer_size;
153 buf_size = 0; /* use default */
155 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
156 set_jcr_job_status(jcr, JS_ErrorTerminated);
159 jcr->buf_size = sd->msglen;
161 #ifdef stbernard_implemented
162 / #if defined(HAVE_WIN32)
163 bool bResumeOfmOnExit = FALSE;
164 if (isOpenFileManagerRunning()) {
165 if ( pauseOpenFileManager() ) {
166 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
167 bResumeOfmOnExit = TRUE;
170 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
174 char username[UNLEN+1];
175 DWORD usize = sizeof(username);
176 int privs = enable_backup_privileges(NULL, 1);
177 if (GetUserName(username, &usize)) {
178 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
180 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
186 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
187 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
188 jcr->compress_buf_size = compress_buf_size;
191 cipher_ctx.cipher = NULL;
192 alt_cipher_ctx.cipher = NULL;
194 cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
195 cipher_ctx.buf_len = 0;
196 cipher_ctx.packet_len = 0;
198 alt_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
199 alt_cipher_ctx.buf_len = 0;
200 alt_cipher_ctx.packet_len = 0;
202 cipher_ctx.buf = NULL;
203 alt_cipher_ctx.buf = NULL;
207 * Get a record from the Storage daemon. We are guaranteed to
208 * receive records in the following order:
209 * 1. Stream record header
211 * a. Attributes (Unix or Win32)
212 * b. Possibly stream encryption session data (e.g., symmetric session key)
213 * or c. File data for the file
214 * or d. Alternate data stream (e.g. Resource Fork)
217 * or g. Possibly a cryptographic signature
218 * or h. Possibly MD5 or SHA1 record
221 * NOTE: We keep track of two bacula file descriptors:
222 * 1. bfd for file data.
223 * This fd is opened for non empty files when an attribute stream is
224 * encountered and closed when we find the next attribute stream.
225 * 2. alt_bfd for alternate data streams
226 * This fd is opened every time we encounter a new alternate data
227 * stream for the current file. When we find any other stream, we
229 * The expected size of the stream, alt_len, should be set when
235 jcr->acl_text = get_pool_memory(PM_MESSAGE);
237 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
238 /* Remember previous stream type */
239 prev_stream = stream;
241 /* First we expect a Stream Record Header */
242 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
243 &stream, &size) != 5) {
244 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
247 Dmsg4(30, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n",
248 jcr->JobFiles, file_index, stream, stream_to_ascii(stream));
250 /* * Now we expect the Stream Data */
251 if (bget_msg(sd) < 0) {
252 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
255 if (size != (uint32_t)sd->msglen) {
256 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
259 Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(stream),
260 sd->msglen, extract);
262 /* If we change streams, close and reset alternate data streams */
263 if (prev_stream != stream) {
264 if (is_bopen(&altbfd)) {
265 if (alt_cipher_ctx.cipher) {
266 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
267 crypto_cipher_free(alt_cipher_ctx.cipher);
268 alt_cipher_ctx.cipher = NULL;
270 bclose_chksize(jcr, &altbfd, alt_size);
272 alt_size = -1; /* Use an impossible value and set a proper one below */
276 /* File Attributes stream */
278 case STREAM_UNIX_ATTRIBUTES:
279 case STREAM_UNIX_ATTRIBUTES_EX:
281 * If extracting, it was from previous stream, so
282 * close the output file and validate the signature.
285 if (size > 0 && !is_bopen(&bfd)) {
286 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
288 /* Flush and deallocate previous stream's cipher context */
289 if (cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
290 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
291 crypto_cipher_free(cipher_ctx.cipher);
292 cipher_ctx.cipher = NULL;
295 /* Flush and deallocate previous stream's alt cipher context */
296 if (alt_cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
297 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
298 crypto_cipher_free(alt_cipher_ctx.cipher);
299 alt_cipher_ctx.cipher = NULL;
301 set_attributes(jcr, attr, &bfd);
304 /* Verify the cryptographic signature, if any */
307 // Failure is reported in verify_signature() ...
308 verify_signature(jcr, sig);
310 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
315 crypto_sign_free(sig);
319 crypto_session_free(cs);
323 Dmsg0(30, "Stop extracting.\n");
324 } else if (is_bopen(&bfd)) {
325 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
330 * Unpack and do sanity check fo attributes.
332 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
335 if (file_index != attr->file_index) {
336 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
337 file_index, attr->file_index);
338 Dmsg0(100, "File index error\n");
342 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
343 attr->attr, attr->attrEx);
345 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
347 if (!is_restore_stream_supported(attr->data_stream)) {
348 if (!non_support_data++) {
349 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
350 stream_to_ascii(attr->data_stream));
355 build_attr_output_fnames(jcr, attr);
358 * Now determine if we are extracting or not.
360 jcr->num_files_examined++;
362 stat = create_file(jcr, attr, &bfd, jcr->replace);
363 Dmsg2(30, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
368 case CF_EXTRACT: /* File created and we expect file data */
371 case CF_CREATED: /* File created, but there is no content */
373 pm_strcpy(jcr->last_fname, attr->ofname);
374 jcr->last_type = attr->type;
378 print_ls_output(jcr, attr);
380 #ifdef HAVE_DARWIN_OS
381 /* Only restore the resource fork for regular files */
382 from_base64(&rsrc_len, attr->attrEx);
383 if (attr->type == FT_REG && rsrc_len > 0) {
388 /* set attributes now because file will not be extracted */
389 set_attributes(jcr, attr, &bfd);
396 case STREAM_ENCRYPTED_SESSION_DATA:
397 crypto_error_t cryptoerr;
399 /* Is this an unexpected session data entry? */
401 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
407 /* Do we have any keys at all? */
408 if (!jcr->pki_recipients) {
409 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
415 /* Decode and save session keys. */
416 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
418 case CRYPTO_ERROR_NONE:
421 case CRYPTO_ERROR_NORECIPIENT:
422 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
424 case CRYPTO_ERROR_DECRYPTION:
425 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
428 /* Shouldn't happen */
429 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
433 if (cryptoerr != CRYPTO_ERROR_NONE) {
441 case STREAM_FILE_DATA:
442 case STREAM_SPARSE_DATA:
443 case STREAM_WIN32_DATA:
444 case STREAM_GZIP_DATA:
445 case STREAM_SPARSE_GZIP_DATA:
446 case STREAM_WIN32_GZIP_DATA:
447 case STREAM_ENCRYPTED_FILE_DATA:
448 case STREAM_ENCRYPTED_WIN32_DATA:
449 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
450 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
451 /* Force an expected, consistent stream type here */
452 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
453 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
454 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
457 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
461 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
462 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
463 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
467 if (stream == STREAM_ENCRYPTED_FILE_DATA
468 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
469 || stream == STREAM_ENCRYPTED_WIN32_DATA
470 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
471 /* Set up a decryption context */
472 if (!cipher_ctx.cipher) {
474 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
480 if ((cipher_ctx.cipher = crypto_cipher_new(cs, false, &cipher_ctx.block_size)) == NULL) {
481 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
482 crypto_session_free(cs);
492 if (is_win32_stream(stream) && !have_win32_api()) {
493 set_portable_backup(&bfd);
494 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
497 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags,
506 /* Resource fork stream - only recorded after a file to be restored */
507 /* Silently ignore if we cannot write - we already reported that */
508 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
509 case STREAM_MACOS_FORK_DATA:
510 #ifdef HAVE_DARWIN_OS
512 jcr->ff->flags |= FO_HFSPLUS;
514 if (stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
515 alt_flags |= FO_ENCRYPT;
517 /* Set up a decryption context */
518 if (extract && !alt_cipher_ctx.cipher) {
520 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
526 if ((alt_cipher_ctx.cipher = crypto_cipher_new(cs, false, &alt_cipher_ctx.block_size)) == NULL) {
527 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
528 crypto_session_free(cs);
538 if (prev_stream != stream) {
539 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
540 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
546 Dmsg0(30, "Restoring resource fork\n");
549 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, alt_flags,
550 &alt_cipher_ctx) < 0) {
561 case STREAM_HFSPLUS_ATTRIBUTES:
562 #ifdef HAVE_DARWIN_OS
563 Dmsg0(30, "Restoring Finder Info\n");
564 jcr->ff->flags |= FO_HFSPLUS;
565 if (sd->msglen != 32) {
566 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
569 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
570 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
578 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
580 pm_strcpy(jcr->acl_text, sd->msg);
581 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
582 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
583 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
590 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
592 pm_strcpy(jcr->acl_text, sd->msg);
593 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
594 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
595 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
602 case STREAM_SIGNED_DIGEST:
604 /* Is this an unexpected signature? */
606 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
610 /* Save signature. */
611 if (extract && (sig = crypto_sign_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
612 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
616 case STREAM_MD5_DIGEST:
617 case STREAM_SHA1_DIGEST:
618 case STREAM_SHA256_DIGEST:
619 case STREAM_SHA512_DIGEST:
622 case STREAM_PROGRAM_NAMES:
623 case STREAM_PROGRAM_DATA:
624 if (!non_support_progname) {
625 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
626 non_support_progname++;
631 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
633 Dmsg1(30, "Found wierd stream %d\n", stream);
634 if (size > 0 && !is_bopen(&bfd)) {
635 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
637 /* Flush and deallocate cipher context */
638 if (cipher_ctx.cipher) {
639 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
640 crypto_cipher_free(cipher_ctx.cipher);
641 cipher_ctx.cipher = NULL;
644 /* Flush and deallocate alt cipher context */
645 if (alt_cipher_ctx.cipher) {
646 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
647 crypto_cipher_free(alt_cipher_ctx.cipher);
648 alt_cipher_ctx.cipher = NULL;
651 set_attributes(jcr, attr, &bfd);
653 /* Verify the cryptographic signature if any */
656 // Failure is reported in verify_signature() ...
657 verify_signature(jcr, sig);
659 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
664 } else if (is_bopen(&bfd)) {
665 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
668 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
669 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
671 } /* end switch(stream) */
673 } /* end while get_msg() */
675 /* If output file is still open, it was the last one in the
676 * archive since we just hit an end of file, so close the file.
678 if (is_bopen(&altbfd)) {
679 bclose_chksize(jcr, &altbfd, alt_size);
682 /* Flush and deallocate cipher context */
683 if (cipher_ctx.cipher) {
684 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
685 crypto_cipher_free(cipher_ctx.cipher);
686 cipher_ctx.cipher = NULL;
689 /* Flush and deallocate alt cipher context */
690 if (alt_cipher_ctx.cipher) {
691 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
692 crypto_cipher_free(alt_cipher_ctx.cipher);
693 alt_cipher_ctx.cipher = NULL;
696 set_attributes(jcr, attr, &bfd);
698 /* Verify the cryptographic signature on the last file, if any */
701 // Failure is reported in verify_signature() ...
702 verify_signature(jcr, sig);
704 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
709 if (is_bopen(&bfd)) {
713 set_jcr_job_status(jcr, JS_Terminated);
717 set_jcr_job_status(jcr, JS_ErrorTerminated);
720 /* Free Signature & Crypto Data */
722 crypto_sign_free(sig);
726 crypto_session_free(cs);
730 /* Free file cipher restore context */
731 if (cipher_ctx.cipher) {
732 crypto_cipher_free(cipher_ctx.cipher);
733 cipher_ctx.cipher = NULL;
735 if (cipher_ctx.buf) {
736 free_pool_memory(cipher_ctx.buf);
737 cipher_ctx.buf = NULL;
740 /* Free alternate stream cipher restore context */
741 if (alt_cipher_ctx.cipher) {
742 crypto_cipher_free(alt_cipher_ctx.cipher);
743 alt_cipher_ctx.cipher = NULL;
745 if (alt_cipher_ctx.buf) {
746 free_pool_memory(alt_cipher_ctx.buf);
747 alt_cipher_ctx.buf = NULL;
750 if (jcr->compress_buf) {
751 free(jcr->compress_buf);
752 jcr->compress_buf = NULL;
753 jcr->compress_buf_size = 0;
758 free_pool_memory(jcr->acl_text);
759 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
760 edit_uint64(jcr->JobBytes, ec1));
761 if (non_support_data > 1 || non_support_attr > 1) {
762 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
763 non_support_data, non_support_attr);
765 if (non_support_rsrc) {
766 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
768 if (non_support_finfo) {
769 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
771 if (non_support_acl) {
772 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
779 * Convert ZLIB error code into an ASCII message
781 static const char *zlib_strerror(int stat)
788 return _("Zlib errno");
790 return _("Zlib stream error");
792 return _("Zlib data error");
794 return _("Zlib memory error");
796 return _("Zlib buffer error");
797 case Z_VERSION_ERROR:
798 return _("Zlib version error");
805 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level)
807 JCR *jcr = (JCR *)pkt;
808 return (digest_file(jcr, ff_pkt, jcr->digest));
812 * Verify the signature for the last restored file
813 * Return value is either true (signature correct)
814 * or false (signature could not be verified).
815 * TODO landonf: Implement without using find_one_file and
816 * without re-reading the file.
818 int verify_signature(JCR *jcr, SIGNATURE *sig)
820 X509_KEYPAIR *keypair;
821 DIGEST *digest = NULL;
823 uint64_t saved_bytes;
825 /* Iterate through the trusted signers */
826 foreach_alist(keypair, jcr->pki_signers) {
827 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
830 case CRYPTO_ERROR_NONE:
831 /* Signature found, digest allocated */
832 jcr->digest = digest;
834 /* Checksum the entire file */
835 /* Make sure we don't modify JobBytes by saving and restoring it */
836 saved_bytes = jcr->JobBytes;
837 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
838 Jmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
839 jcr->JobBytes = saved_bytes;
842 jcr->JobBytes = saved_bytes;
844 /* Verify the signature */
845 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
846 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
847 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
848 crypto_digest_free(digest);
852 /* Valid signature */
853 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
854 crypto_digest_free(digest);
857 case CRYPTO_ERROR_NOSIGNER:
858 /* Signature not found, try again */
861 /* Something strange happened (that shouldn't happen!)... */
862 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
864 crypto_digest_free(digest);
871 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
872 crypto_digest_free(digest);
876 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
881 unser_begin(*data, SPARSE_FADDR_SIZE);
883 if (*addr != faddr) {
885 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
887 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
888 edit_uint64(*addr, ec1), jcr->last_fname,
889 be.strerror(bfd->berrno));
893 *data += SPARSE_FADDR_SIZE;
894 *length -= SPARSE_FADDR_SIZE;
898 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
903 char ec1[50]; /* Buffer printing huge values */
906 * NOTE! We only use uLong and Byte because they are
907 * needed by the zlib routines, they should not otherwise
910 compress_len = jcr->compress_buf_size;
911 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
912 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
913 (const Byte *)*data, (uLong)*length)) != Z_OK) {
914 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
915 jcr->last_fname, zlib_strerror(stat));
918 *data = jcr->compress_buf;
919 *length = compress_len;
920 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
923 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
928 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
931 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
932 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
933 unser_uint32(ctx->packet_len);
934 ctx->packet_len += CRYPTO_LEN_SIZE;
938 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
941 if (!processWin32BackupAPIBlock(bfd, data, length)) {
943 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
944 jcr->last_fname, be.strerror(bfd->berrno));
947 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
949 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
950 jcr->last_fname, be.strerror(bfd->berrno));
958 * In the context of jcr, write data to bfd.
959 * We write buflen bytes in buf at addr. addr is updated in place.
960 * The flags specify whether to use sparse files or compression.
961 * Return value is the number of bytes written, or -1 on errors.
963 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
964 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
966 char *wbuf; /* write buffer */
967 uint32_t wsize; /* write size */
968 uint32_t rsize; /* read size */
969 uint32_t decrypted_len = 0; /* Decryption output length */
970 char ec1[50]; /* Buffer printing huge values */
973 jcr->ReadBytes += rsize;
977 if (flags & FO_ENCRYPT) {
978 ASSERT(cipher_ctx->cipher);
980 /* NOTE: We must implement block preserving semantics for the
981 * non-streaming compression and sparse code. */
984 * Grow the crypto buffer, if necessary.
985 * crypto_cipher_update() will process only whole blocks,
986 * buffering the remaining input.
988 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
989 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
991 /* Decrypt the input block */
992 if (!crypto_cipher_update(cipher_ctx->cipher,
993 (const u_int8_t *)wbuf,
995 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
997 /* Decryption failed. Shouldn't happen. */
998 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1002 if (decrypted_len == 0) {
1003 /* No full block of encrypted data available, write more data */
1007 Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1009 cipher_ctx->buf_len += decrypted_len;
1010 wbuf = cipher_ctx->buf;
1012 /* If one full preserved block is available, write it to disk,
1013 * and then buffer any remaining data. This should be effecient
1014 * as long as Bacula's block size is not significantly smaller than the
1015 * encryption block size (extremely unlikely!) */
1016 unser_crypto_packet_len(cipher_ctx);
1017 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1019 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1020 /* No full preserved block is available. */
1024 /* We have one full block, set up the filter input buffers */
1025 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1026 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1027 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1028 Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1031 if (flags & FO_SPARSE) {
1032 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1037 if (flags & FO_GZIP) {
1038 if (!decompress_data(jcr, &wbuf, &wsize)) {
1043 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1046 jcr->JobBytes += wsize;
1048 Dmsg2(30, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1050 /* Clean up crypto buffers */
1051 if (flags & FO_ENCRYPT) {
1052 /* Move any remaining data to start of buffer */
1053 if (cipher_ctx->buf_len > 0) {
1054 Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1055 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1056 cipher_ctx->buf_len);
1058 /* The packet was successfully written, reset the length so that the next
1059 * packet length may be re-read by unser_crypto_packet_len() */
1060 cipher_ctx->packet_len = 0;
1067 * In the context of jcr, flush any remaining data from the cipher context,
1068 * writing it to bfd.
1069 * Return value is true on success, false on failure.
1071 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1072 RESTORE_CIPHER_CTX *cipher_ctx)
1074 uint32_t decrypted_len;
1075 char *wbuf; /* write buffer */
1076 uint32_t wsize; /* write size */
1077 char ec1[50]; /* Buffer printing huge values */
1078 bool second_pass = false;
1081 /* Write out the remaining block and free the cipher context */
1082 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1083 cipher_ctx->block_size);
1085 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1087 /* Writing out the final, buffered block failed. Shouldn't happen. */
1088 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1089 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1092 Dmsg2(30, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1093 /* If nothing new was decrypted, and our output buffer is empty, return */
1094 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1098 cipher_ctx->buf_len += decrypted_len;
1100 unser_crypto_packet_len(cipher_ctx);
1101 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1102 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1103 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1104 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1105 Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1108 Dmsg2(30, "check buf_len=%d pkt_len=%d\n", cipher_ctx->buf_len, cipher_ctx->packet_len);
1109 if (second_pass && cipher_ctx->buf_len != cipher_ctx->packet_len) {
1110 Jmsg2(jcr, M_FATAL, 0,
1111 _("Unexpected number of bytes remaining at end of file, received %u, expected %u\n"),
1112 cipher_ctx->packet_len, cipher_ctx->buf_len);
1117 if (flags & FO_SPARSE) {
1118 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1123 if (flags & FO_GZIP) {
1124 if (!decompress_data(jcr, &wbuf, &wsize)) {
1129 Dmsg0(30, "Call store_data\n");
1130 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1133 jcr->JobBytes += wsize;
1134 Dmsg2(30, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1136 /* Move any remaining data to start of buffer */
1137 if (cipher_ctx->buf_len > 0) {
1138 Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1139 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1140 cipher_ctx->buf_len);
1142 /* The packet was successfully written, reset the length so that the next
1143 * packet length may be re-read by unser_crypto_packet_len() */
1144 cipher_ctx->packet_len = 0;
1146 if (cipher_ctx->buf_len >0 && !second_pass) {
1151 /* Stop decryption */
1152 cipher_ctx->buf_len = 0;
1153 cipher_ctx->packet_len = 0;