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;
66 /* Data received from Storage Daemon */
67 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
69 typedef struct restore_cipher_ctx {
70 CIPHER_CONTEXT *cipher;
73 POOLMEM *buf; /* Pointer to descryption buffer */
74 int32_t buf_len; /* Count of bytes currently in buf */
75 int32_t packet_len; /* Total bytes in packet */
82 BFILE bfd; /* File content */
83 uint64_t fileAddr; /* file write address */
84 uint32_t size; /* Size of file */
85 int flags; /* Options for extract_data() */
86 BFILE forkbfd; /* Alternative data stream */
87 uint64_t fork_addr; /* Write address for alternative stream */
88 intmax_t fork_size; /* Size of alternate stream */
89 int fork_flags; /* Options for extract_data() */
90 int32_t type; /* file type FT_ */
91 ATTR *attr; /* Pointer to attributes */
92 bool extract; /* set when extracting */
94 SIGNATURE *sig; /* Cryptographic signature (if any) for file */
95 CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */
96 RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
97 RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
101 /* Forward referenced functions */
102 #if defined(HAVE_LIBZ)
103 static const char *zlib_strerror(int stat);
104 const bool have_libz = true;
106 const bool have_libz = false;
109 static void deallocate_cipher(r_ctx &rctx);
110 static void deallocate_fork_cipher(r_ctx &rctx);
111 static void free_signature(r_ctx &rctx);
112 static void free_session(r_ctx &rctx);
113 static void close_previous_stream(r_ctx &rctx);
117 static bool verify_signature(JCR *jcr, r_ctx &rctx);
118 int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
119 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
120 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
121 RESTORE_CIPHER_CTX *cipher_ctx);
125 * Close a bfd check that we are at the expected file offset.
126 * Makes use of some code from set_attributes().
128 static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
130 char ec1[50], ec2[50];
133 fsize = blseek(bfd, 0, SEEK_CUR);
134 bclose(bfd); /* first close file */
135 if (fsize > 0 && fsize != osize) {
136 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
137 jcr->last_fname, edit_uint64(osize, ec1),
138 edit_uint64(fsize, ec2));
146 * Restore the requested files.
149 void do_restore(JCR *jcr)
152 uint32_t VolSessionId, VolSessionTime;
154 char ec1[50]; /* Buffer printing huge values */
155 uint32_t buf_size; /* client buffer size */
157 intmax_t rsrc_len = 0; /* Original length of resource fork */
160 /* ***FIXME*** make configurable */
161 crypto_digest_t signing_algorithm = have_sha2 ?
162 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
163 memset(&rctx, 0, sizeof(rctx));
166 /* The following variables keep track of "known unknowns" */
167 int non_support_data = 0;
168 int non_support_attr = 0;
169 int non_support_rsrc = 0;
170 int non_support_finfo = 0;
171 int non_support_acl = 0;
172 int non_support_progname = 0;
173 int non_support_crypto = 0;
175 #ifdef HAVE_DARWIN_OS
176 struct attrlist attrList;
177 memset(&attrList, 0, sizeof(attrList));
178 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
179 attrList.commonattr = ATTR_CMN_FNDRINFO;
183 sd = jcr->store_bsock;
184 set_jcr_job_status(jcr, JS_Running);
187 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
190 buf_size = client->max_network_buffer_size;
192 buf_size = 0; /* use default */
194 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
195 set_jcr_job_status(jcr, JS_ErrorTerminated);
198 jcr->buf_size = sd->msglen;
200 /* St Bernard code goes here if implemented -- see end of file */
203 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
204 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
205 jcr->compress_buf_size = compress_buf_size;
209 rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
210 if (have_darwin_os) {
211 rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
216 * Get a record from the Storage daemon. We are guaranteed to
217 * receive records in the following order:
218 * 1. Stream record header
219 * 2. Stream data (one or more of the following in the order given)
220 * a. Attributes (Unix or Win32)
221 * b. Possibly stream encryption session data (e.g., symmetric session key)
222 * c. File data for the file
223 * d. Alternate data stream (e.g. Resource Fork)
226 * g. Possibly a cryptographic signature
227 * h. Possibly MD5 or SHA1 record
230 * NOTE: We keep track of two bacula file descriptors:
231 * 1. bfd for file data.
232 * This fd is opened for non empty files when an attribute stream is
233 * encountered and closed when we find the next attribute stream.
234 * 2. fork_bfd for alternate data streams
235 * This fd is opened every time we encounter a new alternate data
236 * stream for the current file. When we find any other stream, we
238 * The expected size of the stream, fork_len, should be set when
240 * 3. Not all the stream data records are required -- e.g. if there
241 * is no fork, there is no alternate data stream, no ACL, ...
244 binit(&rctx.forkbfd);
245 attr = rctx.attr = new_attr(jcr);
246 jcr->acl_text = get_pool_memory(PM_MESSAGE);
250 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
251 /* Remember previous stream type */
252 rctx.prev_stream = rctx.stream;
254 /* First we expect a Stream Record Header */
255 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
256 &rctx.stream, &rctx.size) != 5) {
257 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
260 Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
261 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
263 /* * Now we expect the Stream Data */
264 if (bget_msg(sd) < 0) {
265 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
268 if (rctx.size != (uint32_t)sd->msglen) {
269 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
270 sd->msglen, rctx.size);
271 Dmsg2(50, "Actual data size %d not same as header %d\n",
272 sd->msglen, rctx.size);
275 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
276 sd->msglen, rctx.extract);
278 /* If we change streams, close and reset alternate data streams */
279 if (rctx.prev_stream != rctx.stream) {
280 if (is_bopen(&rctx.forkbfd)) {
281 deallocate_fork_cipher(rctx);
282 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
284 rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
288 /* File Attributes stream */
289 switch (rctx.stream) {
290 case STREAM_UNIX_ATTRIBUTES:
291 case STREAM_UNIX_ATTRIBUTES_EX:
292 close_previous_stream(rctx); /* if any previous stream open, close it */
295 /* TODO: manage deleted files */
296 if (rctx.type == FT_DELETED) { /* deleted file */
301 * Unpack attributes and do sanity check them
303 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
307 if (file_index != attr->file_index) {
308 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
309 file_index, attr->file_index);
310 Dmsg0(200, "File index error\n");
315 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
316 attr->attr, attr->attrEx);
318 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
320 if (!is_restore_stream_supported(attr->data_stream)) {
321 if (!non_support_data++) {
322 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
323 stream_to_ascii(attr->data_stream));
328 build_attr_output_fnames(jcr, attr);
331 * Try to actually create the file, which returns a status telling
332 * us if we need to extract or not.
334 jcr->num_files_examined++;
335 rctx.extract = false;
337 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
339 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
342 pm_strcpy(jcr->last_fname, attr->ofname);
343 jcr->last_type = attr->type;
345 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
350 case CF_EXTRACT: /* File created and we expect file data */
353 case CF_CREATED: /* File created, but there is no content */
356 print_ls_output(jcr, attr);
358 if (have_darwin_os) {
359 /* Only restore the resource fork for regular files */
360 from_base64(&rsrc_len, attr->attrEx);
361 if (attr->type == FT_REG && rsrc_len > 0) {
366 /* set attributes now because file will not be extracted */
368 plugin_set_attributes(jcr, attr, &rctx.bfd);
370 set_attributes(jcr, attr, &rctx.bfd);
378 case STREAM_ENCRYPTED_SESSION_DATA:
379 crypto_error_t cryptoerr;
381 /* Is this an unexpected session data entry? */
383 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
384 rctx.extract = false;
389 /* Do we have any keys at all? */
390 if (!jcr->crypto.pki_recipients) {
391 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
392 rctx.extract = false;
397 if (jcr->crypto.digest) {
398 crypto_digest_free(jcr->crypto.digest);
400 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
401 if (!jcr->crypto.digest) {
402 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
403 rctx.extract = false;
408 /* Decode and save session keys. */
409 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
410 jcr->crypto.pki_recipients, &rctx.cs);
412 case CRYPTO_ERROR_NONE:
415 case CRYPTO_ERROR_NORECIPIENT:
416 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
418 case CRYPTO_ERROR_DECRYPTION:
419 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
422 /* Shouldn't happen */
423 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
427 if (cryptoerr != CRYPTO_ERROR_NONE) {
428 rctx.extract = false;
435 case STREAM_FILE_DATA:
436 case STREAM_SPARSE_DATA:
437 case STREAM_WIN32_DATA:
438 case STREAM_GZIP_DATA:
439 case STREAM_SPARSE_GZIP_DATA:
440 case STREAM_WIN32_GZIP_DATA:
441 case STREAM_ENCRYPTED_FILE_DATA:
442 case STREAM_ENCRYPTED_WIN32_DATA:
443 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
444 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
445 /* Force an expected, consistent stream type here */
446 if (rctx.extract && (rctx.prev_stream == rctx.stream
447 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
448 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
449 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
452 if (rctx.stream == STREAM_SPARSE_DATA ||
453 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
454 rctx.flags |= FO_SPARSE;
457 if (rctx.stream == STREAM_GZIP_DATA
458 || rctx.stream == STREAM_SPARSE_GZIP_DATA
459 || rctx.stream == STREAM_WIN32_GZIP_DATA
460 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
461 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
462 rctx.flags |= FO_GZIP;
465 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
466 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
467 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
468 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
469 /* Set up a decryption context */
470 if (!rctx.cipher_ctx.cipher) {
472 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
473 rctx.extract = false;
478 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
479 &rctx.cipher_ctx.block_size)) == NULL) {
480 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
482 rctx.extract = false;
487 rctx.flags |= FO_ENCRYPT;
490 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
491 set_portable_backup(&rctx.bfd);
492 rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
495 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr,
496 rctx.flags, &rctx.cipher_ctx) < 0) {
503 /* Resource fork stream - only recorded after a file to be restored */
504 /* Silently ignore if we cannot write - we already reported that */
505 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
506 case STREAM_MACOS_FORK_DATA:
507 #ifdef HAVE_DARWIN_OS
509 jcr->ff->flags |= FO_HFSPLUS;
511 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
512 rctx.fork_flags |= FO_ENCRYPT;
514 /* Set up a decryption context */
515 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
517 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
518 rctx.extract = false;
523 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
524 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
526 rctx.extract = false;
534 if (rctx.prev_stream != rctx.stream) {
535 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
536 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
537 rctx.extract = false;
541 rctx.fork_size = rsrc_len;
542 Dmsg0(130, "Restoring resource fork\n");
545 if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
546 &rctx.fork_cipher_ctx) < 0) {
547 bclose(&rctx.forkbfd);
556 case STREAM_HFSPLUS_ATTRIBUTES:
557 #ifdef HAVE_DARWIN_OS
558 Dmsg0(130, "Restoring Finder Info\n");
559 jcr->ff->flags |= FO_HFSPLUS;
560 if (sd->msglen != 32) {
561 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
564 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
565 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
573 case STREAM_UNIX_ACCESS_ACL:
575 pm_strcpy(jcr->acl_text, sd->msg);
576 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
577 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
578 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
585 case STREAM_UNIX_DEFAULT_ACL:
587 pm_strcpy(jcr->acl_text, sd->msg);
588 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
589 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
590 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
597 case STREAM_SIGNED_DIGEST:
598 /* Is this an unexpected signature? */
600 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
601 free_signature(rctx);
604 /* Save signature. */
605 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
606 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
610 case STREAM_MD5_DIGEST:
611 case STREAM_SHA1_DIGEST:
612 case STREAM_SHA256_DIGEST:
613 case STREAM_SHA512_DIGEST:
616 case STREAM_PROGRAM_NAMES:
617 case STREAM_PROGRAM_DATA:
618 if (!non_support_progname) {
619 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
620 non_support_progname++;
624 case STREAM_PLUGIN_NAME:
625 close_previous_stream(rctx);
626 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
627 plugin_name_stream(jcr, sd->msg);
631 close_previous_stream(rctx);
632 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
634 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
636 } /* end switch(stream) */
638 } /* end while get_msg() */
641 * If output file is still open, it was the last one in the
642 * archive since we just hit an end of file, so close the file.
644 if (is_bopen(&rctx.forkbfd)) {
645 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
648 close_previous_stream(rctx);
649 set_jcr_job_status(jcr, JS_Terminated);
653 set_jcr_job_status(jcr, JS_ErrorTerminated);
656 /* Free Signature & Crypto Data */
657 free_signature(rctx);
659 if (jcr->crypto.digest) {
660 crypto_digest_free(jcr->crypto.digest);
661 jcr->crypto.digest = NULL;
664 /* Free file cipher restore context */
665 if (rctx.cipher_ctx.cipher) {
666 crypto_cipher_free(rctx.cipher_ctx.cipher);
667 rctx.cipher_ctx.cipher = NULL;
669 if (rctx.cipher_ctx.buf) {
670 free_pool_memory(rctx.cipher_ctx.buf);
671 rctx.cipher_ctx.buf = NULL;
674 /* Free alternate stream cipher restore context */
675 if (rctx.fork_cipher_ctx.cipher) {
676 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
677 rctx.fork_cipher_ctx.cipher = NULL;
679 if (rctx.fork_cipher_ctx.buf) {
680 free_pool_memory(rctx.fork_cipher_ctx.buf);
681 rctx.fork_cipher_ctx.buf = NULL;
684 if (jcr->compress_buf) {
685 free(jcr->compress_buf);
686 jcr->compress_buf = NULL;
687 jcr->compress_buf_size = 0;
689 bclose(&rctx.forkbfd);
691 free_attr(rctx.attr);
692 free_pool_memory(jcr->acl_text);
693 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
694 edit_uint64(jcr->JobBytes, ec1));
695 if (non_support_data > 1 || non_support_attr > 1) {
696 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
697 non_support_data, non_support_attr);
699 if (non_support_rsrc) {
700 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
702 if (non_support_finfo) {
703 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
705 if (non_support_acl) {
706 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
708 if (non_support_crypto) {
709 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
716 * Convert ZLIB error code into an ASCII message
718 static const char *zlib_strerror(int stat)
725 return _("Zlib errno");
727 return _("Zlib stream error");
729 return _("Zlib data error");
731 return _("Zlib memory error");
733 return _("Zlib buffer error");
734 case Z_VERSION_ERROR:
735 return _("Zlib version error");
742 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
744 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
745 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
749 * Verify the signature for the last restored file
750 * Return value is either true (signature correct)
751 * or false (signature could not be verified).
752 * TODO landonf: Implement without using find_one_file and
753 * without re-reading the file.
755 static bool verify_signature(JCR *jcr, r_ctx &rctx)
757 X509_KEYPAIR *keypair;
758 DIGEST *digest = NULL;
760 uint64_t saved_bytes;
761 crypto_digest_t signing_algorithm = have_sha2 ?
762 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
763 crypto_digest_t algorithm;
764 SIGNATURE *sig = rctx.sig;
767 if (!jcr->crypto.pki_sign) {
768 return true; /* no signature OK */
771 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
772 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
779 /* Iterate through the trusted signers */
780 foreach_alist(keypair, jcr->crypto.pki_signers) {
781 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
783 case CRYPTO_ERROR_NONE:
784 Dmsg0(50, "== Got digest\n");
786 * We computed jcr->crypto.digest using signing_algorithm while writing
787 * the file. If it is not the same as the algorithm used for
788 * this file, punt by releasing the computed algorithm and
789 * computing by re-reading the file.
791 if (algorithm != signing_algorithm) {
792 if (jcr->crypto.digest) {
793 crypto_digest_free(jcr->crypto.digest);
794 jcr->crypto.digest = NULL;
797 if (jcr->crypto.digest) {
798 /* Use digest computed while writing the file to verify the signature */
799 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
800 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
801 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
802 jcr->last_fname, crypto_strerror(err));
806 /* Signature found, digest allocated. Old method,
807 * re-read the file and compute the digest
809 jcr->crypto.digest = digest;
811 /* Checksum the entire file */
812 /* Make sure we don't modify JobBytes by saving and restoring it */
813 saved_bytes = jcr->JobBytes;
814 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
815 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
817 jcr->JobBytes = saved_bytes;
820 jcr->JobBytes = saved_bytes;
822 /* Verify the signature */
823 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
824 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
825 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
826 jcr->last_fname, crypto_strerror(err));
829 jcr->crypto.digest = NULL;
832 /* Valid signature */
833 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
834 crypto_digest_free(digest);
837 case CRYPTO_ERROR_NOSIGNER:
838 /* Signature not found, try again */
840 crypto_digest_free(digest);
845 /* Something strange happened (that shouldn't happen!)... */
846 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
852 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
856 crypto_digest_free(digest);
861 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
866 unser_begin(*data, SPARSE_FADDR_SIZE);
868 if (*addr != faddr) {
870 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
872 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
873 edit_uint64(*addr, ec1), jcr->last_fname,
874 be.bstrerror(bfd->berrno));
878 *data += SPARSE_FADDR_SIZE;
879 *length -= SPARSE_FADDR_SIZE;
883 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
888 char ec1[50]; /* Buffer printing huge values */
891 * NOTE! We only use uLong and Byte because they are
892 * needed by the zlib routines, they should not otherwise
895 compress_len = jcr->compress_buf_size;
896 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
897 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
898 (const Byte *)*data, (uLong)*length)) != Z_OK) {
899 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
900 jcr->last_fname, zlib_strerror(stat));
903 *data = jcr->compress_buf;
904 *length = compress_len;
905 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
908 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
913 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
916 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
917 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
918 unser_uint32(ctx->packet_len);
919 ctx->packet_len += CRYPTO_LEN_SIZE;
923 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
925 if (jcr->crypto.digest) {
926 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
929 if (!processWin32BackupAPIBlock(bfd, data, length)) {
931 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
932 jcr->last_fname, be.bstrerror(bfd->berrno));
935 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
937 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
938 jcr->last_fname, be.bstrerror(bfd->berrno));
946 * In the context of jcr, write data to bfd.
947 * We write buflen bytes in buf at addr. addr is updated in place.
948 * The flags specify whether to use sparse files or compression.
949 * Return value is the number of bytes written, or -1 on errors.
951 int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
952 uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
954 BFILE *bfd = &rctx.bfd;
955 char *wbuf; /* write buffer */
956 uint32_t wsize; /* write size */
957 uint32_t rsize; /* read size */
958 uint32_t decrypted_len = 0; /* Decryption output length */
959 char ec1[50]; /* Buffer printing huge values */
962 jcr->ReadBytes += rsize;
966 if (flags & FO_ENCRYPT) {
967 ASSERT(cipher_ctx->cipher);
969 /* NOTE: We must implement block preserving semantics for the
970 * non-streaming compression and sparse code. */
973 * Grow the crypto buffer, if necessary.
974 * crypto_cipher_update() will process only whole blocks,
975 * buffering the remaining input.
977 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
978 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
980 /* Decrypt the input block */
981 if (!crypto_cipher_update(cipher_ctx->cipher,
982 (const u_int8_t *)wbuf,
984 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
986 /* Decryption failed. Shouldn't happen. */
987 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
991 if (decrypted_len == 0) {
992 /* No full block of encrypted data available, write more data */
996 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
998 cipher_ctx->buf_len += decrypted_len;
999 wbuf = cipher_ctx->buf;
1001 /* If one full preserved block is available, write it to disk,
1002 * and then buffer any remaining data. This should be effecient
1003 * as long as Bacula's block size is not significantly smaller than the
1004 * encryption block size (extremely unlikely!) */
1005 unser_crypto_packet_len(cipher_ctx);
1006 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1008 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1009 /* No full preserved block is available. */
1013 /* We have one full block, set up the filter input buffers */
1014 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1015 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1016 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1017 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1020 if (flags & FO_SPARSE) {
1021 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1026 if (flags & FO_GZIP) {
1027 if (!decompress_data(jcr, &wbuf, &wsize)) {
1032 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1035 jcr->JobBytes += wsize;
1037 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1039 /* Clean up crypto buffers */
1040 if (flags & FO_ENCRYPT) {
1041 /* Move any remaining data to start of buffer */
1042 if (cipher_ctx->buf_len > 0) {
1043 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1044 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1045 cipher_ctx->buf_len);
1047 /* The packet was successfully written, reset the length so that the next
1048 * packet length may be re-read by unser_crypto_packet_len() */
1049 cipher_ctx->packet_len = 0;
1054 rctx.extract = false;
1061 * If extracting, close any previous stream
1063 static void close_previous_stream(r_ctx &rctx)
1066 * If extracting, it was from previous stream, so
1067 * close the output file and validate the signature.
1070 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1071 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1072 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1073 is_bopen(&rctx.bfd));
1076 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1077 deallocate_cipher(rctx);
1078 deallocate_fork_cipher(rctx);
1081 if (rctx.jcr->plugin) {
1082 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1084 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1086 rctx.extract = false;
1088 /* Verify the cryptographic signature, if any */
1089 rctx.type = rctx.attr->type;
1090 verify_signature(rctx.jcr, rctx);
1092 /* Free Signature */
1093 free_signature(rctx);
1095 rctx.jcr->ff->flags = 0;
1096 Dmsg0(130, "Stop extracting.\n");
1097 } else if (is_bopen(&rctx.bfd)) {
1098 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1099 Dmsg0(000, "=== logic error !open\n");
1106 * In the context of jcr, flush any remaining data from the cipher context,
1107 * writing it to bfd.
1108 * Return value is true on success, false on failure.
1110 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1111 RESTORE_CIPHER_CTX *cipher_ctx)
1113 uint32_t decrypted_len = 0;
1114 char *wbuf; /* write buffer */
1115 uint32_t wsize; /* write size */
1116 char ec1[50]; /* Buffer printing huge values */
1117 bool second_pass = false;
1120 /* Write out the remaining block and free the cipher context */
1121 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1122 cipher_ctx->block_size);
1124 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1126 /* Writing out the final, buffered block failed. Shouldn't happen. */
1127 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1128 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1131 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1132 /* If nothing new was decrypted, and our output buffer is empty, return */
1133 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1137 cipher_ctx->buf_len += decrypted_len;
1139 unser_crypto_packet_len(cipher_ctx);
1140 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1141 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1142 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1143 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1144 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1146 if (flags & FO_SPARSE) {
1147 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1152 if (flags & FO_GZIP) {
1153 if (!decompress_data(jcr, &wbuf, &wsize)) {
1158 Dmsg0(130, "Call store_data\n");
1159 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1162 jcr->JobBytes += wsize;
1163 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1165 /* Move any remaining data to start of buffer */
1166 if (cipher_ctx->buf_len > 0) {
1167 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1168 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1169 cipher_ctx->buf_len);
1171 /* The packet was successfully written, reset the length so that the next
1172 * packet length may be re-read by unser_crypto_packet_len() */
1173 cipher_ctx->packet_len = 0;
1175 if (cipher_ctx->buf_len >0 && !second_pass) {
1180 /* Stop decryption */
1181 cipher_ctx->buf_len = 0;
1182 cipher_ctx->packet_len = 0;
1187 static void deallocate_cipher(r_ctx &rctx)
1189 /* Flush and deallocate previous stream's cipher context */
1190 if (rctx.cipher_ctx.cipher) {
1191 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1192 crypto_cipher_free(rctx.cipher_ctx.cipher);
1193 rctx.cipher_ctx.cipher = NULL;
1197 static void deallocate_fork_cipher(r_ctx &rctx)
1200 /* Flush and deallocate previous stream's fork cipher context */
1201 if (rctx.fork_cipher_ctx.cipher) {
1202 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1203 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1204 rctx.fork_cipher_ctx.cipher = NULL;
1208 static void free_signature(r_ctx &rctx)
1211 crypto_sign_free(rctx.sig);
1216 static void free_session(r_ctx &rctx)
1219 crypto_session_free(rctx.cs);
1225 /* This code if implemented goes above */
1226 #ifdef stbernard_implemented
1227 / #if defined(HAVE_WIN32)
1228 bool bResumeOfmOnExit = FALSE;
1229 if (isOpenFileManagerRunning()) {
1230 if ( pauseOpenFileManager() ) {
1231 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1232 bResumeOfmOnExit = TRUE;
1235 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1239 char username[UNLEN+1];
1240 DWORD usize = sizeof(username);
1241 int privs = enable_backup_privileges(NULL, 1);
1242 if (GetUserName(username, &usize)) {
1243 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1245 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));