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)
232 * g. Possibly a cryptographic signature
233 * h. Possibly MD5 or SHA1 record
236 * NOTE: We keep track of two bacula file descriptors:
237 * 1. bfd for file data.
238 * This fd is opened for non empty files when an attribute stream is
239 * encountered and closed when we find the next attribute stream.
240 * 2. fork_bfd for alternate data streams
241 * This fd is opened every time we encounter a new alternate data
242 * stream for the current file. When we find any other stream, we
244 * The expected size of the stream, fork_len, should be set when
246 * 3. Not all the stream data records are required -- e.g. if there
247 * is no fork, there is no alternate data stream, no ACL, ...
250 binit(&rctx.forkbfd);
251 attr = rctx.attr = new_attr(jcr);
252 jcr->acl_data = get_pool_memory(PM_MESSAGE);
253 jcr->xattr_data = get_pool_memory(PM_MESSAGE);
255 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
256 /* Remember previous stream type */
257 rctx.prev_stream = rctx.stream;
259 /* First we expect a Stream Record Header */
260 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
261 &rctx.stream, &rctx.size) != 5) {
262 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
265 Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
266 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
268 /* * Now we expect the Stream Data */
269 if (bget_msg(sd) < 0) {
270 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
273 if (rctx.size != (uint32_t)sd->msglen) {
274 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
275 sd->msglen, rctx.size);
276 Dmsg2(50, "Actual data size %d not same as header %d\n",
277 sd->msglen, rctx.size);
280 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
281 sd->msglen, rctx.extract);
283 /* If we change streams, close and reset alternate data streams */
284 if (rctx.prev_stream != rctx.stream) {
285 if (is_bopen(&rctx.forkbfd)) {
286 deallocate_fork_cipher(rctx);
287 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
289 rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
293 /* File Attributes stream */
294 switch (rctx.stream) {
295 case STREAM_UNIX_ATTRIBUTES:
296 case STREAM_UNIX_ATTRIBUTES_EX:
297 close_previous_stream(rctx); /* if any previous stream open, close it */
300 /* TODO: manage deleted files */
301 if (rctx.type == FT_DELETED) { /* deleted file */
306 * Unpack attributes and do sanity check them
308 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
312 if (file_index != attr->file_index) {
313 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
314 file_index, attr->file_index);
315 Dmsg0(200, "File index error\n");
320 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
321 attr->attr, attr->attrEx);
323 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
325 if (!is_restore_stream_supported(attr->data_stream)) {
326 if (!non_support_data++) {
327 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
328 stream_to_ascii(attr->data_stream));
333 build_attr_output_fnames(jcr, attr);
336 * Try to actually create the file, which returns a status telling
337 * us if we need to extract or not.
339 jcr->num_files_examined++;
340 rctx.extract = false;
342 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
344 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
347 pm_strcpy(jcr->last_fname, attr->ofname);
348 jcr->last_type = attr->type;
350 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
354 pm_strcpy(jcr->last_fname, attr->ofname);
355 jcr->last_type = attr->type;
357 case CF_EXTRACT: /* File created and we expect file data */
360 case CF_CREATED: /* File created, but there is no content */
363 print_ls_output(jcr, attr);
365 if (have_darwin_os) {
366 /* Only restore the resource fork for regular files */
367 from_base64(&rsrc_len, attr->attrEx);
368 if (attr->type == FT_REG && rsrc_len > 0) {
373 /* set attributes now because file will not be extracted */
375 plugin_set_attributes(jcr, attr, &rctx.bfd);
377 set_attributes(jcr, attr, &rctx.bfd);
385 case STREAM_ENCRYPTED_SESSION_DATA:
386 crypto_error_t cryptoerr;
388 /* Is this an unexpected session data entry? */
390 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
391 rctx.extract = false;
396 /* Do we have any keys at all? */
397 if (!jcr->crypto.pki_recipients) {
398 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
399 rctx.extract = false;
404 if (jcr->crypto.digest) {
405 crypto_digest_free(jcr->crypto.digest);
407 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
408 if (!jcr->crypto.digest) {
409 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
410 rctx.extract = false;
415 /* Decode and save session keys. */
416 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
417 jcr->crypto.pki_recipients, &rctx.cs);
419 case CRYPTO_ERROR_NONE:
422 case CRYPTO_ERROR_NORECIPIENT:
423 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
425 case CRYPTO_ERROR_DECRYPTION:
426 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
429 /* Shouldn't happen */
430 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
434 if (cryptoerr != CRYPTO_ERROR_NONE) {
435 rctx.extract = false;
442 case STREAM_FILE_DATA:
443 case STREAM_SPARSE_DATA:
444 case STREAM_WIN32_DATA:
445 case STREAM_GZIP_DATA:
446 case STREAM_SPARSE_GZIP_DATA:
447 case STREAM_WIN32_GZIP_DATA:
448 case STREAM_ENCRYPTED_FILE_DATA:
449 case STREAM_ENCRYPTED_WIN32_DATA:
450 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
451 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
452 /* Force an expected, consistent stream type here */
453 if (rctx.extract && (rctx.prev_stream == rctx.stream
454 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
455 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
456 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
459 if (rctx.stream == STREAM_SPARSE_DATA ||
460 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
461 rctx.flags |= FO_SPARSE;
464 if (rctx.stream == STREAM_GZIP_DATA
465 || rctx.stream == STREAM_SPARSE_GZIP_DATA
466 || rctx.stream == STREAM_WIN32_GZIP_DATA
467 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
468 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
469 rctx.flags |= FO_GZIP;
472 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
473 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
474 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
475 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
476 /* Set up a decryption context */
477 if (!rctx.cipher_ctx.cipher) {
479 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
480 rctx.extract = false;
485 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
486 &rctx.cipher_ctx.block_size)) == NULL) {
487 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
489 rctx.extract = false;
494 rctx.flags |= FO_ENCRYPT;
497 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
498 set_portable_backup(&rctx.bfd);
499 rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
502 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr,
503 rctx.flags, &rctx.cipher_ctx) < 0) {
510 /* Resource fork stream - only recorded after a file to be restored */
511 /* Silently ignore if we cannot write - we already reported that */
512 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
513 case STREAM_MACOS_FORK_DATA:
514 #ifdef HAVE_DARWIN_OS
516 jcr->ff->flags |= FO_HFSPLUS;
518 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
519 rctx.fork_flags |= FO_ENCRYPT;
521 /* Set up a decryption context */
522 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
524 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
525 rctx.extract = false;
530 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
531 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
533 rctx.extract = false;
541 if (rctx.prev_stream != rctx.stream) {
542 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
543 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
544 rctx.extract = false;
548 rctx.fork_size = rsrc_len;
549 Dmsg0(130, "Restoring resource fork\n");
552 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
553 &rctx.fork_cipher_ctx) < 0) {
554 bclose(&rctx.forkbfd);
563 case STREAM_HFSPLUS_ATTRIBUTES:
564 #ifdef HAVE_DARWIN_OS
565 Dmsg0(130, "Restoring Finder Info\n");
566 jcr->ff->flags |= FO_HFSPLUS;
567 if (sd->msglen != 32) {
568 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
571 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
572 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
580 case STREAM_UNIX_ACCESS_ACL:
581 case STREAM_UNIX_DEFAULT_ACL:
582 case STREAM_ACL_AIX_TEXT:
583 case STREAM_ACL_DARWIN_ACCESS_ACL:
584 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
585 case STREAM_ACL_FREEBSD_ACCESS_ACL:
586 case STREAM_ACL_HPUX_ACL_ENTRY:
587 case STREAM_ACL_IRIX_DEFAULT_ACL:
588 case STREAM_ACL_IRIX_ACCESS_ACL:
589 case STREAM_ACL_LINUX_DEFAULT_ACL:
590 case STREAM_ACL_LINUX_ACCESS_ACL:
591 case STREAM_ACL_TRU64_DEFAULT_ACL:
592 case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
593 case STREAM_ACL_TRU64_ACCESS_ACL:
594 case STREAM_ACL_SOLARIS_ACLENT:
595 case STREAM_ACL_SOLARIS_ACE:
597 * Do not restore ACLs when
598 * a) The current file is not extracted
599 * b) and it is not a directory (they are never "extracted")
600 * c) or the file name is empty
602 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
606 pm_memcpy(jcr->acl_data, sd->msg, sd->msglen);
607 jcr->acl_data_len = sd->msglen;
608 if (!parse_acl_stream(jcr, rctx.stream)) {
609 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACLs of %s\n"), jcr->last_fname);
616 case STREAM_XATTR_DARWIN:
617 case STREAM_XATTR_FREEBSD:
618 case STREAM_XATTR_LINUX:
620 * Do not restore Extended Attributes when
621 * a) The current file is not extracted
622 * b) and it is not a directory (they are never "extracted")
623 * c) or the file name is empty
625 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
629 pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen);
630 jcr->xattr_data_len = sd->msglen;
631 if (!parse_xattr_stream(jcr, rctx.stream)) {
632 Qmsg1(jcr, M_WARNING, 0, _("Can't restore Extended Attributes of %s\n"), jcr->last_fname);
639 case STREAM_SIGNED_DIGEST:
640 /* Is this an unexpected signature? */
642 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
643 free_signature(rctx);
646 /* Save signature. */
647 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
648 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
652 case STREAM_MD5_DIGEST:
653 case STREAM_SHA1_DIGEST:
654 case STREAM_SHA256_DIGEST:
655 case STREAM_SHA512_DIGEST:
658 case STREAM_PROGRAM_NAMES:
659 case STREAM_PROGRAM_DATA:
660 if (!non_support_progname) {
661 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
662 non_support_progname++;
666 case STREAM_PLUGIN_NAME:
667 close_previous_stream(rctx);
668 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
669 plugin_name_stream(jcr, sd->msg);
673 close_previous_stream(rctx);
674 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
676 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
678 } /* end switch(stream) */
680 } /* end while get_msg() */
683 * If output file is still open, it was the last one in the
684 * archive since we just hit an end of file, so close the file.
686 if (is_bopen(&rctx.forkbfd)) {
687 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
690 close_previous_stream(rctx);
691 set_jcr_job_status(jcr, JS_Terminated);
695 set_jcr_job_status(jcr, JS_ErrorTerminated);
698 /* Free Signature & Crypto Data */
699 free_signature(rctx);
701 if (jcr->crypto.digest) {
702 crypto_digest_free(jcr->crypto.digest);
703 jcr->crypto.digest = NULL;
706 /* Free file cipher restore context */
707 if (rctx.cipher_ctx.cipher) {
708 crypto_cipher_free(rctx.cipher_ctx.cipher);
709 rctx.cipher_ctx.cipher = NULL;
711 if (rctx.cipher_ctx.buf) {
712 free_pool_memory(rctx.cipher_ctx.buf);
713 rctx.cipher_ctx.buf = NULL;
716 /* Free alternate stream cipher restore context */
717 if (rctx.fork_cipher_ctx.cipher) {
718 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
719 rctx.fork_cipher_ctx.cipher = NULL;
721 if (rctx.fork_cipher_ctx.buf) {
722 free_pool_memory(rctx.fork_cipher_ctx.buf);
723 rctx.fork_cipher_ctx.buf = NULL;
726 if (jcr->compress_buf) {
727 free(jcr->compress_buf);
728 jcr->compress_buf = NULL;
729 jcr->compress_buf_size = 0;
731 bclose(&rctx.forkbfd);
733 free_attr(rctx.attr);
734 free_pool_memory(jcr->xattr_data);
735 free_pool_memory(jcr->acl_data);
736 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
737 edit_uint64(jcr->JobBytes, ec1));
738 if (non_support_data > 1 || non_support_attr > 1) {
739 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
740 non_support_data, non_support_attr);
742 if (non_support_rsrc) {
743 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
745 if (non_support_finfo) {
746 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
748 if (non_support_acl) {
749 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
751 if (non_support_crypto) {
752 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
754 if (non_support_xattr) {
755 Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
762 * Convert ZLIB error code into an ASCII message
764 static const char *zlib_strerror(int stat)
771 return _("Zlib errno");
773 return _("Zlib stream error");
775 return _("Zlib data error");
777 return _("Zlib memory error");
779 return _("Zlib buffer error");
780 case Z_VERSION_ERROR:
781 return _("Zlib version error");
788 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
790 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
791 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
795 * Verify the signature for the last restored file
796 * Return value is either true (signature correct)
797 * or false (signature could not be verified).
798 * TODO landonf: Implement without using find_one_file and
799 * without re-reading the file.
801 static bool verify_signature(JCR *jcr, r_ctx &rctx)
803 X509_KEYPAIR *keypair;
804 DIGEST *digest = NULL;
806 uint64_t saved_bytes;
807 crypto_digest_t signing_algorithm = have_sha2 ?
808 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
809 crypto_digest_t algorithm;
810 SIGNATURE *sig = rctx.sig;
813 if (!jcr->crypto.pki_sign) {
814 return true; /* no signature OK */
817 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
818 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
825 /* Iterate through the trusted signers */
826 foreach_alist(keypair, jcr->crypto.pki_signers) {
827 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
829 case CRYPTO_ERROR_NONE:
830 Dmsg0(50, "== Got digest\n");
832 * We computed jcr->crypto.digest using signing_algorithm while writing
833 * the file. If it is not the same as the algorithm used for
834 * this file, punt by releasing the computed algorithm and
835 * computing by re-reading the file.
837 if (algorithm != signing_algorithm) {
838 if (jcr->crypto.digest) {
839 crypto_digest_free(jcr->crypto.digest);
840 jcr->crypto.digest = NULL;
843 if (jcr->crypto.digest) {
844 /* Use digest computed while writing the file to verify the signature */
845 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
846 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
847 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
848 jcr->last_fname, crypto_strerror(err));
852 /* Signature found, digest allocated. Old method,
853 * re-read the file and compute the digest
855 jcr->crypto.digest = digest;
857 /* Checksum the entire file */
858 /* Make sure we don't modify JobBytes by saving and restoring it */
859 saved_bytes = jcr->JobBytes;
860 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
861 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
863 jcr->JobBytes = saved_bytes;
866 jcr->JobBytes = saved_bytes;
868 /* Verify the signature */
869 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
870 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
871 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
872 jcr->last_fname, crypto_strerror(err));
875 jcr->crypto.digest = NULL;
878 /* Valid signature */
879 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
880 crypto_digest_free(digest);
883 case CRYPTO_ERROR_NOSIGNER:
884 /* Signature not found, try again */
886 crypto_digest_free(digest);
891 /* Something strange happened (that shouldn't happen!)... */
892 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
898 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
902 crypto_digest_free(digest);
907 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
912 unser_begin(*data, SPARSE_FADDR_SIZE);
914 if (*addr != faddr) {
916 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
918 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
919 edit_uint64(*addr, ec1), jcr->last_fname,
920 be.bstrerror(bfd->berrno));
924 *data += SPARSE_FADDR_SIZE;
925 *length -= SPARSE_FADDR_SIZE;
929 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
934 char ec1[50]; /* Buffer printing huge values */
937 * NOTE! We only use uLong and Byte because they are
938 * needed by the zlib routines, they should not otherwise
941 compress_len = jcr->compress_buf_size;
942 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
943 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
944 (const Byte *)*data, (uLong)*length)) != Z_OK) {
945 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
946 jcr->last_fname, zlib_strerror(stat));
949 *data = jcr->compress_buf;
950 *length = compress_len;
951 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
954 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
959 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
962 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
963 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
964 unser_uint32(ctx->packet_len);
965 ctx->packet_len += CRYPTO_LEN_SIZE;
969 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
971 if (jcr->crypto.digest) {
972 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
975 if (!processWin32BackupAPIBlock(bfd, data, length)) {
977 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
978 jcr->last_fname, be.bstrerror(bfd->berrno));
981 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
983 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
984 jcr->last_fname, be.bstrerror(bfd->berrno));
992 * In the context of jcr, write data to bfd.
993 * We write buflen bytes in buf at addr. addr is updated in place.
994 * The flags specify whether to use sparse files or compression.
995 * Return value is the number of bytes written, or -1 on errors.
997 int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
998 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1000 BFILE *bfd = &rctx.bfd;
1001 char *wbuf; /* write buffer */
1002 uint32_t wsize; /* write size */
1003 uint32_t rsize; /* read size */
1004 uint32_t decrypted_len = 0; /* Decryption output length */
1005 char ec1[50]; /* Buffer printing huge values */
1008 jcr->ReadBytes += rsize;
1012 if (flags & FO_ENCRYPT) {
1013 ASSERT(cipher_ctx->cipher);
1015 /* NOTE: We must implement block preserving semantics for the
1016 * non-streaming compression and sparse code. */
1019 * Grow the crypto buffer, if necessary.
1020 * crypto_cipher_update() will process only whole blocks,
1021 * buffering the remaining input.
1023 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
1024 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1026 /* Decrypt the input block */
1027 if (!crypto_cipher_update(cipher_ctx->cipher,
1028 (const u_int8_t *)wbuf,
1030 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1032 /* Decryption failed. Shouldn't happen. */
1033 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1037 if (decrypted_len == 0) {
1038 /* No full block of encrypted data available, write more data */
1042 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1044 cipher_ctx->buf_len += decrypted_len;
1045 wbuf = cipher_ctx->buf;
1047 /* If one full preserved block is available, write it to disk,
1048 * and then buffer any remaining data. This should be effecient
1049 * as long as Bacula's block size is not significantly smaller than the
1050 * encryption block size (extremely unlikely!) */
1051 unser_crypto_packet_len(cipher_ctx);
1052 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1054 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1055 /* No full preserved block is available. */
1059 /* We have one full block, set up the filter input buffers */
1060 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1061 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1062 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1063 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1066 if (flags & FO_SPARSE) {
1067 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1072 if (flags & FO_GZIP) {
1073 if (!decompress_data(jcr, &wbuf, &wsize)) {
1078 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1081 jcr->JobBytes += wsize;
1083 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1085 /* Clean up crypto buffers */
1086 if (flags & FO_ENCRYPT) {
1087 /* Move any remaining data to start of buffer */
1088 if (cipher_ctx->buf_len > 0) {
1089 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1090 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1091 cipher_ctx->buf_len);
1093 /* The packet was successfully written, reset the length so that the next
1094 * packet length may be re-read by unser_crypto_packet_len() */
1095 cipher_ctx->packet_len = 0;
1100 rctx.extract = false;
1107 * If extracting, close any previous stream
1109 static void close_previous_stream(r_ctx &rctx)
1112 * If extracting, it was from previous stream, so
1113 * close the output file and validate the signature.
1116 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1117 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1118 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1119 is_bopen(&rctx.bfd));
1122 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1123 deallocate_cipher(rctx);
1124 deallocate_fork_cipher(rctx);
1127 if (rctx.jcr->plugin) {
1128 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1130 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1132 rctx.extract = false;
1134 /* Verify the cryptographic signature, if any */
1135 rctx.type = rctx.attr->type;
1136 verify_signature(rctx.jcr, rctx);
1138 /* Free Signature */
1139 free_signature(rctx);
1141 rctx.jcr->ff->flags = 0;
1142 Dmsg0(130, "Stop extracting.\n");
1143 } else if (is_bopen(&rctx.bfd)) {
1144 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1145 Dmsg0(000, "=== logic error !open\n");
1152 * In the context of jcr, flush any remaining data from the cipher context,
1153 * writing it to bfd.
1154 * Return value is true on success, false on failure.
1156 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1157 RESTORE_CIPHER_CTX *cipher_ctx)
1159 uint32_t decrypted_len = 0;
1160 char *wbuf; /* write buffer */
1161 uint32_t wsize; /* write size */
1162 char ec1[50]; /* Buffer printing huge values */
1163 bool second_pass = false;
1166 /* Write out the remaining block and free the cipher context */
1167 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1168 cipher_ctx->block_size);
1170 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1172 /* Writing out the final, buffered block failed. Shouldn't happen. */
1173 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1174 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1177 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1178 /* If nothing new was decrypted, and our output buffer is empty, return */
1179 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1183 cipher_ctx->buf_len += decrypted_len;
1185 unser_crypto_packet_len(cipher_ctx);
1186 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1187 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1188 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1189 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1190 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1192 if (flags & FO_SPARSE) {
1193 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1198 if (flags & FO_GZIP) {
1199 if (!decompress_data(jcr, &wbuf, &wsize)) {
1204 Dmsg0(130, "Call store_data\n");
1205 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1208 jcr->JobBytes += wsize;
1209 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1211 /* Move any remaining data to start of buffer */
1212 if (cipher_ctx->buf_len > 0) {
1213 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1214 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1215 cipher_ctx->buf_len);
1217 /* The packet was successfully written, reset the length so that the next
1218 * packet length may be re-read by unser_crypto_packet_len() */
1219 cipher_ctx->packet_len = 0;
1221 if (cipher_ctx->buf_len >0 && !second_pass) {
1226 /* Stop decryption */
1227 cipher_ctx->buf_len = 0;
1228 cipher_ctx->packet_len = 0;
1233 static void deallocate_cipher(r_ctx &rctx)
1235 /* Flush and deallocate previous stream's cipher context */
1236 if (rctx.cipher_ctx.cipher) {
1237 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1238 crypto_cipher_free(rctx.cipher_ctx.cipher);
1239 rctx.cipher_ctx.cipher = NULL;
1243 static void deallocate_fork_cipher(r_ctx &rctx)
1246 /* Flush and deallocate previous stream's fork cipher context */
1247 if (rctx.fork_cipher_ctx.cipher) {
1248 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1249 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1250 rctx.fork_cipher_ctx.cipher = NULL;
1254 static void free_signature(r_ctx &rctx)
1257 crypto_sign_free(rctx.sig);
1262 static void free_session(r_ctx &rctx)
1265 crypto_session_free(rctx.cs);
1271 /* This code if implemented goes above */
1272 #ifdef stbernard_implemented
1273 / #if defined(HAVE_WIN32)
1274 bool bResumeOfmOnExit = FALSE;
1275 if (isOpenFileManagerRunning()) {
1276 if ( pauseOpenFileManager() ) {
1277 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1278 bResumeOfmOnExit = TRUE;
1281 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1285 char username[UNLEN+1];
1286 DWORD usize = sizeof(username);
1287 int privs = enable_backup_privileges(NULL, 1);
1288 if (GetUserName(username, &usize)) {
1289 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1291 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));