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
42 const bool have_darwin_os = true;
44 const bool have_darwin_os = false;
47 #if defined(HAVE_CRYPTO)
48 const bool have_crypto = true;
50 const bool have_crypto = false;
54 const bool have_acl = true;
56 const bool have_acl = false;
60 const bool have_sha2 = true;
62 const bool have_sha2 = false;
65 #if defined(HAVE_XATTR)
66 const bool have_xattr = true;
68 const bool have_xattr = false;
71 /* Data received from Storage Daemon */
72 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
74 typedef struct restore_cipher_ctx {
75 CIPHER_CONTEXT *cipher;
78 POOLMEM *buf; /* Pointer to descryption buffer */
79 int32_t buf_len; /* Count of bytes currently in buf */
80 int32_t packet_len; /* Total bytes in packet */
87 BFILE bfd; /* File content */
88 uint64_t fileAddr; /* file write address */
89 uint32_t size; /* Size of file */
90 int flags; /* Options for extract_data() */
91 BFILE forkbfd; /* Alternative data stream */
92 uint64_t fork_addr; /* Write address for alternative stream */
93 intmax_t fork_size; /* Size of alternate stream */
94 int fork_flags; /* Options for extract_data() */
95 int32_t type; /* file type FT_ */
96 ATTR *attr; /* Pointer to attributes */
97 bool extract; /* set when extracting */
99 SIGNATURE *sig; /* Cryptographic signature (if any) for file */
100 CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */
101 RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
102 RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
106 /* Forward referenced functions */
107 #if defined(HAVE_LIBZ)
108 static const char *zlib_strerror(int stat);
109 const bool have_libz = true;
111 const bool have_libz = false;
114 static void deallocate_cipher(r_ctx &rctx);
115 static void deallocate_fork_cipher(r_ctx &rctx);
116 static void free_signature(r_ctx &rctx);
117 static void free_session(r_ctx &rctx);
118 static void close_previous_stream(r_ctx &rctx);
122 static bool verify_signature(JCR *jcr, r_ctx &rctx);
123 int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
124 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
125 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
126 RESTORE_CIPHER_CTX *cipher_ctx);
130 * Close a bfd check that we are at the expected file offset.
131 * Makes use of some code from set_attributes().
133 static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
135 char ec1[50], ec2[50];
138 fsize = blseek(bfd, 0, SEEK_CUR);
139 bclose(bfd); /* first close file */
140 if (fsize > 0 && fsize != osize) {
141 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
142 jcr->last_fname, edit_uint64(osize, ec1),
143 edit_uint64(fsize, ec2));
151 * Restore the requested files.
154 void do_restore(JCR *jcr)
157 uint32_t VolSessionId, VolSessionTime;
159 char ec1[50]; /* Buffer printing huge values */
160 uint32_t buf_size; /* client buffer size */
162 intmax_t rsrc_len = 0; /* Original length of resource fork */
165 /* ***FIXME*** make configurable */
166 crypto_digest_t signing_algorithm = have_sha2 ?
167 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
168 memset(&rctx, 0, sizeof(rctx));
171 /* The following variables keep track of "known unknowns" */
172 int non_support_data = 0;
173 int non_support_attr = 0;
174 int non_support_rsrc = 0;
175 int non_support_finfo = 0;
176 int non_support_acl = 0;
177 int non_support_progname = 0;
178 int non_support_crypto = 0;
179 int non_support_xattr = 0;
181 #ifdef HAVE_DARWIN_OS
182 struct attrlist attrList;
183 memset(&attrList, 0, sizeof(attrList));
184 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
185 attrList.commonattr = ATTR_CMN_FNDRINFO;
189 sd = jcr->store_bsock;
190 set_jcr_job_status(jcr, JS_Running);
193 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
196 buf_size = client->max_network_buffer_size;
198 buf_size = 0; /* use default */
200 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
201 set_jcr_job_status(jcr, JS_ErrorTerminated);
204 jcr->buf_size = sd->msglen;
206 /* St Bernard code goes here if implemented -- see end of file */
209 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
210 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
211 jcr->compress_buf_size = compress_buf_size;
215 rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
216 if (have_darwin_os) {
217 rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
222 * Get a record from the Storage daemon. We are guaranteed to
223 * receive records in the following order:
224 * 1. Stream record header
225 * 2. Stream data (one or more of the following in the order given)
226 * a. Attributes (Unix or Win32)
227 * b. Possibly stream encryption session data (e.g., symmetric session key)
228 * c. File data for the file
229 * d. Alternate data stream (e.g. Resource Fork)
233 * h. Possibly a cryptographic signature
234 * i. Possibly MD5 or SHA1 record
237 * NOTE: We keep track of two bacula file descriptors:
238 * 1. bfd for file data.
239 * This fd is opened for non empty files when an attribute stream is
240 * encountered and closed when we find the next attribute stream.
241 * 2. fork_bfd for alternate data streams
242 * This fd is opened every time we encounter a new alternate data
243 * stream for the current file. When we find any other stream, we
245 * The expected size of the stream, fork_len, should be set when
247 * 3. Not all the stream data records are required -- e.g. if there
248 * is no fork, there is no alternate data stream, no ACL, ...
251 binit(&rctx.forkbfd);
252 attr = rctx.attr = new_attr(jcr);
253 jcr->acl_data = get_pool_memory(PM_MESSAGE);
254 jcr->xattr_data = get_pool_memory(PM_MESSAGE);
256 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
257 /* Remember previous stream type */
258 rctx.prev_stream = rctx.stream;
260 /* First we expect a Stream Record Header */
261 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
262 &rctx.stream, &rctx.size) != 5) {
263 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
266 Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
267 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
269 /* * Now we expect the Stream Data */
270 if (bget_msg(sd) < 0) {
271 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
274 if (rctx.size != (uint32_t)sd->msglen) {
275 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
276 sd->msglen, rctx.size);
277 Dmsg2(50, "Actual data size %d not same as header %d\n",
278 sd->msglen, rctx.size);
281 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
282 sd->msglen, rctx.extract);
284 /* If we change streams, close and reset alternate data streams */
285 if (rctx.prev_stream != rctx.stream) {
286 if (is_bopen(&rctx.forkbfd)) {
287 deallocate_fork_cipher(rctx);
288 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
290 rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
294 /* File Attributes stream */
295 switch (rctx.stream) {
296 case STREAM_UNIX_ATTRIBUTES:
297 case STREAM_UNIX_ATTRIBUTES_EX:
298 close_previous_stream(rctx); /* if any previous stream open, close it */
301 /* TODO: manage deleted files */
302 if (rctx.type == FT_DELETED) { /* deleted file */
307 * Unpack attributes and do sanity check them
309 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
313 if (file_index != attr->file_index) {
314 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
315 file_index, attr->file_index);
316 Dmsg0(200, "File index error\n");
321 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
322 attr->attr, attr->attrEx);
324 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
326 if (!is_restore_stream_supported(attr->data_stream)) {
327 if (!non_support_data++) {
328 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
329 stream_to_ascii(attr->data_stream));
334 build_attr_output_fnames(jcr, attr);
337 * Try to actually create the file, which returns a status telling
338 * us if we need to extract or not.
340 jcr->num_files_examined++;
341 rctx.extract = false;
343 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
345 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
348 pm_strcpy(jcr->last_fname, attr->ofname);
349 jcr->last_type = attr->type;
351 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
355 pm_strcpy(jcr->last_fname, attr->ofname);
356 jcr->last_type = attr->type;
358 case CF_EXTRACT: /* File created and we expect file data */
361 case CF_CREATED: /* File created, but there is no content */
364 print_ls_output(jcr, attr);
366 if (have_darwin_os) {
367 /* Only restore the resource fork for regular files */
368 from_base64(&rsrc_len, attr->attrEx);
369 if (attr->type == FT_REG && rsrc_len > 0) {
374 /* set attributes now because file will not be extracted */
376 plugin_set_attributes(jcr, attr, &rctx.bfd);
378 set_attributes(jcr, attr, &rctx.bfd);
386 case STREAM_ENCRYPTED_SESSION_DATA:
387 crypto_error_t cryptoerr;
389 /* Is this an unexpected session data entry? */
391 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
392 rctx.extract = false;
397 /* Do we have any keys at all? */
398 if (!jcr->crypto.pki_recipients) {
399 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
400 rctx.extract = false;
405 if (jcr->crypto.digest) {
406 crypto_digest_free(jcr->crypto.digest);
408 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
409 if (!jcr->crypto.digest) {
410 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
411 rctx.extract = false;
416 /* Decode and save session keys. */
417 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
418 jcr->crypto.pki_recipients, &rctx.cs);
420 case CRYPTO_ERROR_NONE:
423 case CRYPTO_ERROR_NORECIPIENT:
424 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
426 case CRYPTO_ERROR_DECRYPTION:
427 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
430 /* Shouldn't happen */
431 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
435 if (cryptoerr != CRYPTO_ERROR_NONE) {
436 rctx.extract = false;
443 case STREAM_FILE_DATA:
444 case STREAM_SPARSE_DATA:
445 case STREAM_WIN32_DATA:
446 case STREAM_GZIP_DATA:
447 case STREAM_SPARSE_GZIP_DATA:
448 case STREAM_WIN32_GZIP_DATA:
449 case STREAM_ENCRYPTED_FILE_DATA:
450 case STREAM_ENCRYPTED_WIN32_DATA:
451 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
452 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
453 /* Force an expected, consistent stream type here */
454 if (rctx.extract && (rctx.prev_stream == rctx.stream
455 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
456 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
457 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
460 if (rctx.stream == STREAM_SPARSE_DATA ||
461 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
462 rctx.flags |= FO_SPARSE;
465 if (rctx.stream == STREAM_GZIP_DATA
466 || rctx.stream == STREAM_SPARSE_GZIP_DATA
467 || rctx.stream == STREAM_WIN32_GZIP_DATA
468 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
469 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
470 rctx.flags |= FO_GZIP;
473 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
474 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
475 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
476 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
477 /* Set up a decryption context */
478 if (!rctx.cipher_ctx.cipher) {
480 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
481 rctx.extract = false;
486 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
487 &rctx.cipher_ctx.block_size)) == NULL) {
488 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
490 rctx.extract = false;
495 rctx.flags |= FO_ENCRYPT;
498 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
499 set_portable_backup(&rctx.bfd);
500 rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
503 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr,
504 rctx.flags, &rctx.cipher_ctx) < 0) {
511 /* Resource fork stream - only recorded after a file to be restored */
512 /* Silently ignore if we cannot write - we already reported that */
513 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
514 case STREAM_MACOS_FORK_DATA:
515 #ifdef HAVE_DARWIN_OS
517 jcr->ff->flags |= FO_HFSPLUS;
519 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
520 rctx.fork_flags |= FO_ENCRYPT;
522 /* Set up a decryption context */
523 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
525 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
526 rctx.extract = false;
531 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
532 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
534 rctx.extract = false;
542 if (rctx.prev_stream != rctx.stream) {
543 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
544 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
545 rctx.extract = false;
549 rctx.fork_size = rsrc_len;
550 Dmsg0(130, "Restoring resource fork\n");
553 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
554 &rctx.fork_cipher_ctx) < 0) {
555 bclose(&rctx.forkbfd);
564 case STREAM_HFSPLUS_ATTRIBUTES:
565 #ifdef HAVE_DARWIN_OS
566 Dmsg0(130, "Restoring Finder Info\n");
567 jcr->ff->flags |= FO_HFSPLUS;
568 if (sd->msglen != 32) {
569 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
572 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
573 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
581 case STREAM_UNIX_ACCESS_ACL:
582 case STREAM_UNIX_DEFAULT_ACL:
583 case STREAM_ACL_AIX_TEXT:
584 case STREAM_ACL_DARWIN_ACCESS_ACL:
585 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
586 case STREAM_ACL_FREEBSD_ACCESS_ACL:
587 case STREAM_ACL_HPUX_ACL_ENTRY:
588 case STREAM_ACL_IRIX_DEFAULT_ACL:
589 case STREAM_ACL_IRIX_ACCESS_ACL:
590 case STREAM_ACL_LINUX_DEFAULT_ACL:
591 case STREAM_ACL_LINUX_ACCESS_ACL:
592 case STREAM_ACL_TRU64_DEFAULT_ACL:
593 case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
594 case STREAM_ACL_TRU64_ACCESS_ACL:
595 case STREAM_ACL_SOLARIS_ACLENT:
596 case STREAM_ACL_SOLARIS_ACE:
598 * Do not restore ACLs when
599 * a) The current file is not extracted
600 * b) and it is not a directory (they are never "extracted")
601 * c) or the file name is empty
603 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
607 pm_memcpy(jcr->acl_data, sd->msg, sd->msglen);
608 jcr->acl_data_len = sd->msglen;
609 if (!parse_acl_stream(jcr, rctx.stream)) {
610 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACLs of %s\n"), jcr->last_fname);
617 case STREAM_XATTR_SOLARIS_SYS:
618 case STREAM_XATTR_SOLARIS:
619 case STREAM_XATTR_DARWIN:
620 case STREAM_XATTR_FREEBSD:
621 case STREAM_XATTR_LINUX:
622 case STREAM_XATTR_NETBSD:
624 * Do not restore Extended Attributes when
625 * a) The current file is not extracted
626 * b) and it is not a directory (they are never "extracted")
627 * c) or the file name is empty
629 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
633 pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen);
634 jcr->xattr_data_len = sd->msglen;
635 if (!parse_xattr_stream(jcr, rctx.stream)) {
636 Qmsg1(jcr, M_WARNING, 0, _("Can't restore Extended Attributes of %s\n"), jcr->last_fname);
643 case STREAM_SIGNED_DIGEST:
644 /* Is this an unexpected signature? */
646 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
647 free_signature(rctx);
650 /* Save signature. */
651 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
652 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
656 case STREAM_MD5_DIGEST:
657 case STREAM_SHA1_DIGEST:
658 case STREAM_SHA256_DIGEST:
659 case STREAM_SHA512_DIGEST:
662 case STREAM_PROGRAM_NAMES:
663 case STREAM_PROGRAM_DATA:
664 if (!non_support_progname) {
665 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
666 non_support_progname++;
670 case STREAM_PLUGIN_NAME:
671 close_previous_stream(rctx);
672 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
673 plugin_name_stream(jcr, sd->msg);
677 close_previous_stream(rctx);
678 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
680 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
682 } /* end switch(stream) */
684 } /* end while get_msg() */
687 * If output file is still open, it was the last one in the
688 * archive since we just hit an end of file, so close the file.
690 if (is_bopen(&rctx.forkbfd)) {
691 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
694 close_previous_stream(rctx);
695 set_jcr_job_status(jcr, JS_Terminated);
699 set_jcr_job_status(jcr, JS_ErrorTerminated);
702 /* Free Signature & Crypto Data */
703 free_signature(rctx);
705 if (jcr->crypto.digest) {
706 crypto_digest_free(jcr->crypto.digest);
707 jcr->crypto.digest = NULL;
710 /* Free file cipher restore context */
711 if (rctx.cipher_ctx.cipher) {
712 crypto_cipher_free(rctx.cipher_ctx.cipher);
713 rctx.cipher_ctx.cipher = NULL;
715 if (rctx.cipher_ctx.buf) {
716 free_pool_memory(rctx.cipher_ctx.buf);
717 rctx.cipher_ctx.buf = NULL;
720 /* Free alternate stream cipher restore context */
721 if (rctx.fork_cipher_ctx.cipher) {
722 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
723 rctx.fork_cipher_ctx.cipher = NULL;
725 if (rctx.fork_cipher_ctx.buf) {
726 free_pool_memory(rctx.fork_cipher_ctx.buf);
727 rctx.fork_cipher_ctx.buf = NULL;
730 if (jcr->compress_buf) {
731 free(jcr->compress_buf);
732 jcr->compress_buf = NULL;
733 jcr->compress_buf_size = 0;
736 if (jcr->xattr_data) {
737 free_pool_memory(jcr->xattr_data);
738 jcr->xattr_data = NULL;
741 free_pool_memory(jcr->acl_data);
742 jcr->acl_data = NULL;
745 bclose(&rctx.forkbfd);
747 free_attr(rctx.attr);
748 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
749 edit_uint64(jcr->JobBytes, ec1));
750 if (non_support_data > 1 || non_support_attr > 1) {
751 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
752 non_support_data, non_support_attr);
754 if (non_support_rsrc) {
755 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
757 if (non_support_finfo) {
758 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
760 if (non_support_acl) {
761 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
763 if (non_support_crypto) {
764 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
766 if (non_support_xattr) {
767 Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
774 * Convert ZLIB error code into an ASCII message
776 static const char *zlib_strerror(int stat)
783 return _("Zlib errno");
785 return _("Zlib stream error");
787 return _("Zlib data error");
789 return _("Zlib memory error");
791 return _("Zlib buffer error");
792 case Z_VERSION_ERROR:
793 return _("Zlib version error");
800 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
802 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
803 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
807 * Verify the signature for the last restored file
808 * Return value is either true (signature correct)
809 * or false (signature could not be verified).
810 * TODO landonf: Implement without using find_one_file and
811 * without re-reading the file.
813 static bool verify_signature(JCR *jcr, r_ctx &rctx)
815 X509_KEYPAIR *keypair;
816 DIGEST *digest = NULL;
818 uint64_t saved_bytes;
819 crypto_digest_t signing_algorithm = have_sha2 ?
820 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
821 crypto_digest_t algorithm;
822 SIGNATURE *sig = rctx.sig;
825 if (!jcr->crypto.pki_sign) {
826 return true; /* no signature OK */
829 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
830 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
837 /* Iterate through the trusted signers */
838 foreach_alist(keypair, jcr->crypto.pki_signers) {
839 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
841 case CRYPTO_ERROR_NONE:
842 Dmsg0(50, "== Got digest\n");
844 * We computed jcr->crypto.digest using signing_algorithm while writing
845 * the file. If it is not the same as the algorithm used for
846 * this file, punt by releasing the computed algorithm and
847 * computing by re-reading the file.
849 if (algorithm != signing_algorithm) {
850 if (jcr->crypto.digest) {
851 crypto_digest_free(jcr->crypto.digest);
852 jcr->crypto.digest = NULL;
855 if (jcr->crypto.digest) {
856 /* Use digest computed while writing the file to verify the signature */
857 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
858 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
859 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
860 jcr->last_fname, crypto_strerror(err));
864 /* Signature found, digest allocated. Old method,
865 * re-read the file and compute the digest
867 jcr->crypto.digest = digest;
869 /* Checksum the entire file */
870 /* Make sure we don't modify JobBytes by saving and restoring it */
871 saved_bytes = jcr->JobBytes;
872 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
873 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
875 jcr->JobBytes = saved_bytes;
878 jcr->JobBytes = saved_bytes;
880 /* Verify the signature */
881 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
882 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
883 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
884 jcr->last_fname, crypto_strerror(err));
887 jcr->crypto.digest = NULL;
890 /* Valid signature */
891 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
892 crypto_digest_free(digest);
895 case CRYPTO_ERROR_NOSIGNER:
896 /* Signature not found, try again */
898 crypto_digest_free(digest);
903 /* Something strange happened (that shouldn't happen!)... */
904 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
910 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
914 crypto_digest_free(digest);
919 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
924 unser_begin(*data, SPARSE_FADDR_SIZE);
926 if (*addr != faddr) {
928 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
930 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
931 edit_uint64(*addr, ec1), jcr->last_fname,
932 be.bstrerror(bfd->berrno));
936 *data += SPARSE_FADDR_SIZE;
937 *length -= SPARSE_FADDR_SIZE;
941 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
946 char ec1[50]; /* Buffer printing huge values */
949 * NOTE! We only use uLong and Byte because they are
950 * needed by the zlib routines, they should not otherwise
953 compress_len = jcr->compress_buf_size;
954 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
955 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
956 (const Byte *)*data, (uLong)*length)) != Z_OK) {
957 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
958 jcr->last_fname, zlib_strerror(stat));
961 *data = jcr->compress_buf;
962 *length = compress_len;
963 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
966 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
971 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
974 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
975 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
976 unser_uint32(ctx->packet_len);
977 ctx->packet_len += CRYPTO_LEN_SIZE;
981 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
983 if (jcr->crypto.digest) {
984 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
987 if (!processWin32BackupAPIBlock(bfd, data, length)) {
989 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
990 jcr->last_fname, be.bstrerror(bfd->berrno));
993 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
995 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
996 jcr->last_fname, be.bstrerror(bfd->berrno));
1004 * In the context of jcr, write data to bfd.
1005 * We write buflen bytes in buf at addr. addr is updated in place.
1006 * The flags specify whether to use sparse files or compression.
1007 * Return value is the number of bytes written, or -1 on errors.
1009 int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
1010 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1012 BFILE *bfd = &rctx.bfd;
1013 char *wbuf; /* write buffer */
1014 uint32_t wsize; /* write size */
1015 uint32_t rsize; /* read size */
1016 uint32_t decrypted_len = 0; /* Decryption output length */
1017 char ec1[50]; /* Buffer printing huge values */
1020 jcr->ReadBytes += rsize;
1024 if (flags & FO_ENCRYPT) {
1025 ASSERT(cipher_ctx->cipher);
1027 /* NOTE: We must implement block preserving semantics for the
1028 * non-streaming compression and sparse code. */
1031 * Grow the crypto buffer, if necessary.
1032 * crypto_cipher_update() will process only whole blocks,
1033 * buffering the remaining input.
1035 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
1036 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1038 /* Decrypt the input block */
1039 if (!crypto_cipher_update(cipher_ctx->cipher,
1040 (const u_int8_t *)wbuf,
1042 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1044 /* Decryption failed. Shouldn't happen. */
1045 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1049 if (decrypted_len == 0) {
1050 /* No full block of encrypted data available, write more data */
1054 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1056 cipher_ctx->buf_len += decrypted_len;
1057 wbuf = cipher_ctx->buf;
1059 /* If one full preserved block is available, write it to disk,
1060 * and then buffer any remaining data. This should be effecient
1061 * as long as Bacula's block size is not significantly smaller than the
1062 * encryption block size (extremely unlikely!) */
1063 unser_crypto_packet_len(cipher_ctx);
1064 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1066 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1067 /* No full preserved block is available. */
1071 /* We have one full block, set up the filter input buffers */
1072 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1073 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1074 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1075 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1078 if (flags & FO_SPARSE) {
1079 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1084 if (flags & FO_GZIP) {
1085 if (!decompress_data(jcr, &wbuf, &wsize)) {
1090 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1093 jcr->JobBytes += wsize;
1095 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1097 /* Clean up crypto buffers */
1098 if (flags & FO_ENCRYPT) {
1099 /* Move any remaining data to start of buffer */
1100 if (cipher_ctx->buf_len > 0) {
1101 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1102 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1103 cipher_ctx->buf_len);
1105 /* The packet was successfully written, reset the length so that the next
1106 * packet length may be re-read by unser_crypto_packet_len() */
1107 cipher_ctx->packet_len = 0;
1112 rctx.extract = false;
1119 * If extracting, close any previous stream
1121 static void close_previous_stream(r_ctx &rctx)
1124 * If extracting, it was from previous stream, so
1125 * close the output file and validate the signature.
1128 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1129 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1130 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1131 is_bopen(&rctx.bfd));
1134 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1135 deallocate_cipher(rctx);
1136 deallocate_fork_cipher(rctx);
1139 if (rctx.jcr->plugin) {
1140 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1142 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1144 rctx.extract = false;
1146 /* Verify the cryptographic signature, if any */
1147 rctx.type = rctx.attr->type;
1148 verify_signature(rctx.jcr, rctx);
1150 /* Free Signature */
1151 free_signature(rctx);
1153 rctx.jcr->ff->flags = 0;
1154 Dmsg0(130, "Stop extracting.\n");
1155 } else if (is_bopen(&rctx.bfd)) {
1156 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1157 Dmsg0(000, "=== logic error !open\n");
1164 * In the context of jcr, flush any remaining data from the cipher context,
1165 * writing it to bfd.
1166 * Return value is true on success, false on failure.
1168 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1169 RESTORE_CIPHER_CTX *cipher_ctx)
1171 uint32_t decrypted_len = 0;
1172 char *wbuf; /* write buffer */
1173 uint32_t wsize; /* write size */
1174 char ec1[50]; /* Buffer printing huge values */
1175 bool second_pass = false;
1178 /* Write out the remaining block and free the cipher context */
1179 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1180 cipher_ctx->block_size);
1182 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1184 /* Writing out the final, buffered block failed. Shouldn't happen. */
1185 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1186 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1189 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1190 /* If nothing new was decrypted, and our output buffer is empty, return */
1191 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1195 cipher_ctx->buf_len += decrypted_len;
1197 unser_crypto_packet_len(cipher_ctx);
1198 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1199 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1200 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1201 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1202 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1204 if (flags & FO_SPARSE) {
1205 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1210 if (flags & FO_GZIP) {
1211 if (!decompress_data(jcr, &wbuf, &wsize)) {
1216 Dmsg0(130, "Call store_data\n");
1217 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1220 jcr->JobBytes += wsize;
1221 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1223 /* Move any remaining data to start of buffer */
1224 if (cipher_ctx->buf_len > 0) {
1225 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1226 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1227 cipher_ctx->buf_len);
1229 /* The packet was successfully written, reset the length so that the next
1230 * packet length may be re-read by unser_crypto_packet_len() */
1231 cipher_ctx->packet_len = 0;
1233 if (cipher_ctx->buf_len >0 && !second_pass) {
1238 /* Stop decryption */
1239 cipher_ctx->buf_len = 0;
1240 cipher_ctx->packet_len = 0;
1245 static void deallocate_cipher(r_ctx &rctx)
1247 /* Flush and deallocate previous stream's cipher context */
1248 if (rctx.cipher_ctx.cipher) {
1249 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1250 crypto_cipher_free(rctx.cipher_ctx.cipher);
1251 rctx.cipher_ctx.cipher = NULL;
1255 static void deallocate_fork_cipher(r_ctx &rctx)
1258 /* Flush and deallocate previous stream's fork cipher context */
1259 if (rctx.fork_cipher_ctx.cipher) {
1260 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1261 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1262 rctx.fork_cipher_ctx.cipher = NULL;
1266 static void free_signature(r_ctx &rctx)
1269 crypto_sign_free(rctx.sig);
1274 static void free_session(r_ctx &rctx)
1277 crypto_session_free(rctx.cs);
1283 /* This code if implemented goes above */
1284 #ifdef stbernard_implemented
1285 / #if defined(HAVE_WIN32)
1286 bool bResumeOfmOnExit = FALSE;
1287 if (isOpenFileManagerRunning()) {
1288 if ( pauseOpenFileManager() ) {
1289 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1290 bResumeOfmOnExit = TRUE;
1293 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1297 char username[UNLEN+1];
1298 DWORD usize = sizeof(username);
1299 int privs = enable_backup_privileges(NULL, 1);
1300 if (GetUserName(username, &usize)) {
1301 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1303 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));