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 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;
192 cipher_ctx.cipher = NULL;
193 cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
194 cipher_ctx.buf_len = 0;
195 cipher_ctx.packet_len = 0;
197 cipher_ctx.cipher = NULL;
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;
204 * Get a record from the Storage daemon. We are guaranteed to
205 * receive records in the following order:
206 * 1. Stream record header
208 * a. Attributes (Unix or Win32)
209 * b. Possibly stream encryption session data (e.g., symmetric session key)
210 * or c. File data for the file
211 * or d. Alternate data stream (e.g. Resource Fork)
214 * or g. Possibly a cryptographic signature
215 * or h. Possibly MD5 or SHA1 record
218 * NOTE: We keep track of two bacula file descriptors:
219 * 1. bfd for file data.
220 * This fd is opened for non empty files when an attribute stream is
221 * encountered and closed when we find the next attribute stream.
222 * 2. alt_bfd for alternate data streams
223 * This fd is opened every time we encounter a new alternate data
224 * stream for the current file. When we find any other stream, we
226 * The expected size of the stream, alt_len, should be set when
232 jcr->acl_text = get_pool_memory(PM_MESSAGE);
234 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
235 /* Remember previous stream type */
236 prev_stream = stream;
238 /* First we expect a Stream Record Header */
239 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
240 &stream, &size) != 5) {
241 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
244 Dmsg4(30, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n",
245 jcr->JobFiles, file_index, stream, stream_to_ascii(stream));
247 /* * Now we expect the Stream Data */
248 if (bget_msg(sd) < 0) {
249 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
252 if (size != (uint32_t)sd->msglen) {
253 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
256 Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(stream),
257 sd->msglen, extract);
259 /* If we change streams, close and reset alternate data streams */
260 if (prev_stream != stream) {
261 if (is_bopen(&altbfd)) {
262 if (alt_cipher_ctx.cipher) {
263 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
264 crypto_cipher_free(alt_cipher_ctx.cipher);
265 alt_cipher_ctx.cipher = NULL;
267 bclose_chksize(jcr, &altbfd, alt_size);
269 alt_size = -1; /* Use an impossible value and set a proper one below */
273 /* File Attributes stream */
275 case STREAM_UNIX_ATTRIBUTES:
276 case STREAM_UNIX_ATTRIBUTES_EX:
278 * If extracting, it was from previous stream, so
279 * close the output file and validate the signature.
282 if (size > 0 && !is_bopen(&bfd)) {
283 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
285 /* Flush and deallocate previous stream's cipher context */
286 if (cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
287 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
288 crypto_cipher_free(cipher_ctx.cipher);
289 cipher_ctx.cipher = NULL;
292 /* Flush and deallocate previous stream's alt cipher context */
293 if (alt_cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
294 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
295 crypto_cipher_free(alt_cipher_ctx.cipher);
296 alt_cipher_ctx.cipher = NULL;
298 set_attributes(jcr, attr, &bfd);
301 /* Verify the cryptographic signature, if any */
304 // Failure is reported in verify_signature() ...
305 verify_signature(jcr, sig);
307 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
312 crypto_sign_free(sig);
316 crypto_session_free(cs);
320 Dmsg0(30, "Stop extracting.\n");
321 } else if (is_bopen(&bfd)) {
322 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
327 * Unpack and do sanity check fo attributes.
329 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
332 if (file_index != attr->file_index) {
333 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
334 file_index, attr->file_index);
335 Dmsg0(100, "File index error\n");
339 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
340 attr->attr, attr->attrEx);
342 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
344 if (!is_restore_stream_supported(attr->data_stream)) {
345 if (!non_support_data++) {
346 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
347 stream_to_ascii(attr->data_stream));
352 build_attr_output_fnames(jcr, attr);
355 * Now determine if we are extracting or not.
357 jcr->num_files_examined++;
358 Dmsg1(30, "Outfile=%s\n", attr->ofname);
360 stat = create_file(jcr, attr, &bfd, jcr->replace);
365 case CF_EXTRACT: /* File created and we expect file data */
368 case CF_CREATED: /* File created, but there is no content */
370 pm_strcpy(jcr->last_fname, attr->ofname);
371 jcr->last_type = attr->type;
375 print_ls_output(jcr, attr);
376 #ifdef HAVE_DARWIN_OS
377 /* Only restore the resource fork for regular files */
378 from_base64(&rsrc_len, attr->attrEx);
379 if (attr->type == FT_REG && rsrc_len > 0) {
384 /* set attributes now because file will not be extracted */
385 set_attributes(jcr, attr, &bfd);
392 case STREAM_ENCRYPTED_SESSION_DATA:
393 crypto_error_t cryptoerr;
395 /* Do we have any keys at all? */
396 if (!jcr->pki_recipients) {
397 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
403 /* Decode and save session keys. */
404 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
406 case CRYPTO_ERROR_NONE:
409 case CRYPTO_ERROR_NORECIPIENT:
410 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
412 case CRYPTO_ERROR_DECRYPTION:
413 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
416 /* Shouldn't happen */
417 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
421 if (cryptoerr != CRYPTO_ERROR_NONE) {
427 /* Set up a decryption context */
428 if ((cipher_ctx.cipher = crypto_cipher_new(cs, false, &cipher_ctx.block_size)) == NULL) {
429 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
430 crypto_session_free(cs);
439 case STREAM_FILE_DATA:
440 case STREAM_SPARSE_DATA:
441 case STREAM_WIN32_DATA:
442 case STREAM_GZIP_DATA:
443 case STREAM_SPARSE_GZIP_DATA:
444 case STREAM_WIN32_GZIP_DATA:
445 case STREAM_ENCRYPTED_FILE_DATA:
446 case STREAM_ENCRYPTED_WIN32_DATA:
447 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
448 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
449 /* Force an expected, consistent stream type here */
450 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
451 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
452 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
455 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
459 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
460 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
461 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
465 if (stream == STREAM_ENCRYPTED_FILE_DATA
466 || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
467 || stream == STREAM_ENCRYPTED_WIN32_DATA
468 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
472 if (is_win32_stream(stream) && !have_win32_api()) {
473 set_portable_backup(&bfd);
474 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
477 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags,
486 /* Resource fork stream - only recorded after a file to be restored */
487 /* Silently ignore if we cannot write - we already reported that */
488 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
489 case STREAM_MACOS_FORK_DATA:
490 #ifdef HAVE_DARWIN_OS
492 jcr->ff->flags |= FO_HFSPLUS;
494 if (stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
495 alt_flags |= FO_ENCRYPT;
497 /* Set up a decryption context */
498 if (!alt_cipher_ctx.cipher) {
499 if ((alt_cipher_ctx.cipher = crypto_cipher_new(cs, false, &alt_cipher_ctx.block_size)) == NULL) {
500 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
501 crypto_session_free(cs);
510 if (prev_stream != stream) {
511 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
512 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
518 Dmsg0(30, "Restoring resource fork\n");
521 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, alt_flags,
522 &alt_cipher_ctx) < 0) {
533 case STREAM_HFSPLUS_ATTRIBUTES:
534 #ifdef HAVE_DARWIN_OS
535 Dmsg0(30, "Restoring Finder Info\n");
536 jcr->ff->flags |= FO_HFSPLUS;
537 if (sd->msglen != 32) {
538 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
541 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
542 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
550 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
552 pm_strcpy(jcr->acl_text, sd->msg);
553 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
554 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
555 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
562 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
564 pm_strcpy(jcr->acl_text, sd->msg);
565 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
566 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
567 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
574 case STREAM_SIGNED_DIGEST:
575 /* Save signature. */
576 if (extract && (sig = crypto_sign_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
577 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
581 case STREAM_MD5_DIGEST:
582 case STREAM_SHA1_DIGEST:
583 case STREAM_SHA256_DIGEST:
584 case STREAM_SHA512_DIGEST:
587 case STREAM_PROGRAM_NAMES:
588 case STREAM_PROGRAM_DATA:
589 if (!non_support_progname) {
590 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
591 non_support_progname++;
596 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
598 Dmsg1(30, "Found wierd stream %d\n", stream);
599 if (size > 0 && !is_bopen(&bfd)) {
600 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
602 /* Flush and deallocate cipher context */
603 if (cipher_ctx.cipher) {
604 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
605 crypto_cipher_free(cipher_ctx.cipher);
606 cipher_ctx.cipher = NULL;
609 /* Flush and deallocate alt cipher context */
610 if (alt_cipher_ctx.cipher) {
611 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
612 crypto_cipher_free(alt_cipher_ctx.cipher);
613 alt_cipher_ctx.cipher = NULL;
616 set_attributes(jcr, attr, &bfd);
618 /* Verify the cryptographic signature if any */
621 // Failure is reported in verify_signature() ...
622 verify_signature(jcr, sig);
624 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
629 } else if (is_bopen(&bfd)) {
630 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
633 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
634 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
636 } /* end switch(stream) */
638 } /* end while get_msg() */
640 /* If output file is still open, it was the last one in the
641 * archive since we just hit an end of file, so close the file.
643 if (is_bopen(&altbfd)) {
644 bclose_chksize(jcr, &altbfd, alt_size);
647 /* Flush and deallocate cipher context */
648 if (cipher_ctx.cipher) {
649 flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
650 crypto_cipher_free(cipher_ctx.cipher);
651 cipher_ctx.cipher = NULL;
654 /* Flush and deallocate alt cipher context */
655 if (alt_cipher_ctx.cipher) {
656 flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
657 crypto_cipher_free(alt_cipher_ctx.cipher);
658 alt_cipher_ctx.cipher = NULL;
661 set_attributes(jcr, attr, &bfd);
663 /* Verify the cryptographic signature on the last file, if any */
666 // Failure is reported in verify_signature() ...
667 verify_signature(jcr, sig);
669 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
674 if (is_bopen(&bfd)) {
678 set_jcr_job_status(jcr, JS_Terminated);
682 set_jcr_job_status(jcr, JS_ErrorTerminated);
685 /* Free Signature & Crypto Data */
687 crypto_sign_free(sig);
691 crypto_session_free(cs);
695 /* Free file cipher restore context */
696 if (cipher_ctx.cipher) {
697 crypto_cipher_free(cipher_ctx.cipher);
698 cipher_ctx.cipher = NULL;
700 if (cipher_ctx.buf) {
701 free_pool_memory(cipher_ctx.buf);
702 cipher_ctx.buf = NULL;
705 /* Free alternate stream cipher restore context */
706 if (alt_cipher_ctx.cipher) {
707 crypto_cipher_free(alt_cipher_ctx.cipher);
708 alt_cipher_ctx.cipher = NULL;
710 if (alt_cipher_ctx.buf) {
711 free_pool_memory(alt_cipher_ctx.buf);
712 alt_cipher_ctx.buf = NULL;
715 if (jcr->compress_buf) {
716 free(jcr->compress_buf);
717 jcr->compress_buf = NULL;
718 jcr->compress_buf_size = 0;
723 free_pool_memory(jcr->acl_text);
724 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
725 edit_uint64(jcr->JobBytes, ec1));
726 if (non_support_data > 1 || non_support_attr > 1) {
727 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
728 non_support_data, non_support_attr);
730 if (non_support_rsrc) {
731 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
733 if (non_support_finfo) {
734 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
736 if (non_support_acl) {
737 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
743 * Convert ZLIB error code into an ASCII message
745 static const char *zlib_strerror(int stat)
752 return _("Zlib errno");
754 return _("Zlib stream error");
756 return _("Zlib data error");
758 return _("Zlib memory error");
760 return _("Zlib buffer error");
761 case Z_VERSION_ERROR:
762 return _("Zlib version error");
768 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level)
770 JCR *jcr = (JCR *)pkt;
771 return (digest_file(jcr, ff_pkt, jcr->digest));
775 * Verify the signature for the last restored file
776 * Return value is either true (signature correct)
777 * or false (signature could not be verified).
778 * TODO landonf: Better signature failure handling.
780 int verify_signature(JCR *jcr, SIGNATURE *sig)
782 X509_KEYPAIR *keypair;
783 DIGEST *digest = NULL;
786 /* Iterate through the trusted signers */
787 foreach_alist(keypair, jcr->pki_signers) {
788 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
791 case CRYPTO_ERROR_NONE:
792 /* Signature found, digest allocated */
793 jcr->digest = digest;
795 /* Checksum the entire file */
796 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
797 Jmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
801 /* Verify the signature */
802 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
803 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
804 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
805 crypto_digest_free(digest);
809 /* Valid signature */
810 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
811 crypto_digest_free(digest);
814 case CRYPTO_ERROR_NOSIGNER:
815 /* Signature not found, try again */
818 /* Something strange happened (that shouldn't happen!)... */
819 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
821 crypto_digest_free(digest);
828 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
829 crypto_digest_free(digest);
833 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
838 unser_begin(*data, SPARSE_FADDR_SIZE);
840 if (*addr != faddr) {
842 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
844 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
845 edit_uint64(*addr, ec1), jcr->last_fname,
846 be.strerror(bfd->berrno));
850 *data += SPARSE_FADDR_SIZE;
851 *length -= SPARSE_FADDR_SIZE;
855 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
860 char ec1[50]; /* Buffer printing huge values */
863 * NOTE! We only use uLong and Byte because they are
864 * needed by the zlib routines, they should not otherwise
867 compress_len = jcr->compress_buf_size;
868 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
869 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
870 (const Byte *)*data, (uLong)*length)) != Z_OK) {
871 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
872 jcr->last_fname, zlib_strerror(stat));
875 *data = jcr->compress_buf;
876 *length = compress_len;
877 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
880 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
885 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
888 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
889 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
890 unser_uint32(ctx->packet_len);
891 ctx->packet_len += CRYPTO_LEN_SIZE;
895 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
898 if (!processWin32BackupAPIBlock(bfd, data, length)) {
900 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
901 jcr->last_fname, be.strerror(bfd->berrno));
904 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
906 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
907 jcr->last_fname, be.strerror(bfd->berrno));
915 * In the context of jcr, write data to bfd.
916 * We write buflen bytes in buf at addr. addr is updated in place.
917 * The flags specify whether to use sparse files or compression.
918 * Return value is the number of bytes written, or -1 on errors.
920 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
921 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
923 char *wbuf; /* write buffer */
924 uint32_t wsize; /* write size */
925 uint32_t rsize; /* read size */
926 uint32_t decrypted_len = 0; /* Decryption output length */
927 char ec1[50]; /* Buffer printing huge values */
930 jcr->ReadBytes += rsize;
934 if (flags & FO_ENCRYPT) {
935 ASSERT(cipher_ctx->cipher);
937 /* NOTE: We must implement block preserving semantics for the
938 * non-streaming compression and sparse code. */
941 * Grow the crypto buffer, if necessary.
942 * crypto_cipher_update() will process only whole blocks,
943 * buffering the remaining input.
945 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
946 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
948 /* Decrypt the input block */
949 if (!crypto_cipher_update(cipher_ctx->cipher,
950 (const u_int8_t *)wbuf,
952 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
954 /* Decryption failed. Shouldn't happen. */
955 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
959 if (decrypted_len == 0) {
960 /* No full block of encrypted data available, write more data */
964 Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
966 cipher_ctx->buf_len += decrypted_len;
967 wbuf = cipher_ctx->buf;
969 /* If one full preserved block is available, write it to disk,
970 * and then buffer any remaining data. This should be effecient
971 * as long as Bacula's block size is not significantly smaller than the
972 * encryption block size (extremely unlikely!) */
973 unser_crypto_packet_len(cipher_ctx);
974 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
976 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
977 /* No full preserved block is available. */
981 /* We have one full block, set up the filter input buffers */
982 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
983 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
984 cipher_ctx->buf_len -= cipher_ctx->packet_len;
985 Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
988 if (flags & FO_SPARSE) {
989 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
994 if (flags & FO_GZIP) {
995 if (!decompress_data(jcr, &wbuf, &wsize)) {
999 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1002 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1006 jcr->JobBytes += wsize;
1009 /* Clean up crypto buffers */
1010 if (flags & FO_ENCRYPT) {
1011 /* Move any remaining data to start of buffer */
1012 if (cipher_ctx->buf_len > 0) {
1013 Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1014 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1015 cipher_ctx->buf_len);
1017 /* The packet was successfully written, reset the length so that the next
1018 * packet length may be re-read by unser_crypto_packet_len() */
1019 cipher_ctx->packet_len = 0;
1026 * In the context of jcr, flush any remaining data from the cipher context,
1027 * writing it to bfd.
1028 * Return value is true on success, false on failure.
1030 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1031 RESTORE_CIPHER_CTX *cipher_ctx)
1033 uint32_t decrypted_len;
1034 char *wbuf; /* write buffer */
1035 uint32_t wsize; /* write size */
1036 char ec1[50]; /* Buffer printing huge values */
1038 /* Write out the remaining block and free the cipher context */
1039 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1040 cipher_ctx->block_size);
1042 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1044 /* Writing out the final, buffered block failed. Shouldn't happen. */
1045 Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
1048 /* If nothing new was decrypted, and our output buffer is empty, return */
1049 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1053 cipher_ctx->buf_len += decrypted_len;
1055 unser_crypto_packet_len(cipher_ctx);
1056 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1057 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1058 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1060 if (cipher_ctx->buf_len != cipher_ctx->packet_len) {
1061 Jmsg2(jcr, M_FATAL, 0,
1062 _("Unexpected number of bytes remaining at end of file, received %u, expected %u\n"),
1063 cipher_ctx->packet_len, cipher_ctx->buf_len);
1067 cipher_ctx->buf_len = 0;
1068 cipher_ctx->packet_len = 0;
1070 if (flags & FO_SPARSE) {
1071 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1076 if (flags & FO_GZIP) {
1077 decompress_data(jcr, &wbuf, &wsize);
1079 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1082 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1086 jcr->JobBytes += wsize;