2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 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 and included
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 Kern Sibbald.
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
40 const bool have_darwin_os = true;
42 const bool have_darwin_os = false;
45 #if defined(HAVE_CRYPTO)
46 const bool have_crypto = true;
48 const bool have_crypto = false;
52 const bool have_acl = true;
54 const bool have_acl = false;
58 const bool have_sha2 = true;
60 const bool have_sha2 = false;
63 #if defined(HAVE_XATTR)
64 const bool have_xattr = true;
66 const bool have_xattr = false;
69 /* Data received from Storage Daemon */
70 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
72 typedef struct restore_cipher_ctx {
73 CIPHER_CONTEXT *cipher;
76 POOLMEM *buf; /* Pointer to descryption buffer */
77 int32_t buf_len; /* Count of bytes currently in buf */
78 int32_t packet_len; /* Total bytes in packet */
85 BFILE bfd; /* File content */
86 uint64_t fileAddr; /* file write address */
87 uint32_t size; /* Size of file */
88 int flags; /* Options for extract_data() */
89 BFILE forkbfd; /* Alternative data stream */
90 uint64_t fork_addr; /* Write address for alternative stream */
91 intmax_t fork_size; /* Size of alternate stream */
92 int fork_flags; /* Options for extract_data() */
93 int32_t type; /* file type FT_ */
94 ATTR *attr; /* Pointer to attributes */
95 bool extract; /* set when extracting */
97 SIGNATURE *sig; /* Cryptographic signature (if any) for file */
98 CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */
99 RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
100 RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
104 /* Forward referenced functions */
105 #if defined(HAVE_LIBZ)
106 static const char *zlib_strerror(int stat);
107 const bool have_libz = true;
109 const bool have_libz = false;
112 static void deallocate_cipher(r_ctx &rctx);
113 static void deallocate_fork_cipher(r_ctx &rctx);
114 static void free_signature(r_ctx &rctx);
115 static void free_session(r_ctx &rctx);
116 static void close_previous_stream(r_ctx &rctx);
120 static bool verify_signature(JCR *jcr, r_ctx &rctx);
121 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
122 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
123 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
124 RESTORE_CIPHER_CTX *cipher_ctx);
128 * Close a bfd check that we are at the expected file offset.
129 * Makes use of some code from set_attributes().
131 static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
133 char ec1[50], ec2[50];
136 fsize = blseek(bfd, 0, SEEK_CUR);
137 bclose(bfd); /* first close file */
138 if (fsize > 0 && fsize != osize) {
139 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
140 jcr->last_fname, edit_uint64(osize, ec1),
141 edit_uint64(fsize, ec2));
147 #ifdef HAVE_DARWIN_OS
148 bool restore_finderinfo(JCR *jcr, POOLMEM *buf, int32_t buflen)
150 struct attrlist attrList;
152 memset(&attrList, 0, sizeof(attrList));
153 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
154 attrList.commonattr = ATTR_CMN_FNDRINFO;
156 Dmsg0(130, "Restoring Finder Info\n");
157 jcr->ff->flags |= FO_HFSPLUS;
159 Jmsg(jcr, M_ERROR, 0, _("Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
163 if (setattrlist(jcr->last_fname, &attrList, buf, buflen, 0) != 0) {
164 Jmsg(jcr, M_ERROR, 0, _("Could not set Finder Info on %s\n"), jcr->last_fname);
171 bool restore_finderinfo(JCR *jcr, POOLMEM *buf, int32_t buflen)
178 * Restore the requested files.
181 void do_restore(JCR *jcr)
184 uint32_t VolSessionId, VolSessionTime;
186 char ec1[50]; /* Buffer printing huge values */
187 uint32_t buf_size; /* client buffer size */
189 intmax_t rsrc_len = 0; /* Original length of resource fork */
192 /* ***FIXME*** make configurable */
193 crypto_digest_t signing_algorithm = have_sha2 ?
194 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
195 memset(&rctx, 0, sizeof(rctx));
198 /* The following variables keep track of "known unknowns" */
199 int non_support_data = 0;
200 int non_support_attr = 0;
201 int non_support_rsrc = 0;
202 int non_support_finfo = 0;
203 int non_support_acl = 0;
204 int non_support_progname = 0;
205 int non_support_crypto = 0;
206 int non_support_xattr = 0;
208 sd = jcr->store_bsock;
209 set_jcr_job_status(jcr, JS_Running);
212 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
215 buf_size = client->max_network_buffer_size;
217 buf_size = 0; /* use default */
219 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
220 set_jcr_job_status(jcr, JS_ErrorTerminated);
223 jcr->buf_size = sd->msglen;
225 /* St Bernard code goes here if implemented -- see end of file */
228 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
229 jcr->compress_buf = get_memory(compress_buf_size);
230 jcr->compress_buf_size = compress_buf_size;
234 rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
235 if (have_darwin_os) {
236 rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
241 * Get a record from the Storage daemon. We are guaranteed to
242 * receive records in the following order:
243 * 1. Stream record header
244 * 2. Stream data (one or more of the following in the order given)
245 * a. Attributes (Unix or Win32)
246 * b. Possibly stream encryption session data (e.g., symmetric session key)
247 * c. File data for the file
248 * d. Alternate data stream (e.g. Resource Fork)
252 * h. Possibly a cryptographic signature
253 * i. Possibly MD5 or SHA1 record
256 * NOTE: We keep track of two bacula file descriptors:
257 * 1. bfd for file data.
258 * This fd is opened for non empty files when an attribute stream is
259 * encountered and closed when we find the next attribute stream.
260 * 2. fork_bfd for alternate data streams
261 * This fd is opened every time we encounter a new alternate data
262 * stream for the current file. When we find any other stream, we
264 * The expected size of the stream, fork_len, should be set when
266 * 3. Not all the stream data records are required -- e.g. if there
267 * is no fork, there is no alternate data stream, no ACL, ...
270 binit(&rctx.forkbfd);
271 attr = rctx.attr = new_attr(jcr);
273 jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
274 memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
275 jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
278 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
279 memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
280 jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
283 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
284 /* Remember previous stream type */
285 rctx.prev_stream = rctx.stream;
287 /* First we expect a Stream Record Header */
288 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
289 &rctx.stream, &rctx.size) != 5) {
290 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
293 Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
294 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
296 /* * Now we expect the Stream Data */
297 if (bget_msg(sd) < 0) {
298 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
301 if (rctx.size != (uint32_t)sd->msglen) {
302 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
303 sd->msglen, rctx.size);
304 Dmsg2(50, "Actual data size %d not same as header %d\n",
305 sd->msglen, rctx.size);
308 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
309 sd->msglen, rctx.extract);
311 /* If we change streams, close and reset alternate data streams */
312 if (rctx.prev_stream != rctx.stream) {
313 if (is_bopen(&rctx.forkbfd)) {
314 deallocate_fork_cipher(rctx);
315 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
317 rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
321 /* File Attributes stream */
322 switch (rctx.stream) {
323 case STREAM_UNIX_ATTRIBUTES:
324 case STREAM_UNIX_ATTRIBUTES_EX:
325 close_previous_stream(rctx); /* if any previous stream open, close it */
328 /* TODO: manage deleted files */
329 if (rctx.type == FT_DELETED) { /* deleted file */
334 * Unpack attributes and do sanity check them
336 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
340 if (file_index != attr->file_index) {
341 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
342 file_index, attr->file_index);
343 Dmsg0(200, "File index error\n");
348 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
349 attr->attr, attr->attrEx);
351 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
353 if (!is_restore_stream_supported(attr->data_stream)) {
354 if (!non_support_data++) {
355 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
356 stream_to_ascii(attr->data_stream));
361 build_attr_output_fnames(jcr, attr);
364 * Try to actually create the file, which returns a status telling
365 * us if we need to extract or not.
367 jcr->num_files_examined++;
368 rctx.extract = false;
370 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
372 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
375 pm_strcpy(jcr->last_fname, attr->ofname);
376 jcr->last_type = attr->type;
378 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
382 pm_strcpy(jcr->last_fname, attr->ofname);
383 jcr->last_type = attr->type;
385 case CF_EXTRACT: /* File created and we expect file data */
388 case CF_CREATED: /* File created, but there is no content */
390 print_ls_output(jcr, attr);
392 if (have_darwin_os) {
393 /* Only restore the resource fork for regular files */
394 from_base64(&rsrc_len, attr->attrEx);
395 if (attr->type == FT_REG && rsrc_len > 0) {
400 * Count the resource forks not as regular files being restored.
410 /* set attributes now because file will not be extracted */
412 plugin_set_attributes(jcr, attr, &rctx.bfd);
414 set_attributes(jcr, attr, &rctx.bfd);
422 case STREAM_ENCRYPTED_SESSION_DATA:
423 crypto_error_t cryptoerr;
425 /* Is this an unexpected session data entry? */
427 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
428 rctx.extract = false;
433 /* Do we have any keys at all? */
434 if (!jcr->crypto.pki_recipients) {
435 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
436 rctx.extract = false;
441 if (jcr->crypto.digest) {
442 crypto_digest_free(jcr->crypto.digest);
444 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
445 if (!jcr->crypto.digest) {
446 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
447 rctx.extract = false;
452 /* Decode and save session keys. */
453 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
454 jcr->crypto.pki_recipients, &rctx.cs);
456 case CRYPTO_ERROR_NONE:
459 case CRYPTO_ERROR_NORECIPIENT:
460 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
462 case CRYPTO_ERROR_DECRYPTION:
463 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
466 /* Shouldn't happen */
467 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
471 if (cryptoerr != CRYPTO_ERROR_NONE) {
472 rctx.extract = false;
479 case STREAM_FILE_DATA:
480 case STREAM_SPARSE_DATA:
481 case STREAM_WIN32_DATA:
482 case STREAM_GZIP_DATA:
483 case STREAM_SPARSE_GZIP_DATA:
484 case STREAM_WIN32_GZIP_DATA:
485 case STREAM_ENCRYPTED_FILE_DATA:
486 case STREAM_ENCRYPTED_WIN32_DATA:
487 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
488 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
489 /* Force an expected, consistent stream type here */
490 if (rctx.extract && (rctx.prev_stream == rctx.stream
491 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
492 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
493 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
496 if (rctx.stream == STREAM_SPARSE_DATA ||
497 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
498 rctx.flags |= FO_SPARSE;
501 if (rctx.stream == STREAM_GZIP_DATA
502 || rctx.stream == STREAM_SPARSE_GZIP_DATA
503 || rctx.stream == STREAM_WIN32_GZIP_DATA
504 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
505 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
506 rctx.flags |= FO_GZIP;
509 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
510 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
511 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
512 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
513 /* Set up a decryption context */
514 if (!rctx.cipher_ctx.cipher) {
516 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
517 rctx.extract = false;
522 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
523 &rctx.cipher_ctx.block_size)) == NULL) {
524 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
526 rctx.extract = false;
531 rctx.flags |= FO_ENCRYPT;
534 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
535 set_portable_backup(&rctx.bfd);
536 rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
539 if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr,
540 rctx.flags, &rctx.cipher_ctx) < 0) {
541 rctx.extract = false;
549 * Resource fork stream - only recorded after a file to be restored
550 * Silently ignore if we cannot write - we already reported that
552 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
553 case STREAM_MACOS_FORK_DATA:
554 if (have_darwin_os) {
556 jcr->ff->flags |= FO_HFSPLUS;
558 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
559 rctx.fork_flags |= FO_ENCRYPT;
561 /* Set up a decryption context */
562 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
564 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
565 rctx.extract = false;
570 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
571 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
573 rctx.extract = false;
581 if (rctx.prev_stream != rctx.stream) {
582 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
583 Jmsg(jcr, M_ERROR, 0, _("Cannot open resource fork for %s.\n"), jcr->last_fname);
584 rctx.extract = false;
588 rctx.fork_size = rsrc_len;
589 Dmsg0(130, "Restoring resource fork\n");
592 if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
593 &rctx.fork_cipher_ctx) < 0) {
594 rctx.extract = false;
595 bclose(&rctx.forkbfd);
604 case STREAM_HFSPLUS_ATTRIBUTES:
605 if (have_darwin_os) {
606 if (!restore_finderinfo(jcr, sd->msg, sd->msglen)) {
614 case STREAM_UNIX_ACCESS_ACL:
615 case STREAM_UNIX_DEFAULT_ACL:
616 case STREAM_ACL_AIX_TEXT:
617 case STREAM_ACL_DARWIN_ACCESS_ACL:
618 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
619 case STREAM_ACL_FREEBSD_ACCESS_ACL:
620 case STREAM_ACL_HPUX_ACL_ENTRY:
621 case STREAM_ACL_IRIX_DEFAULT_ACL:
622 case STREAM_ACL_IRIX_ACCESS_ACL:
623 case STREAM_ACL_LINUX_DEFAULT_ACL:
624 case STREAM_ACL_LINUX_ACCESS_ACL:
625 case STREAM_ACL_TRU64_DEFAULT_ACL:
626 case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
627 case STREAM_ACL_TRU64_ACCESS_ACL:
628 case STREAM_ACL_SOLARIS_ACLENT:
629 case STREAM_ACL_SOLARIS_ACE:
631 * Do not restore ACLs when
632 * a) The current file is not extracted
633 * b) and it is not a directory (they are never "extracted")
634 * c) or the file name is empty
636 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
640 pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen);
641 jcr->acl_data->content_length = sd->msglen;
642 switch (parse_acl_streams(jcr, rctx.stream)) {
643 case bacl_exit_fatal:
645 case bacl_exit_error:
647 * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
648 * print the error message set by the lower level routine in jcr->errmsg.
650 if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
651 Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
653 jcr->acl_data->nr_errors++;
663 case STREAM_XATTR_SOLARIS_SYS:
664 case STREAM_XATTR_SOLARIS:
665 case STREAM_XATTR_DARWIN:
666 case STREAM_XATTR_FREEBSD:
667 case STREAM_XATTR_LINUX:
668 case STREAM_XATTR_NETBSD:
670 * Do not restore Extended Attributes when
671 * a) The current file is not extracted
672 * b) and it is not a directory (they are never "extracted")
673 * c) or the file name is empty
675 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
679 pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen);
680 jcr->xattr_data->content_length = sd->msglen;
681 switch (parse_xattr_streams(jcr, rctx.stream)) {
682 case bxattr_exit_fatal:
684 case bxattr_exit_error:
686 * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
687 * print the error message set by the lower level routine in jcr->errmsg.
689 if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
690 Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
692 jcr->xattr_data->nr_errors++;
702 case STREAM_SIGNED_DIGEST:
703 /* Is this an unexpected signature? */
705 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
706 free_signature(rctx);
709 /* Save signature. */
710 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
711 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
715 case STREAM_MD5_DIGEST:
716 case STREAM_SHA1_DIGEST:
717 case STREAM_SHA256_DIGEST:
718 case STREAM_SHA512_DIGEST:
721 case STREAM_PROGRAM_NAMES:
722 case STREAM_PROGRAM_DATA:
723 if (!non_support_progname) {
724 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
725 non_support_progname++;
729 case STREAM_PLUGIN_NAME:
730 close_previous_stream(rctx);
731 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
732 plugin_name_stream(jcr, sd->msg);
736 close_previous_stream(rctx);
737 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
739 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
741 } /* end switch(stream) */
743 } /* end while get_msg() */
746 * If output file is still open, it was the last one in the
747 * archive since we just hit an end of file, so close the file.
749 if (is_bopen(&rctx.forkbfd)) {
750 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
753 close_previous_stream(rctx);
754 set_jcr_job_status(jcr, JS_Terminated);
758 set_jcr_job_status(jcr, JS_ErrorTerminated);
762 * First output the statistics.
764 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
765 edit_uint64(jcr->JobBytes, ec1));
766 if (have_acl && jcr->acl_data->nr_errors > 0) {
767 Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing restore\n"),
768 jcr->acl_data->nr_errors);
770 if (have_xattr && jcr->xattr_data->nr_errors > 0) {
771 Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing restore\n"),
772 jcr->xattr_data->nr_errors);
774 if (non_support_data > 1 || non_support_attr > 1) {
775 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
776 non_support_data, non_support_attr);
778 if (non_support_rsrc) {
779 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
781 if (non_support_finfo) {
782 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
784 if (non_support_acl) {
785 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
787 if (non_support_crypto) {
788 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
790 if (non_support_xattr) {
791 Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
795 * Free Signature & Crypto Data
797 free_signature(rctx);
799 if (jcr->crypto.digest) {
800 crypto_digest_free(jcr->crypto.digest);
801 jcr->crypto.digest = NULL;
805 * Free file cipher restore context
807 if (rctx.cipher_ctx.cipher) {
808 crypto_cipher_free(rctx.cipher_ctx.cipher);
809 rctx.cipher_ctx.cipher = NULL;
812 if (rctx.cipher_ctx.buf) {
813 free_pool_memory(rctx.cipher_ctx.buf);
814 rctx.cipher_ctx.buf = NULL;
818 * Free alternate stream cipher restore context
820 if (rctx.fork_cipher_ctx.cipher) {
821 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
822 rctx.fork_cipher_ctx.cipher = NULL;
824 if (rctx.fork_cipher_ctx.buf) {
825 free_pool_memory(rctx.fork_cipher_ctx.buf);
826 rctx.fork_cipher_ctx.buf = NULL;
829 if (jcr->compress_buf) {
830 free_pool_memory(jcr->compress_buf);
831 jcr->compress_buf = NULL;
832 jcr->compress_buf_size = 0;
835 if (have_acl && jcr->acl_data) {
836 free_pool_memory(jcr->acl_data->content);
838 jcr->acl_data = NULL;
841 if (have_xattr && jcr->xattr_data) {
842 free_pool_memory(jcr->xattr_data->content);
843 free(jcr->xattr_data);
844 jcr->xattr_data = NULL;
847 bclose(&rctx.forkbfd);
849 free_attr(rctx.attr);
854 * Convert ZLIB error code into an ASCII message
856 static const char *zlib_strerror(int stat)
863 return _("Zlib errno");
865 return _("Zlib stream error");
867 return _("Zlib data error");
869 return _("Zlib memory error");
871 return _("Zlib buffer error");
872 case Z_VERSION_ERROR:
873 return _("Zlib version error");
880 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
882 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
883 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
887 * Verify the signature for the last restored file
888 * Return value is either true (signature correct)
889 * or false (signature could not be verified).
890 * TODO landonf: Implement without using find_one_file and
891 * without re-reading the file.
893 static bool verify_signature(JCR *jcr, r_ctx &rctx)
895 X509_KEYPAIR *keypair;
896 DIGEST *digest = NULL;
898 uint64_t saved_bytes;
899 crypto_digest_t signing_algorithm = have_sha2 ?
900 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
901 crypto_digest_t algorithm;
902 SIGNATURE *sig = rctx.sig;
905 if (!jcr->crypto.pki_sign) {
906 return true; /* no signature OK */
909 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
910 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
917 /* Iterate through the trusted signers */
918 foreach_alist(keypair, jcr->crypto.pki_signers) {
919 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
921 case CRYPTO_ERROR_NONE:
922 Dmsg0(50, "== Got digest\n");
924 * We computed jcr->crypto.digest using signing_algorithm while writing
925 * the file. If it is not the same as the algorithm used for
926 * this file, punt by releasing the computed algorithm and
927 * computing by re-reading the file.
929 if (algorithm != signing_algorithm) {
930 if (jcr->crypto.digest) {
931 crypto_digest_free(jcr->crypto.digest);
932 jcr->crypto.digest = NULL;
935 if (jcr->crypto.digest) {
936 /* Use digest computed while writing the file to verify the signature */
937 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
938 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
939 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
940 jcr->last_fname, crypto_strerror(err));
944 /* Signature found, digest allocated. Old method,
945 * re-read the file and compute the digest
947 jcr->crypto.digest = digest;
949 /* Checksum the entire file */
950 /* Make sure we don't modify JobBytes by saving and restoring it */
951 saved_bytes = jcr->JobBytes;
952 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
953 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
955 jcr->JobBytes = saved_bytes;
958 jcr->JobBytes = saved_bytes;
960 /* Verify the signature */
961 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
962 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
963 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
964 jcr->last_fname, crypto_strerror(err));
967 jcr->crypto.digest = NULL;
970 /* Valid signature */
971 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
972 crypto_digest_free(digest);
975 case CRYPTO_ERROR_NOSIGNER:
976 /* Signature not found, try again */
978 crypto_digest_free(digest);
983 /* Something strange happened (that shouldn't happen!)... */
984 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
990 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
994 crypto_digest_free(digest);
999 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
1004 unser_begin(*data, SPARSE_FADDR_SIZE);
1005 unser_uint64(faddr);
1006 if (*addr != faddr) {
1008 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
1010 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
1011 edit_uint64(*addr, ec1), jcr->last_fname,
1012 be.bstrerror(bfd->berrno));
1016 *data += SPARSE_FADDR_SIZE;
1017 *length -= SPARSE_FADDR_SIZE;
1021 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
1026 char ec1[50]; /* Buffer printing huge values */
1029 * NOTE! We only use uLong and Byte because they are
1030 * needed by the zlib routines, they should not otherwise
1031 * be used in Bacula.
1033 compress_len = jcr->compress_buf_size;
1034 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1035 while ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
1036 (const Byte *)*data, (uLong)*length)) == Z_BUF_ERROR)
1038 /* The buffer size is too small, try with a bigger one */
1039 compress_len = jcr->compress_buf_size = jcr->compress_buf_size + jcr->compress_buf_size >> 1;
1040 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1041 jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
1045 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
1046 jcr->last_fname, zlib_strerror(stat));
1049 *data = jcr->compress_buf;
1050 *length = compress_len;
1051 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
1054 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
1059 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
1062 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
1063 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
1064 unser_uint32(ctx->packet_len);
1065 ctx->packet_len += CRYPTO_LEN_SIZE;
1069 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
1071 if (jcr->crypto.digest) {
1072 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
1075 if (!processWin32BackupAPIBlock(bfd, data, length)) {
1077 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
1078 jcr->last_fname, be.bstrerror(bfd->berrno));
1081 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
1083 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
1084 jcr->last_fname, be.bstrerror(bfd->berrno));
1092 * In the context of jcr, write data to bfd.
1093 * We write buflen bytes in buf at addr. addr is updated in place.
1094 * The flags specify whether to use sparse files or compression.
1095 * Return value is the number of bytes written, or -1 on errors.
1097 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
1098 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1100 char *wbuf; /* write buffer */
1101 uint32_t wsize; /* write size */
1102 uint32_t rsize; /* read size */
1103 uint32_t decrypted_len = 0; /* Decryption output length */
1104 char ec1[50]; /* Buffer printing huge values */
1107 jcr->ReadBytes += rsize;
1111 if (flags & FO_ENCRYPT) {
1112 ASSERT(cipher_ctx->cipher);
1114 /* NOTE: We must implement block preserving semantics for the
1115 * non-streaming compression and sparse code. */
1118 * Grow the crypto buffer, if necessary.
1119 * crypto_cipher_update() will process only whole blocks,
1120 * buffering the remaining input.
1122 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
1123 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1125 /* Decrypt the input block */
1126 if (!crypto_cipher_update(cipher_ctx->cipher,
1127 (const u_int8_t *)wbuf,
1129 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1131 /* Decryption failed. Shouldn't happen. */
1132 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1136 if (decrypted_len == 0) {
1137 /* No full block of encrypted data available, write more data */
1141 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1143 cipher_ctx->buf_len += decrypted_len;
1144 wbuf = cipher_ctx->buf;
1146 /* If one full preserved block is available, write it to disk,
1147 * and then buffer any remaining data. This should be effecient
1148 * as long as Bacula's block size is not significantly smaller than the
1149 * encryption block size (extremely unlikely!) */
1150 unser_crypto_packet_len(cipher_ctx);
1151 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1153 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1154 /* No full preserved block is available. */
1158 /* We have one full block, set up the filter input buffers */
1159 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1160 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1161 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1162 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1165 if (flags & FO_SPARSE) {
1166 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1171 if (flags & FO_GZIP) {
1172 if (!decompress_data(jcr, &wbuf, &wsize)) {
1177 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1180 jcr->JobBytes += wsize;
1182 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1184 /* Clean up crypto buffers */
1185 if (flags & FO_ENCRYPT) {
1186 /* Move any remaining data to start of buffer */
1187 if (cipher_ctx->buf_len > 0) {
1188 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1189 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1190 cipher_ctx->buf_len);
1192 /* The packet was successfully written, reset the length so that the next
1193 * packet length may be re-read by unser_crypto_packet_len() */
1194 cipher_ctx->packet_len = 0;
1204 * If extracting, close any previous stream
1206 static void close_previous_stream(r_ctx &rctx)
1209 * If extracting, it was from previous stream, so
1210 * close the output file and validate the signature.
1213 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1214 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1215 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1216 is_bopen(&rctx.bfd));
1219 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1220 deallocate_cipher(rctx);
1221 deallocate_fork_cipher(rctx);
1224 if (rctx.jcr->plugin) {
1225 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1227 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1229 rctx.extract = false;
1231 /* Verify the cryptographic signature, if any */
1232 rctx.type = rctx.attr->type;
1233 verify_signature(rctx.jcr, rctx);
1235 /* Free Signature */
1236 free_signature(rctx);
1238 rctx.jcr->ff->flags = 0;
1239 Dmsg0(130, "Stop extracting.\n");
1240 } else if (is_bopen(&rctx.bfd)) {
1241 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1242 Dmsg0(000, "=== logic error !open\n");
1249 * In the context of jcr, flush any remaining data from the cipher context,
1250 * writing it to bfd.
1251 * Return value is true on success, false on failure.
1253 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1254 RESTORE_CIPHER_CTX *cipher_ctx)
1256 uint32_t decrypted_len = 0;
1257 char *wbuf; /* write buffer */
1258 uint32_t wsize; /* write size */
1259 char ec1[50]; /* Buffer printing huge values */
1260 bool second_pass = false;
1263 /* Write out the remaining block and free the cipher context */
1264 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1265 cipher_ctx->block_size);
1267 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1269 /* Writing out the final, buffered block failed. Shouldn't happen. */
1270 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1271 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1274 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1275 /* If nothing new was decrypted, and our output buffer is empty, return */
1276 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1280 cipher_ctx->buf_len += decrypted_len;
1282 unser_crypto_packet_len(cipher_ctx);
1283 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1284 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1285 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1286 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1287 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1289 if (flags & FO_SPARSE) {
1290 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1295 if (flags & FO_GZIP) {
1296 if (!decompress_data(jcr, &wbuf, &wsize)) {
1301 Dmsg0(130, "Call store_data\n");
1302 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1305 jcr->JobBytes += wsize;
1306 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1308 /* Move any remaining data to start of buffer */
1309 if (cipher_ctx->buf_len > 0) {
1310 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1311 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1312 cipher_ctx->buf_len);
1314 /* The packet was successfully written, reset the length so that the next
1315 * packet length may be re-read by unser_crypto_packet_len() */
1316 cipher_ctx->packet_len = 0;
1318 if (cipher_ctx->buf_len >0 && !second_pass) {
1323 /* Stop decryption */
1324 cipher_ctx->buf_len = 0;
1325 cipher_ctx->packet_len = 0;
1330 static void deallocate_cipher(r_ctx &rctx)
1332 /* Flush and deallocate previous stream's cipher context */
1333 if (rctx.cipher_ctx.cipher) {
1334 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1335 crypto_cipher_free(rctx.cipher_ctx.cipher);
1336 rctx.cipher_ctx.cipher = NULL;
1340 static void deallocate_fork_cipher(r_ctx &rctx)
1343 /* Flush and deallocate previous stream's fork cipher context */
1344 if (rctx.fork_cipher_ctx.cipher) {
1345 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1346 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1347 rctx.fork_cipher_ctx.cipher = NULL;
1351 static void free_signature(r_ctx &rctx)
1354 crypto_sign_free(rctx.sig);
1359 static void free_session(r_ctx &rctx)
1362 crypto_session_free(rctx.cs);
1368 /* This code if implemented goes above */
1369 #ifdef stbernard_implemented
1370 / #if defined(HAVE_WIN32)
1371 bool bResumeOfmOnExit = FALSE;
1372 if (isOpenFileManagerRunning()) {
1373 if ( pauseOpenFileManager() ) {
1374 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1375 bResumeOfmOnExit = TRUE;
1378 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1382 char username[UNLEN+1];
1383 DWORD usize = sizeof(username);
1384 int privs = enable_backup_privileges(NULL, 1);
1385 if (GetUserName(username, &usize)) {
1386 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1388 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));