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));
149 * Restore the requested files.
152 void do_restore(JCR *jcr)
155 uint32_t VolSessionId, VolSessionTime;
157 char ec1[50]; /* Buffer printing huge values */
158 uint32_t buf_size; /* client buffer size */
160 intmax_t rsrc_len = 0; /* Original length of resource fork */
163 /* ***FIXME*** make configurable */
164 crypto_digest_t signing_algorithm = have_sha2 ?
165 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
166 memset(&rctx, 0, sizeof(rctx));
169 /* The following variables keep track of "known unknowns" */
170 int non_support_data = 0;
171 int non_support_attr = 0;
172 int non_support_rsrc = 0;
173 int non_support_finfo = 0;
174 int non_support_acl = 0;
175 int non_support_progname = 0;
176 int non_support_crypto = 0;
177 int non_support_xattr = 0;
179 #ifdef HAVE_DARWIN_OS
180 struct attrlist attrList;
181 memset(&attrList, 0, sizeof(attrList));
182 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
183 attrList.commonattr = ATTR_CMN_FNDRINFO;
187 sd = jcr->store_bsock;
188 set_jcr_job_status(jcr, JS_Running);
191 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
194 buf_size = client->max_network_buffer_size;
196 buf_size = 0; /* use default */
198 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
199 set_jcr_job_status(jcr, JS_ErrorTerminated);
202 jcr->buf_size = sd->msglen;
204 /* St Bernard code goes here if implemented -- see end of file */
207 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
208 jcr->compress_buf = get_memory(compress_buf_size);
209 jcr->compress_buf_size = compress_buf_size;
213 rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
214 if (have_darwin_os) {
215 rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
220 * Get a record from the Storage daemon. We are guaranteed to
221 * receive records in the following order:
222 * 1. Stream record header
223 * 2. Stream data (one or more of the following in the order given)
224 * a. Attributes (Unix or Win32)
225 * b. Possibly stream encryption session data (e.g., symmetric session key)
226 * c. File data for the file
227 * d. Alternate data stream (e.g. Resource Fork)
231 * h. Possibly a cryptographic signature
232 * i. Possibly MD5 or SHA1 record
235 * NOTE: We keep track of two bacula file descriptors:
236 * 1. bfd for file data.
237 * This fd is opened for non empty files when an attribute stream is
238 * encountered and closed when we find the next attribute stream.
239 * 2. fork_bfd for alternate data streams
240 * This fd is opened every time we encounter a new alternate data
241 * stream for the current file. When we find any other stream, we
243 * The expected size of the stream, fork_len, should be set when
245 * 3. Not all the stream data records are required -- e.g. if there
246 * is no fork, there is no alternate data stream, no ACL, ...
249 binit(&rctx.forkbfd);
250 attr = rctx.attr = new_attr(jcr);
252 jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
253 memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
254 jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
257 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
258 memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
259 jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
262 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
263 /* Remember previous stream type */
264 rctx.prev_stream = rctx.stream;
266 /* First we expect a Stream Record Header */
267 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
268 &rctx.stream, &rctx.size) != 5) {
269 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
272 Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
273 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
275 /* * Now we expect the Stream Data */
276 if (bget_msg(sd) < 0) {
277 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
280 if (rctx.size != (uint32_t)sd->msglen) {
281 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
282 sd->msglen, rctx.size);
283 Dmsg2(50, "Actual data size %d not same as header %d\n",
284 sd->msglen, rctx.size);
287 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
288 sd->msglen, rctx.extract);
290 /* If we change streams, close and reset alternate data streams */
291 if (rctx.prev_stream != rctx.stream) {
292 if (is_bopen(&rctx.forkbfd)) {
293 deallocate_fork_cipher(rctx);
294 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
296 rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
300 /* File Attributes stream */
301 switch (rctx.stream) {
302 case STREAM_UNIX_ATTRIBUTES:
303 case STREAM_UNIX_ATTRIBUTES_EX:
304 close_previous_stream(rctx); /* if any previous stream open, close it */
307 /* TODO: manage deleted files */
308 if (rctx.type == FT_DELETED) { /* deleted file */
313 * Unpack attributes and do sanity check them
315 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
319 if (file_index != attr->file_index) {
320 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
321 file_index, attr->file_index);
322 Dmsg0(200, "File index error\n");
327 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
328 attr->attr, attr->attrEx);
330 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
332 if (!is_restore_stream_supported(attr->data_stream)) {
333 if (!non_support_data++) {
334 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
335 stream_to_ascii(attr->data_stream));
340 build_attr_output_fnames(jcr, attr);
343 * Try to actually create the file, which returns a status telling
344 * us if we need to extract or not.
346 jcr->num_files_examined++;
347 rctx.extract = false;
349 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
351 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
354 pm_strcpy(jcr->last_fname, attr->ofname);
355 jcr->last_type = attr->type;
357 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
361 pm_strcpy(jcr->last_fname, attr->ofname);
362 jcr->last_type = attr->type;
364 case CF_EXTRACT: /* File created and we expect file data */
367 case CF_CREATED: /* File created, but there is no content */
369 print_ls_output(jcr, attr);
371 if (have_darwin_os) {
372 /* Only restore the resource fork for regular files */
373 from_base64(&rsrc_len, attr->attrEx);
374 if (attr->type == FT_REG && rsrc_len > 0) {
379 * Count the resource forks not as regular files being restored.
389 /* set attributes now because file will not be extracted */
391 plugin_set_attributes(jcr, attr, &rctx.bfd);
393 set_attributes(jcr, attr, &rctx.bfd);
401 case STREAM_ENCRYPTED_SESSION_DATA:
402 crypto_error_t cryptoerr;
404 /* Is this an unexpected session data entry? */
406 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
407 rctx.extract = false;
412 /* Do we have any keys at all? */
413 if (!jcr->crypto.pki_recipients) {
414 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
415 rctx.extract = false;
420 if (jcr->crypto.digest) {
421 crypto_digest_free(jcr->crypto.digest);
423 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
424 if (!jcr->crypto.digest) {
425 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
426 rctx.extract = false;
431 /* Decode and save session keys. */
432 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
433 jcr->crypto.pki_recipients, &rctx.cs);
435 case CRYPTO_ERROR_NONE:
438 case CRYPTO_ERROR_NORECIPIENT:
439 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
441 case CRYPTO_ERROR_DECRYPTION:
442 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
445 /* Shouldn't happen */
446 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
450 if (cryptoerr != CRYPTO_ERROR_NONE) {
451 rctx.extract = false;
458 case STREAM_FILE_DATA:
459 case STREAM_SPARSE_DATA:
460 case STREAM_WIN32_DATA:
461 case STREAM_GZIP_DATA:
462 case STREAM_SPARSE_GZIP_DATA:
463 case STREAM_WIN32_GZIP_DATA:
464 case STREAM_ENCRYPTED_FILE_DATA:
465 case STREAM_ENCRYPTED_WIN32_DATA:
466 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
467 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
468 /* Force an expected, consistent stream type here */
469 if (rctx.extract && (rctx.prev_stream == rctx.stream
470 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
471 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
472 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
475 if (rctx.stream == STREAM_SPARSE_DATA ||
476 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
477 rctx.flags |= FO_SPARSE;
480 if (rctx.stream == STREAM_GZIP_DATA
481 || rctx.stream == STREAM_SPARSE_GZIP_DATA
482 || rctx.stream == STREAM_WIN32_GZIP_DATA
483 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
484 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
485 rctx.flags |= FO_GZIP;
488 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
489 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
490 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
491 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
492 /* Set up a decryption context */
493 if (!rctx.cipher_ctx.cipher) {
495 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
496 rctx.extract = false;
501 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
502 &rctx.cipher_ctx.block_size)) == NULL) {
503 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
505 rctx.extract = false;
510 rctx.flags |= FO_ENCRYPT;
513 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
514 set_portable_backup(&rctx.bfd);
515 rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
518 if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr,
519 rctx.flags, &rctx.cipher_ctx) < 0) {
520 rctx.extract = false;
528 * Resource fork stream - only recorded after a file to be restored
529 * Silently ignore if we cannot write - we already reported that
531 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
532 case STREAM_MACOS_FORK_DATA:
533 if (have_darwin_os) {
535 jcr->ff->flags |= FO_HFSPLUS;
537 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
538 rctx.fork_flags |= FO_ENCRYPT;
540 /* Set up a decryption context */
541 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
543 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
544 rctx.extract = false;
549 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
550 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
552 rctx.extract = false;
560 if (rctx.prev_stream != rctx.stream) {
561 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
562 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
563 rctx.extract = false;
567 rctx.fork_size = rsrc_len;
568 Dmsg0(130, "Restoring resource fork\n");
571 if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
572 &rctx.fork_cipher_ctx) < 0) {
573 rctx.extract = false;
574 bclose(&rctx.forkbfd);
583 case STREAM_HFSPLUS_ATTRIBUTES:
584 if (have_darwin_os) {
585 Dmsg0(130, "Restoring Finder Info\n");
586 jcr->ff->flags |= FO_HFSPLUS;
587 if (sd->msglen != 32) {
588 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
591 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
592 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
600 case STREAM_UNIX_ACCESS_ACL:
601 case STREAM_UNIX_DEFAULT_ACL:
602 case STREAM_ACL_AIX_TEXT:
603 case STREAM_ACL_DARWIN_ACCESS_ACL:
604 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
605 case STREAM_ACL_FREEBSD_ACCESS_ACL:
606 case STREAM_ACL_HPUX_ACL_ENTRY:
607 case STREAM_ACL_IRIX_DEFAULT_ACL:
608 case STREAM_ACL_IRIX_ACCESS_ACL:
609 case STREAM_ACL_LINUX_DEFAULT_ACL:
610 case STREAM_ACL_LINUX_ACCESS_ACL:
611 case STREAM_ACL_TRU64_DEFAULT_ACL:
612 case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
613 case STREAM_ACL_TRU64_ACCESS_ACL:
614 case STREAM_ACL_SOLARIS_ACLENT:
615 case STREAM_ACL_SOLARIS_ACE:
617 * Do not restore ACLs when
618 * a) The current file is not extracted
619 * b) and it is not a directory (they are never "extracted")
620 * c) or the file name is empty
622 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
626 pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen);
627 jcr->acl_data->content_length = sd->msglen;
628 switch (parse_acl_streams(jcr, rctx.stream)) {
629 case bacl_exit_fatal:
631 case bacl_exit_error:
633 * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
634 * print the error message set by the lower level routine in jcr->errmsg.
636 if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
637 Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
639 jcr->acl_data->nr_errors++;
649 case STREAM_XATTR_SOLARIS_SYS:
650 case STREAM_XATTR_SOLARIS:
651 case STREAM_XATTR_DARWIN:
652 case STREAM_XATTR_FREEBSD:
653 case STREAM_XATTR_LINUX:
654 case STREAM_XATTR_NETBSD:
656 * Do not restore Extended Attributes when
657 * a) The current file is not extracted
658 * b) and it is not a directory (they are never "extracted")
659 * c) or the file name is empty
661 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
665 pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen);
666 jcr->xattr_data->content_length = sd->msglen;
667 switch (parse_xattr_streams(jcr, rctx.stream)) {
668 case bxattr_exit_fatal:
670 case bxattr_exit_error:
672 * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
673 * print the error message set by the lower level routine in jcr->errmsg.
675 if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
676 Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
678 jcr->xattr_data->nr_errors++;
688 case STREAM_SIGNED_DIGEST:
689 /* Is this an unexpected signature? */
691 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
692 free_signature(rctx);
695 /* Save signature. */
696 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
697 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
701 case STREAM_MD5_DIGEST:
702 case STREAM_SHA1_DIGEST:
703 case STREAM_SHA256_DIGEST:
704 case STREAM_SHA512_DIGEST:
707 case STREAM_PROGRAM_NAMES:
708 case STREAM_PROGRAM_DATA:
709 if (!non_support_progname) {
710 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
711 non_support_progname++;
715 case STREAM_PLUGIN_NAME:
716 close_previous_stream(rctx);
717 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
718 plugin_name_stream(jcr, sd->msg);
722 close_previous_stream(rctx);
723 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
725 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
727 } /* end switch(stream) */
729 } /* end while get_msg() */
732 * If output file is still open, it was the last one in the
733 * archive since we just hit an end of file, so close the file.
735 if (is_bopen(&rctx.forkbfd)) {
736 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
739 close_previous_stream(rctx);
740 set_jcr_job_status(jcr, JS_Terminated);
744 set_jcr_job_status(jcr, JS_ErrorTerminated);
748 * First output the statistics.
750 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
751 edit_uint64(jcr->JobBytes, ec1));
752 if (have_acl && jcr->acl_data->nr_errors > 0) {
753 Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing restore\n"),
754 jcr->acl_data->nr_errors);
756 if (have_xattr && jcr->xattr_data->nr_errors > 0) {
757 Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing restore\n"),
758 jcr->xattr_data->nr_errors);
760 if (non_support_data > 1 || non_support_attr > 1) {
761 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
762 non_support_data, non_support_attr);
764 if (non_support_rsrc) {
765 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
767 if (non_support_finfo) {
768 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
770 if (non_support_acl) {
771 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
773 if (non_support_crypto) {
774 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
776 if (non_support_xattr) {
777 Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
781 * Free Signature & Crypto Data
783 free_signature(rctx);
785 if (jcr->crypto.digest) {
786 crypto_digest_free(jcr->crypto.digest);
787 jcr->crypto.digest = NULL;
791 * Free file cipher restore context
793 if (rctx.cipher_ctx.cipher) {
794 crypto_cipher_free(rctx.cipher_ctx.cipher);
795 rctx.cipher_ctx.cipher = NULL;
798 if (rctx.cipher_ctx.buf) {
799 free_pool_memory(rctx.cipher_ctx.buf);
800 rctx.cipher_ctx.buf = NULL;
804 * Free alternate stream cipher restore context
806 if (rctx.fork_cipher_ctx.cipher) {
807 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
808 rctx.fork_cipher_ctx.cipher = NULL;
810 if (rctx.fork_cipher_ctx.buf) {
811 free_pool_memory(rctx.fork_cipher_ctx.buf);
812 rctx.fork_cipher_ctx.buf = NULL;
815 if (jcr->compress_buf) {
816 free_pool_memory(jcr->compress_buf);
817 jcr->compress_buf = NULL;
818 jcr->compress_buf_size = 0;
821 if (have_acl && jcr->acl_data) {
822 free_pool_memory(jcr->acl_data->content);
824 jcr->acl_data = NULL;
827 if (have_xattr && jcr->xattr_data) {
828 free_pool_memory(jcr->xattr_data->content);
829 free(jcr->xattr_data);
830 jcr->xattr_data = NULL;
833 bclose(&rctx.forkbfd);
835 free_attr(rctx.attr);
840 * Convert ZLIB error code into an ASCII message
842 static const char *zlib_strerror(int stat)
849 return _("Zlib errno");
851 return _("Zlib stream error");
853 return _("Zlib data error");
855 return _("Zlib memory error");
857 return _("Zlib buffer error");
858 case Z_VERSION_ERROR:
859 return _("Zlib version error");
866 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
868 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
869 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
873 * Verify the signature for the last restored file
874 * Return value is either true (signature correct)
875 * or false (signature could not be verified).
876 * TODO landonf: Implement without using find_one_file and
877 * without re-reading the file.
879 static bool verify_signature(JCR *jcr, r_ctx &rctx)
881 X509_KEYPAIR *keypair;
882 DIGEST *digest = NULL;
884 uint64_t saved_bytes;
885 crypto_digest_t signing_algorithm = have_sha2 ?
886 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
887 crypto_digest_t algorithm;
888 SIGNATURE *sig = rctx.sig;
891 if (!jcr->crypto.pki_sign) {
892 return true; /* no signature OK */
895 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
896 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
903 /* Iterate through the trusted signers */
904 foreach_alist(keypair, jcr->crypto.pki_signers) {
905 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
907 case CRYPTO_ERROR_NONE:
908 Dmsg0(50, "== Got digest\n");
910 * We computed jcr->crypto.digest using signing_algorithm while writing
911 * the file. If it is not the same as the algorithm used for
912 * this file, punt by releasing the computed algorithm and
913 * computing by re-reading the file.
915 if (algorithm != signing_algorithm) {
916 if (jcr->crypto.digest) {
917 crypto_digest_free(jcr->crypto.digest);
918 jcr->crypto.digest = NULL;
921 if (jcr->crypto.digest) {
922 /* Use digest computed while writing the file to verify the signature */
923 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
924 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
925 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
926 jcr->last_fname, crypto_strerror(err));
930 /* Signature found, digest allocated. Old method,
931 * re-read the file and compute the digest
933 jcr->crypto.digest = digest;
935 /* Checksum the entire file */
936 /* Make sure we don't modify JobBytes by saving and restoring it */
937 saved_bytes = jcr->JobBytes;
938 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
939 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
941 jcr->JobBytes = saved_bytes;
944 jcr->JobBytes = saved_bytes;
946 /* Verify the signature */
947 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
948 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
949 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
950 jcr->last_fname, crypto_strerror(err));
953 jcr->crypto.digest = NULL;
956 /* Valid signature */
957 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
958 crypto_digest_free(digest);
961 case CRYPTO_ERROR_NOSIGNER:
962 /* Signature not found, try again */
964 crypto_digest_free(digest);
969 /* Something strange happened (that shouldn't happen!)... */
970 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
976 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
980 crypto_digest_free(digest);
985 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
990 unser_begin(*data, SPARSE_FADDR_SIZE);
992 if (*addr != faddr) {
994 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
996 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
997 edit_uint64(*addr, ec1), jcr->last_fname,
998 be.bstrerror(bfd->berrno));
1002 *data += SPARSE_FADDR_SIZE;
1003 *length -= SPARSE_FADDR_SIZE;
1007 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
1012 char ec1[50]; /* Buffer printing huge values */
1015 * NOTE! We only use uLong and Byte because they are
1016 * needed by the zlib routines, they should not otherwise
1017 * be used in Bacula.
1019 compress_len = jcr->compress_buf_size;
1020 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1021 while ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
1022 (const Byte *)*data, (uLong)*length)) == Z_BUF_ERROR)
1024 /* The buffer size is too small, try with a bigger one */
1025 compress_len = jcr->compress_buf_size = jcr->compress_buf_size + jcr->compress_buf_size >> 1;
1026 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1027 jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
1031 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
1032 jcr->last_fname, zlib_strerror(stat));
1035 *data = jcr->compress_buf;
1036 *length = compress_len;
1037 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
1040 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
1045 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
1048 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
1049 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
1050 unser_uint32(ctx->packet_len);
1051 ctx->packet_len += CRYPTO_LEN_SIZE;
1055 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
1057 if (jcr->crypto.digest) {
1058 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
1061 if (!processWin32BackupAPIBlock(bfd, data, length)) {
1063 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
1064 jcr->last_fname, be.bstrerror(bfd->berrno));
1067 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
1069 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
1070 jcr->last_fname, be.bstrerror(bfd->berrno));
1078 * In the context of jcr, write data to bfd.
1079 * We write buflen bytes in buf at addr. addr is updated in place.
1080 * The flags specify whether to use sparse files or compression.
1081 * Return value is the number of bytes written, or -1 on errors.
1083 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
1084 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1086 char *wbuf; /* write buffer */
1087 uint32_t wsize; /* write size */
1088 uint32_t rsize; /* read size */
1089 uint32_t decrypted_len = 0; /* Decryption output length */
1090 char ec1[50]; /* Buffer printing huge values */
1093 jcr->ReadBytes += rsize;
1097 if (flags & FO_ENCRYPT) {
1098 ASSERT(cipher_ctx->cipher);
1100 /* NOTE: We must implement block preserving semantics for the
1101 * non-streaming compression and sparse code. */
1104 * Grow the crypto buffer, if necessary.
1105 * crypto_cipher_update() will process only whole blocks,
1106 * buffering the remaining input.
1108 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
1109 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1111 /* Decrypt the input block */
1112 if (!crypto_cipher_update(cipher_ctx->cipher,
1113 (const u_int8_t *)wbuf,
1115 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1117 /* Decryption failed. Shouldn't happen. */
1118 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1122 if (decrypted_len == 0) {
1123 /* No full block of encrypted data available, write more data */
1127 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1129 cipher_ctx->buf_len += decrypted_len;
1130 wbuf = cipher_ctx->buf;
1132 /* If one full preserved block is available, write it to disk,
1133 * and then buffer any remaining data. This should be effecient
1134 * as long as Bacula's block size is not significantly smaller than the
1135 * encryption block size (extremely unlikely!) */
1136 unser_crypto_packet_len(cipher_ctx);
1137 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1139 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1140 /* No full preserved block is available. */
1144 /* We have one full block, set up the filter input buffers */
1145 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1146 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1147 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1148 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1151 if (flags & FO_SPARSE) {
1152 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1157 if (flags & FO_GZIP) {
1158 if (!decompress_data(jcr, &wbuf, &wsize)) {
1163 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1166 jcr->JobBytes += wsize;
1168 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1170 /* Clean up crypto buffers */
1171 if (flags & FO_ENCRYPT) {
1172 /* Move any remaining data to start of buffer */
1173 if (cipher_ctx->buf_len > 0) {
1174 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1175 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1176 cipher_ctx->buf_len);
1178 /* The packet was successfully written, reset the length so that the next
1179 * packet length may be re-read by unser_crypto_packet_len() */
1180 cipher_ctx->packet_len = 0;
1190 * If extracting, close any previous stream
1192 static void close_previous_stream(r_ctx &rctx)
1195 * If extracting, it was from previous stream, so
1196 * close the output file and validate the signature.
1199 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1200 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1201 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1202 is_bopen(&rctx.bfd));
1205 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1206 deallocate_cipher(rctx);
1207 deallocate_fork_cipher(rctx);
1210 if (rctx.jcr->plugin) {
1211 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1213 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1215 rctx.extract = false;
1217 /* Verify the cryptographic signature, if any */
1218 rctx.type = rctx.attr->type;
1219 verify_signature(rctx.jcr, rctx);
1221 /* Free Signature */
1222 free_signature(rctx);
1224 rctx.jcr->ff->flags = 0;
1225 Dmsg0(130, "Stop extracting.\n");
1226 } else if (is_bopen(&rctx.bfd)) {
1227 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1228 Dmsg0(000, "=== logic error !open\n");
1235 * In the context of jcr, flush any remaining data from the cipher context,
1236 * writing it to bfd.
1237 * Return value is true on success, false on failure.
1239 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1240 RESTORE_CIPHER_CTX *cipher_ctx)
1242 uint32_t decrypted_len = 0;
1243 char *wbuf; /* write buffer */
1244 uint32_t wsize; /* write size */
1245 char ec1[50]; /* Buffer printing huge values */
1246 bool second_pass = false;
1249 /* Write out the remaining block and free the cipher context */
1250 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1251 cipher_ctx->block_size);
1253 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1255 /* Writing out the final, buffered block failed. Shouldn't happen. */
1256 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1257 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1260 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1261 /* If nothing new was decrypted, and our output buffer is empty, return */
1262 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1266 cipher_ctx->buf_len += decrypted_len;
1268 unser_crypto_packet_len(cipher_ctx);
1269 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1270 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1271 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1272 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1273 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1275 if (flags & FO_SPARSE) {
1276 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1281 if (flags & FO_GZIP) {
1282 if (!decompress_data(jcr, &wbuf, &wsize)) {
1287 Dmsg0(130, "Call store_data\n");
1288 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1291 jcr->JobBytes += wsize;
1292 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1294 /* Move any remaining data to start of buffer */
1295 if (cipher_ctx->buf_len > 0) {
1296 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1297 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1298 cipher_ctx->buf_len);
1300 /* The packet was successfully written, reset the length so that the next
1301 * packet length may be re-read by unser_crypto_packet_len() */
1302 cipher_ctx->packet_len = 0;
1304 if (cipher_ctx->buf_len >0 && !second_pass) {
1309 /* Stop decryption */
1310 cipher_ctx->buf_len = 0;
1311 cipher_ctx->packet_len = 0;
1316 static void deallocate_cipher(r_ctx &rctx)
1318 /* Flush and deallocate previous stream's cipher context */
1319 if (rctx.cipher_ctx.cipher) {
1320 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1321 crypto_cipher_free(rctx.cipher_ctx.cipher);
1322 rctx.cipher_ctx.cipher = NULL;
1326 static void deallocate_fork_cipher(r_ctx &rctx)
1329 /* Flush and deallocate previous stream's fork cipher context */
1330 if (rctx.fork_cipher_ctx.cipher) {
1331 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1332 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1333 rctx.fork_cipher_ctx.cipher = NULL;
1337 static void free_signature(r_ctx &rctx)
1340 crypto_sign_free(rctx.sig);
1345 static void free_session(r_ctx &rctx)
1348 crypto_session_free(rctx.cs);
1354 /* This code if implemented goes above */
1355 #ifdef stbernard_implemented
1356 / #if defined(HAVE_WIN32)
1357 bool bResumeOfmOnExit = FALSE;
1358 if (isOpenFileManagerRunning()) {
1359 if ( pauseOpenFileManager() ) {
1360 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1361 bResumeOfmOnExit = TRUE;
1364 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1368 char username[UNLEN+1];
1369 DWORD usize = sizeof(username);
1370 int privs = enable_backup_privileges(NULL, 1);
1371 if (GetUserName(username, &usize)) {
1372 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1374 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));