2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2011 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 three of the GNU Affero 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 Affero 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;
72 * Data received from Storage Daemon
74 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
77 * Forward referenced functions
79 #if defined(HAVE_LIBZ)
80 static const char *zlib_strerror(int stat);
81 const bool have_libz = true;
83 const bool have_libz = false;
86 const bool have_lzo = true;
88 const bool have_lzo = false;
92 static void deallocate_cipher(r_ctx &rctx);
93 static void deallocate_fork_cipher(r_ctx &rctx);
94 static void free_signature(r_ctx &rctx);
95 static void free_session(r_ctx &rctx);
96 static void close_previous_stream(r_ctx &rctx);
98 static bool verify_signature(JCR *jcr, r_ctx &rctx);
99 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
100 uint64_t *addr, int flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx);
101 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, int32_t stream,
102 RESTORE_CIPHER_CTX *cipher_ctx);
105 * Close a bfd check that we are at the expected file offset.
106 * Makes use of some code from set_attributes().
108 static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
110 char ec1[50], ec2[50];
113 fsize = blseek(bfd, 0, SEEK_CUR);
115 if (fsize > 0 && fsize != osize) {
116 Qmsg3(jcr, M_WARNING, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
117 jcr->last_fname, edit_uint64(osize, ec1),
118 edit_uint64(fsize, ec2));
124 #ifdef HAVE_DARWIN_OS
125 bool restore_finderinfo(JCR *jcr, POOLMEM *buf, int32_t buflen)
127 struct attrlist attrList;
129 memset(&attrList, 0, sizeof(attrList));
130 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
131 attrList.commonattr = ATTR_CMN_FNDRINFO;
133 Dmsg0(130, "Restoring Finder Info\n");
134 jcr->ff->flags |= FO_HFSPLUS;
136 Jmsg(jcr, M_WARNING, 0, _("Invalid length of Finder Info (got %d, not 32)\n"), buflen);
140 if (setattrlist(jcr->last_fname, &attrList, buf, buflen, 0) != 0) {
141 Jmsg(jcr, M_WARNING, 0, _("Could not set Finder Info on %s\n"), jcr->last_fname);
148 bool restore_finderinfo(JCR *jcr, POOLMEM *buf, int32_t buflen)
155 * Restore the requested files.
157 void do_restore(JCR *jcr)
160 uint32_t VolSessionId, VolSessionTime;
162 char ec1[50]; /* Buffer printing huge values */
163 uint32_t buf_size; /* client buffer size */
165 int64_t rsrc_len = 0; /* Original length of resource fork */
168 /* ***FIXME*** make configurable */
169 crypto_digest_t signing_algorithm = have_sha2 ?
170 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
171 memset(&rctx, 0, sizeof(rctx));
175 * The following variables keep track of "known unknowns"
177 int non_support_data = 0;
178 int non_support_attr = 0;
179 int non_support_rsrc = 0;
180 int non_support_finfo = 0;
181 int non_support_acl = 0;
182 int non_support_progname = 0;
183 int non_support_crypto = 0;
184 int non_support_xattr = 0;
186 sd = jcr->store_bsock;
187 jcr->setJobStatus(JS_Running);
190 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
193 buf_size = client->max_network_buffer_size;
195 buf_size = 0; /* use default */
197 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
198 jcr->setJobStatus(JS_ErrorTerminated);
201 jcr->buf_size = sd->msglen;
204 * St Bernard code goes here if implemented -- see end of file
207 /* use the same buffer size to decompress both gzip and lzo */
208 if (have_libz || have_lzo) {
209 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
210 jcr->compress_buf = get_memory(compress_buf_size);
211 jcr->compress_buf_size = compress_buf_size;
215 if (lzo_init() != LZO_E_OK) {
216 Jmsg(jcr, M_FATAL, 0, _("LZO init failed\n"));
222 rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
223 if (have_darwin_os) {
224 rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
229 * Get a record from the Storage daemon. We are guaranteed to
230 * receive records in the following order:
231 * 1. Stream record header
232 * 2. Stream data (one or more of the following in the order given)
233 * a. Attributes (Unix or Win32)
234 * b. Possibly stream encryption session data (e.g., symmetric session key)
235 * c. File data for the file
236 * d. Alternate data stream (e.g. Resource Fork)
240 * h. Possibly a cryptographic signature
241 * i. Possibly MD5 or SHA1 record
244 * NOTE: We keep track of two bacula file descriptors:
245 * 1. bfd for file data.
246 * This fd is opened for non empty files when an attribute stream is
247 * encountered and closed when we find the next attribute stream.
248 * 2. fork_bfd for alternate data streams
249 * This fd is opened every time we encounter a new alternate data
250 * stream for the current file. When we find any other stream, we
252 * The expected size of the stream, fork_len, should be set when
254 * 3. Not all the stream data records are required -- e.g. if there
255 * is no fork, there is no alternate data stream, no ACL, ...
258 binit(&rctx.forkbfd);
259 attr = rctx.attr = new_attr(jcr);
261 jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
262 memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
263 jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
266 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
267 memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
268 jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
271 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
273 * Remember previous stream type
275 rctx.prev_stream = rctx.stream;
278 * First we expect a Stream Record Header
280 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
281 &rctx.full_stream, &rctx.size) != 5) {
282 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
285 /* Strip off new stream high bits */
286 rctx.stream = rctx.full_stream & STREAMMASK_TYPE;
287 Dmsg5(150, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
288 jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
291 * Now we expect the Stream Data
293 if (bget_msg(sd) < 0) {
294 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
297 if (rctx.size != (uint32_t)sd->msglen) {
298 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"),
299 sd->msglen, rctx.size);
300 Dmsg2(50, "Actual data size %d not same as header %d\n",
301 sd->msglen, rctx.size);
304 Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream),
305 sd->msglen, rctx.extract);
308 * If we change streams, close and reset alternate data streams
310 if (rctx.prev_stream != rctx.stream) {
311 if (is_bopen(&rctx.forkbfd)) {
312 deallocate_fork_cipher(rctx);
313 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
316 * Use an impossible value and set a proper one below
323 * File Attributes stream
325 switch (rctx.stream) {
326 case STREAM_UNIX_ATTRIBUTES:
327 case STREAM_UNIX_ATTRIBUTES_EX:
329 * if any previous stream open, close it
331 close_previous_stream(rctx);
334 * TODO: manage deleted files
336 if (rctx.type == FT_DELETED) { /* deleted file */
340 * Restore objects should be ignored here -- they are
341 * returned at the beginning of the restore.
343 if (IS_FT_OBJECT(rctx.type)) {
348 * Unpack attributes and do sanity check them
350 if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, sd->msglen, attr)) {
354 Dmsg3(100, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
355 attr->attr, attr->attrEx);
356 Dmsg3(100, "=== msglen=%d attrExlen=%d msg=%s\n", sd->msglen,
357 strlen(attr->attrEx), sd->msg);
359 attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI);
361 if (!is_restore_stream_supported(attr->data_stream)) {
362 if (!non_support_data++) {
363 Jmsg(jcr, M_WARNING, 0, _("%s stream not supported on this Client.\n"),
364 stream_to_ascii(attr->data_stream));
369 build_attr_output_fnames(jcr, attr);
372 * Try to actually create the file, which returns a status telling
373 * us if we need to extract or not.
375 jcr->num_files_examined++;
376 rctx.extract = false;
377 stat = CF_CORE; /* By default, let Bacula's core handle it */
380 stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
383 if (stat == CF_CORE) {
384 stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
387 pm_strcpy(jcr->last_fname, attr->ofname);
388 jcr->last_type = attr->type;
390 Dmsg2(130, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
398 * File created and we expect file data
406 * File created, but there is no content
409 print_ls_output(jcr, attr);
411 if (have_darwin_os) {
413 * Only restore the resource fork for regular files
415 from_base64(&rsrc_len, attr->attrEx);
416 if (attr->type == FT_REG && rsrc_len > 0) {
421 * Do not count the resource forks as regular files being restored.
432 * set attributes now because file will not be extracted
435 plugin_set_attributes(jcr, attr, &rctx.bfd);
437 set_attributes(jcr, attr, &rctx.bfd);
447 case STREAM_ENCRYPTED_SESSION_DATA:
448 crypto_error_t cryptoerr;
451 * Is this an unexpected session data entry?
454 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
455 rctx.extract = false;
461 * Do we have any keys at all?
463 if (!jcr->crypto.pki_recipients) {
464 Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
465 rctx.extract = false;
470 if (jcr->crypto.digest) {
471 crypto_digest_free(jcr->crypto.digest);
473 jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
474 if (!jcr->crypto.digest) {
475 Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
476 rctx.extract = false;
482 * Decode and save session keys.
484 cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
485 jcr->crypto.pki_recipients, &rctx.cs);
487 case CRYPTO_ERROR_NONE:
492 case CRYPTO_ERROR_NORECIPIENT:
493 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
495 case CRYPTO_ERROR_DECRYPTION:
496 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
502 Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
506 if (cryptoerr != CRYPTO_ERROR_NONE) {
507 rctx.extract = false;
514 case STREAM_FILE_DATA:
515 case STREAM_SPARSE_DATA:
516 case STREAM_WIN32_DATA:
517 case STREAM_GZIP_DATA:
518 case STREAM_SPARSE_GZIP_DATA:
519 case STREAM_WIN32_GZIP_DATA:
520 case STREAM_COMPRESSED_DATA:
521 case STREAM_SPARSE_COMPRESSED_DATA:
522 case STREAM_WIN32_COMPRESSED_DATA:
523 case STREAM_ENCRYPTED_FILE_DATA:
524 case STREAM_ENCRYPTED_WIN32_DATA:
525 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
526 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
527 case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
528 case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
530 * Force an expected, consistent stream type here
532 if (rctx.extract && (rctx.prev_stream == rctx.stream
533 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
534 || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
535 || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
538 if (rctx.stream == STREAM_SPARSE_DATA
539 || rctx.stream == STREAM_SPARSE_COMPRESSED_DATA
540 || rctx.stream == STREAM_SPARSE_GZIP_DATA) {
541 rctx.flags |= FO_SPARSE;
544 if (rctx.stream == STREAM_GZIP_DATA
545 || rctx.stream == STREAM_SPARSE_GZIP_DATA
546 || rctx.stream == STREAM_WIN32_GZIP_DATA
547 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
548 || rctx.stream == STREAM_COMPRESSED_DATA
549 || rctx.stream == STREAM_SPARSE_COMPRESSED_DATA
550 || rctx.stream == STREAM_WIN32_COMPRESSED_DATA
551 || rctx.stream == STREAM_ENCRYPTED_FILE_COMPRESSED_DATA
552 || rctx.stream == STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA
553 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
554 rctx.flags |= FO_COMPRESS;
555 rctx.comp_stream = rctx.stream;
558 if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
559 || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
560 || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
561 || rctx.stream == STREAM_ENCRYPTED_FILE_COMPRESSED_DATA
562 || rctx.stream == STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA
563 || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
565 * Set up a decryption context
567 if (!rctx.cipher_ctx.cipher) {
569 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
570 rctx.extract = false;
575 if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false,
576 &rctx.cipher_ctx.block_size)) == NULL) {
577 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
579 rctx.extract = false;
584 rctx.flags |= FO_ENCRYPT;
587 if (is_win32_stream(rctx.stream) && !have_win32_api()) {
588 set_portable_backup(&rctx.bfd);
590 * "decompose" BackupWrite data
592 rctx.flags |= FO_WIN32DECOMP;
595 if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr,
596 rctx.flags, rctx.stream, &rctx.cipher_ctx) < 0) {
597 rctx.extract = false;
605 * Resource fork stream - only recorded after a file to be restored
606 * Silently ignore if we cannot write - we already reported that
608 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
609 case STREAM_MACOS_FORK_DATA:
610 if (have_darwin_os) {
612 jcr->ff->flags |= FO_HFSPLUS;
614 if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
615 rctx.fork_flags |= FO_ENCRYPT;
618 * Set up a decryption context
620 if (rctx.extract && !rctx.fork_cipher_ctx.cipher) {
622 Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
623 rctx.extract = false;
628 if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
629 Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
631 rctx.extract = false;
639 if (rctx.prev_stream != rctx.stream) {
640 if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
641 Jmsg(jcr, M_WARNING, 0, _("Cannot open resource fork for %s.\n"), jcr->last_fname);
642 rctx.extract = false;
646 rctx.fork_size = rsrc_len;
647 Dmsg0(130, "Restoring resource fork\n");
650 if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
651 rctx.stream, &rctx.fork_cipher_ctx) < 0) {
652 rctx.extract = false;
653 bclose(&rctx.forkbfd);
662 case STREAM_HFSPLUS_ATTRIBUTES:
663 if (have_darwin_os) {
664 if (!restore_finderinfo(jcr, sd->msg, sd->msglen)) {
672 case STREAM_UNIX_ACCESS_ACL:
673 case STREAM_UNIX_DEFAULT_ACL:
674 case STREAM_ACL_AIX_TEXT:
675 case STREAM_ACL_DARWIN_ACCESS_ACL:
676 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
677 case STREAM_ACL_FREEBSD_ACCESS_ACL:
678 case STREAM_ACL_HPUX_ACL_ENTRY:
679 case STREAM_ACL_IRIX_DEFAULT_ACL:
680 case STREAM_ACL_IRIX_ACCESS_ACL:
681 case STREAM_ACL_LINUX_DEFAULT_ACL:
682 case STREAM_ACL_LINUX_ACCESS_ACL:
683 case STREAM_ACL_TRU64_DEFAULT_ACL:
684 case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
685 case STREAM_ACL_TRU64_ACCESS_ACL:
686 case STREAM_ACL_SOLARIS_ACLENT:
687 case STREAM_ACL_SOLARIS_ACE:
688 case STREAM_ACL_AFS_TEXT:
689 case STREAM_ACL_AIX_AIXC:
690 case STREAM_ACL_AIX_NFS4:
691 case STREAM_ACL_FREEBSD_NFS4_ACL:
693 * Do not restore ACLs when
694 * a) The current file is not extracted
695 * b) and it is not a directory (they are never "extracted")
696 * c) or the file name is empty
698 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
702 pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen);
703 jcr->acl_data->content_length = sd->msglen;
704 switch (parse_acl_streams(jcr, rctx.stream)) {
705 case bacl_exit_fatal:
707 case bacl_exit_error:
709 * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
710 * print the error message set by the lower level routine in jcr->errmsg.
712 if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
713 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
715 jcr->acl_data->nr_errors++;
725 case STREAM_XATTR_IRIX:
726 case STREAM_XATTR_TRU64:
727 case STREAM_XATTR_AIX:
728 case STREAM_XATTR_OPENBSD:
729 case STREAM_XATTR_SOLARIS_SYS:
730 case STREAM_XATTR_SOLARIS:
731 case STREAM_XATTR_DARWIN:
732 case STREAM_XATTR_FREEBSD:
733 case STREAM_XATTR_LINUX:
734 case STREAM_XATTR_NETBSD:
736 * Do not restore Extended Attributes when
737 * a) The current file is not extracted
738 * b) and it is not a directory (they are never "extracted")
739 * c) or the file name is empty
741 if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
745 pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen);
746 jcr->xattr_data->content_length = sd->msglen;
747 switch (parse_xattr_streams(jcr, rctx.stream)) {
748 case bxattr_exit_fatal:
750 case bxattr_exit_error:
752 * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
753 * print the error message set by the lower level routine in jcr->errmsg.
755 if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
756 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
758 jcr->xattr_data->nr_errors++;
768 case STREAM_SIGNED_DIGEST:
770 * Is this an unexpected signature?
773 Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
774 free_signature(rctx);
780 if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
781 Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
785 case STREAM_MD5_DIGEST:
786 case STREAM_SHA1_DIGEST:
787 case STREAM_SHA256_DIGEST:
788 case STREAM_SHA512_DIGEST:
791 case STREAM_PROGRAM_NAMES:
792 case STREAM_PROGRAM_DATA:
793 if (!non_support_progname) {
794 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
795 non_support_progname++;
799 case STREAM_PLUGIN_NAME:
800 close_previous_stream(rctx);
801 Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg);
802 plugin_name_stream(jcr, sd->msg);
805 case STREAM_RESTORE_OBJECT:
806 break; /* these are sent by Director */
809 close_previous_stream(rctx);
810 Jmsg(jcr, M_WARNING, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
812 Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
814 } /* end switch(stream) */
815 } /* end while get_msg() */
818 * If output file is still open, it was the last one in the
819 * archive since we just hit an end of file, so close the file.
821 if (is_bopen(&rctx.forkbfd)) {
822 bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
825 close_previous_stream(rctx);
826 jcr->setJobStatus(JS_Terminated);
830 jcr->setJobStatus(JS_ErrorTerminated);
834 * First output the statistics.
836 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
837 edit_uint64(jcr->JobBytes, ec1));
838 if (have_acl && jcr->acl_data->nr_errors > 0) {
839 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing restore\n"),
840 jcr->acl_data->nr_errors);
842 if (have_xattr && jcr->xattr_data->nr_errors > 0) {
843 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing restore\n"),
844 jcr->xattr_data->nr_errors);
846 if (non_support_data > 1 || non_support_attr > 1) {
847 Jmsg(jcr, M_WARNING, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
848 non_support_data, non_support_attr);
850 if (non_support_rsrc) {
851 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
853 if (non_support_finfo) {
854 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
856 if (non_support_acl) {
857 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
859 if (non_support_crypto) {
860 Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
862 if (non_support_xattr) {
863 Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
867 * Free Signature & Crypto Data
869 free_signature(rctx);
871 if (jcr->crypto.digest) {
872 crypto_digest_free(jcr->crypto.digest);
873 jcr->crypto.digest = NULL;
877 * Free file cipher restore context
879 if (rctx.cipher_ctx.cipher) {
880 crypto_cipher_free(rctx.cipher_ctx.cipher);
881 rctx.cipher_ctx.cipher = NULL;
884 if (rctx.cipher_ctx.buf) {
885 free_pool_memory(rctx.cipher_ctx.buf);
886 rctx.cipher_ctx.buf = NULL;
890 * Free alternate stream cipher restore context
892 if (rctx.fork_cipher_ctx.cipher) {
893 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
894 rctx.fork_cipher_ctx.cipher = NULL;
896 if (rctx.fork_cipher_ctx.buf) {
897 free_pool_memory(rctx.fork_cipher_ctx.buf);
898 rctx.fork_cipher_ctx.buf = NULL;
901 if (jcr->compress_buf) {
902 free_pool_memory(jcr->compress_buf);
903 jcr->compress_buf = NULL;
904 jcr->compress_buf_size = 0;
907 if (have_acl && jcr->acl_data) {
908 free_pool_memory(jcr->acl_data->content);
910 jcr->acl_data = NULL;
913 if (have_xattr && jcr->xattr_data) {
914 free_pool_memory(jcr->xattr_data->content);
915 free(jcr->xattr_data);
916 jcr->xattr_data = NULL;
919 bclose(&rctx.forkbfd);
921 free_attr(rctx.attr);
926 * Convert ZLIB error code into an ASCII message
928 static const char *zlib_strerror(int stat)
935 return _("Zlib errno");
937 return _("Zlib stream error");
939 return _("Zlib data error");
941 return _("Zlib memory error");
943 return _("Zlib buffer error");
944 case Z_VERSION_ERROR:
945 return _("Zlib version error");
952 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
954 Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
955 return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
959 * Verify the signature for the last restored file
960 * Return value is either true (signature correct)
961 * or false (signature could not be verified).
962 * TODO landonf: Implement without using find_one_file and
963 * without re-reading the file.
965 static bool verify_signature(JCR *jcr, r_ctx &rctx)
967 X509_KEYPAIR *keypair;
968 DIGEST *digest = NULL;
970 uint64_t saved_bytes;
971 crypto_digest_t signing_algorithm = have_sha2 ?
972 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
973 crypto_digest_t algorithm;
974 SIGNATURE *sig = rctx.sig;
977 if (!jcr->crypto.pki_sign) {
984 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
985 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
993 * Iterate through the trusted signers
995 foreach_alist(keypair, jcr->crypto.pki_signers) {
996 err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
998 case CRYPTO_ERROR_NONE:
999 Dmsg0(50, "== Got digest\n");
1001 * We computed jcr->crypto.digest using signing_algorithm while writing
1002 * the file. If it is not the same as the algorithm used for
1003 * this file, punt by releasing the computed algorithm and
1004 * computing by re-reading the file.
1006 if (algorithm != signing_algorithm) {
1007 if (jcr->crypto.digest) {
1008 crypto_digest_free(jcr->crypto.digest);
1009 jcr->crypto.digest = NULL;
1012 if (jcr->crypto.digest) {
1014 * Use digest computed while writing the file to verify the signature
1016 if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
1017 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
1018 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
1019 jcr->last_fname, crypto_strerror(err));
1024 * Signature found, digest allocated. Old method,
1025 * re-read the file and compute the digest
1027 jcr->crypto.digest = digest;
1030 * Checksum the entire file
1031 * Make sure we don't modify JobBytes by saving and restoring it
1033 saved_bytes = jcr->JobBytes;
1034 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
1035 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
1037 jcr->JobBytes = saved_bytes;
1040 jcr->JobBytes = saved_bytes;
1043 * Verify the signature
1045 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
1046 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
1047 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
1048 jcr->last_fname, crypto_strerror(err));
1051 jcr->crypto.digest = NULL;
1057 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
1058 crypto_digest_free(digest);
1061 case CRYPTO_ERROR_NOSIGNER:
1063 * Signature not found, try again
1066 crypto_digest_free(digest);
1072 * Something strange happened (that shouldn't happen!)...
1074 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
1082 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
1086 crypto_digest_free(digest);
1091 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
1096 unser_begin(*data, OFFSET_FADDR_SIZE);
1097 unser_uint64(faddr);
1098 if (*addr != faddr) {
1100 if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
1102 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
1103 edit_uint64(*addr, ec1), jcr->last_fname,
1104 be.bstrerror(bfd->berrno));
1108 *data += OFFSET_FADDR_SIZE;
1109 *length -= OFFSET_FADDR_SIZE;
1113 bool decompress_data(JCR *jcr, int32_t stream, char **data, uint32_t *length)
1115 char ec1[50]; /* Buffer printing huge values */
1117 Dmsg1(200, "Stream found in decompress_data(): %d\n", stream);
1118 if(stream == STREAM_COMPRESSED_DATA || stream == STREAM_SPARSE_COMPRESSED_DATA || stream == STREAM_WIN32_COMPRESSED_DATA
1119 || stream == STREAM_ENCRYPTED_FILE_COMPRESSED_DATA || stream == STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA)
1121 uint32_t comp_magic, comp_len;
1122 uint16_t comp_level, comp_version;
1124 lzo_uint compress_len;
1125 const unsigned char *cbuf;
1126 int r, real_compress_len;
1129 /* read compress header */
1131 unser_begin(*data, sizeof(comp_stream_header));
1132 unser_uint32(comp_magic);
1133 unser_uint32(comp_len);
1134 unser_uint16(comp_level);
1135 unser_uint16(comp_version);
1136 Dmsg4(200, "Compressed data stream found: magic=0x%x, len=%d, level=%d, ver=0x%x\n", comp_magic, comp_len,
1137 comp_level, comp_version);
1140 if (comp_version != COMP_HEAD_VERSION) {
1141 Qmsg(jcr, M_ERROR, 0, _("Compressed header version error. version=0x%x\n"), comp_version);
1145 if (comp_len + sizeof(comp_stream_header) != *length) {
1146 Qmsg(jcr, M_ERROR, 0, _("Compressed header size error. comp_len=%d, msglen=%d\n"),
1150 switch(comp_magic) {
1152 case COMPRESS_LZO1X:
1153 compress_len = jcr->compress_buf_size;
1154 cbuf = (const unsigned char*)*data + sizeof(comp_stream_header);
1155 real_compress_len = *length - sizeof(comp_stream_header);
1156 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1157 while ((r=lzo1x_decompress_safe(cbuf, real_compress_len,
1158 (unsigned char *)jcr->compress_buf, &compress_len, NULL)) == LZO_E_OUTPUT_OVERRUN)
1161 * The buffer size is too small, try with a bigger one
1163 compress_len = jcr->compress_buf_size = jcr->compress_buf_size + (jcr->compress_buf_size >> 1);
1164 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1165 jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
1168 if (r != LZO_E_OK) {
1169 Qmsg(jcr, M_ERROR, 0, _("LZO uncompression error on file %s. ERR=%d\n"),
1170 jcr->last_fname, r);
1173 *data = jcr->compress_buf;
1174 *length = compress_len;
1175 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
1179 Qmsg(jcr, M_ERROR, 0, _("Compression algorithm 0x%x found, but not supported!\n"), comp_magic);
1188 * NOTE! We only use uLong and Byte because they are
1189 * needed by the zlib routines, they should not otherwise
1190 * be used in Bacula.
1192 compress_len = jcr->compress_buf_size;
1193 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1194 while ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
1195 (const Byte *)*data, (uLong)*length)) == Z_BUF_ERROR)
1198 * The buffer size is too small, try with a bigger one
1200 compress_len = jcr->compress_buf_size = jcr->compress_buf_size + (jcr->compress_buf_size >> 1);
1201 Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
1202 jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
1206 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
1207 jcr->last_fname, zlib_strerror(stat));
1210 *data = jcr->compress_buf;
1211 *length = compress_len;
1212 Dmsg2(200, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
1215 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
1221 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
1224 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
1225 unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
1226 unser_uint32(ctx->packet_len);
1227 ctx->packet_len += CRYPTO_LEN_SIZE;
1231 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
1233 if (jcr->crypto.digest) {
1234 crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
1237 if (!processWin32BackupAPIBlock(bfd, data, length)) {
1239 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
1240 jcr->last_fname, be.bstrerror(bfd->berrno));
1243 } else if (bwrite(bfd, data, length) != (ssize_t)length) {
1245 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
1246 jcr->last_fname, be.bstrerror(bfd->berrno));
1254 * In the context of jcr, write data to bfd.
1255 * We write buflen bytes in buf at addr. addr is updated in place.
1256 * The flags specify whether to use sparse files or compression.
1257 * Return value is the number of bytes written, or -1 on errors.
1259 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
1260 uint64_t *addr, int flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx)
1262 char *wbuf; /* write buffer */
1263 uint32_t wsize; /* write size */
1264 uint32_t rsize; /* read size */
1265 uint32_t decrypted_len = 0; /* Decryption output length */
1266 char ec1[50]; /* Buffer printing huge values */
1269 jcr->ReadBytes += rsize;
1273 if (flags & FO_ENCRYPT) {
1274 ASSERT(cipher_ctx->cipher);
1277 * NOTE: We must implement block preserving semantics for the
1278 * non-streaming compression and sparse code.
1280 * Grow the crypto buffer, if necessary.
1281 * crypto_cipher_update() will process only whole blocks,
1282 * buffering the remaining input.
1284 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf,
1285 cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1288 * Decrypt the input block
1290 if (!crypto_cipher_update(cipher_ctx->cipher,
1291 (const u_int8_t *)wbuf,
1293 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1296 * Decryption failed. Shouldn't happen.
1298 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1302 if (decrypted_len == 0) {
1304 * No full block of encrypted data available, write more data
1309 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1311 cipher_ctx->buf_len += decrypted_len;
1312 wbuf = cipher_ctx->buf;
1315 * If one full preserved block is available, write it to disk,
1316 * and then buffer any remaining data. This should be effecient
1317 * as long as Bacula's block size is not significantly smaller than the
1318 * encryption block size (extremely unlikely!)
1320 unser_crypto_packet_len(cipher_ctx);
1321 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1323 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1325 * No full preserved block is available.
1331 * We have one full block, set up the filter input buffers
1333 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1334 wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1335 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1336 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1339 if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
1340 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1345 if (flags & FO_COMPRESS) {
1346 if (!decompress_data(jcr, stream, &wbuf, &wsize)) {
1351 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1354 jcr->JobBytes += wsize;
1356 Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1359 * Clean up crypto buffers
1361 if (flags & FO_ENCRYPT) {
1362 /* Move any remaining data to start of buffer */
1363 if (cipher_ctx->buf_len > 0) {
1364 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1365 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1366 cipher_ctx->buf_len);
1369 * The packet was successfully written, reset the length so that the next
1370 * packet length may be re-read by unser_crypto_packet_len()
1372 cipher_ctx->packet_len = 0;
1382 * If extracting, close any previous stream
1384 static void close_previous_stream(r_ctx &rctx)
1387 * If extracting, it was from previous stream, so
1388 * close the output file and validate the signature.
1391 if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
1392 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
1393 Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size,
1394 is_bopen(&rctx.bfd));
1397 if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
1398 deallocate_cipher(rctx);
1399 deallocate_fork_cipher(rctx);
1402 if (rctx.jcr->plugin) {
1403 plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1405 set_attributes(rctx.jcr, rctx.attr, &rctx.bfd);
1407 rctx.extract = false;
1410 * Verify the cryptographic signature, if any
1412 rctx.type = rctx.attr->type;
1413 verify_signature(rctx.jcr, rctx);
1418 free_signature(rctx);
1420 rctx.jcr->ff->flags = 0;
1421 Dmsg0(130, "Stop extracting.\n");
1422 } else if (is_bopen(&rctx.bfd)) {
1423 Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
1424 Dmsg0(000, "=== logic error !open\n");
1431 * In the context of jcr, flush any remaining data from the cipher context,
1432 * writing it to bfd.
1433 * Return value is true on success, false on failure.
1435 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, int32_t stream,
1436 RESTORE_CIPHER_CTX *cipher_ctx)
1438 uint32_t decrypted_len = 0;
1439 char *wbuf; /* write buffer */
1440 uint32_t wsize; /* write size */
1441 char ec1[50]; /* Buffer printing huge values */
1442 bool second_pass = false;
1446 * Write out the remaining block and free the cipher context
1448 cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
1449 cipher_ctx->block_size);
1451 if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1454 * Writing out the final, buffered block failed. Shouldn't happen.
1456 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
1457 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1460 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1462 * If nothing new was decrypted, and our output buffer is empty, return
1464 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1468 cipher_ctx->buf_len += decrypted_len;
1470 unser_crypto_packet_len(cipher_ctx);
1471 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1472 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1474 * Decrypted, possibly decompressed output here.
1476 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE];
1477 cipher_ctx->buf_len -= cipher_ctx->packet_len;
1478 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1480 if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
1481 if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1486 if (flags & FO_COMPRESS) {
1487 if (!decompress_data(jcr, stream, &wbuf, &wsize)) {
1492 Dmsg0(130, "Call store_data\n");
1493 if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1496 jcr->JobBytes += wsize;
1497 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1500 * Move any remaining data to start of buffer
1502 if (cipher_ctx->buf_len > 0) {
1503 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1504 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
1505 cipher_ctx->buf_len);
1508 * The packet was successfully written, reset the length so that the next
1509 * packet length may be re-read by unser_crypto_packet_len()
1511 cipher_ctx->packet_len = 0;
1513 if (cipher_ctx->buf_len >0 && !second_pass) {
1521 cipher_ctx->buf_len = 0;
1522 cipher_ctx->packet_len = 0;
1527 static void deallocate_cipher(r_ctx &rctx)
1530 * Flush and deallocate previous stream's cipher context
1532 if (rctx.cipher_ctx.cipher) {
1533 flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, rctx.comp_stream, &rctx.cipher_ctx);
1534 crypto_cipher_free(rctx.cipher_ctx.cipher);
1535 rctx.cipher_ctx.cipher = NULL;
1539 static void deallocate_fork_cipher(r_ctx &rctx)
1543 * Flush and deallocate previous stream's fork cipher context
1545 if (rctx.fork_cipher_ctx.cipher) {
1546 flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, rctx.comp_stream, &rctx.fork_cipher_ctx);
1547 crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1548 rctx.fork_cipher_ctx.cipher = NULL;
1552 static void free_signature(r_ctx &rctx)
1555 crypto_sign_free(rctx.sig);
1560 static void free_session(r_ctx &rctx)
1563 crypto_session_free(rctx.cs);
1570 * This code if implemented goes above
1572 #ifdef stbernard_implemented
1573 / #if defined(HAVE_WIN32)
1574 bool bResumeOfmOnExit = FALSE;
1575 if (isOpenFileManagerRunning()) {
1576 if ( pauseOpenFileManager() ) {
1577 Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1578 bResumeOfmOnExit = TRUE;
1581 Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1585 char username[UNLEN+1];
1586 DWORD usize = sizeof(username);
1587 int privs = enable_backup_privileges(NULL, 1);
1588 if (GetUserName(username, &usize)) {
1589 Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1591 Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));