]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/restore.c
Plugin update
[bacula/bacula] / bacula / src / filed / restore.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
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
11    in the file LICENSE.
12
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.
17
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
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
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.
27 */
28 /*
29  *  Bacula File Daemon  restore.c Restorefiles.
30  *
31  *    Kern Sibbald, November MM
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "filed.h"
39
40 #ifdef HAVE_DARWIN_OS
41 #include <sys/attr.h>
42 const bool have_darwin_os = true;
43 #else
44 const bool have_darwin_os = false;
45 #endif
46
47 #if defined(HAVE_CRYPTO)
48 const bool have_crypto = true;
49 #else
50 const bool have_crypto = false;
51 #endif
52
53 #if defined(HAVE_ACL)
54 const bool have_acl = true;
55 #else
56 const bool have_acl = false;
57 #endif
58
59 #ifdef HAVE_SHA2
60    const bool have_sha2 = true;
61 #else
62    const bool have_sha2 = false;
63 #endif
64
65
66 /* Data received from Storage Daemon */
67 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
68
69 typedef struct restore_cipher_ctx {
70    CIPHER_CONTEXT *cipher;
71    uint32_t block_size;
72
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 */
76 } RESTORE_CIPHER_CTX;
77
78 struct r_ctx {
79    JCR *jcr;
80    int32_t stream;
81    int32_t prev_stream;
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
92    SIGNATURE *sig;                     /* Cryptographic signature (if any) for file */
93    CRYPTO_SESSION *cs;                 /* Cryptographic session data (if any) for file */
94    RESTORE_CIPHER_CTX cipher_ctx;      /* Cryptographic restore context (if any) for file */
95    RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
96 };
97
98
99 /* Forward referenced functions */
100 #if   defined(HAVE_LIBZ)
101 static const char *zlib_strerror(int stat);
102 const bool have_libz = true;
103 #else
104 const bool have_libz = false;
105 #endif
106
107 static void deallocate_cipher(r_ctx &rctx);
108 static void deallocate_fork_cipher(r_ctx &rctx);
109 static void free_signature(r_ctx &rctx);
110 static void free_session(r_ctx &rctx);
111
112
113
114 static bool verify_signature(JCR *jcr, r_ctx &rctx);
115 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
116                      uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
117 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, 
118                   RESTORE_CIPHER_CTX *cipher_ctx);
119
120
121 /*
122  * Close a bfd check that we are at the expected file offset.
123  * Makes use of some code from set_attributes().
124  */
125 static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
126 {
127    char ec1[50], ec2[50];
128    boffset_t fsize;
129
130    fsize = blseek(bfd, 0, SEEK_CUR);
131    bclose(bfd);                              /* first close file */
132    if (fsize > 0 && fsize != osize) {
133       Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
134             jcr->last_fname, edit_uint64(osize, ec1),
135             edit_uint64(fsize, ec2));
136       return -1;
137    }
138    return 0;
139 }
140
141
142 /*
143  * Restore the requested files.
144  *
145  */
146 void do_restore(JCR *jcr)
147 {
148    BSOCK *sd;
149    uint32_t VolSessionId, VolSessionTime;
150    bool extract = false;
151    int32_t file_index;
152    char ec1[50];                       /* Buffer printing huge values */
153    uint32_t buf_size;                  /* client buffer size */
154    int stat;
155    ATTR *attr;
156    intmax_t rsrc_len = 0;             /* Original length of resource fork */
157    r_ctx rctx;
158    /* ***FIXME*** make configurable */
159    crypto_digest_t signing_algorithm = have_sha2 ? 
160                                        CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
161    memset(&rctx, 0, sizeof(rctx));
162    rctx.jcr = jcr;
163
164    /* The following variables keep track of "known unknowns" */
165    int non_support_data = 0;
166    int non_support_attr = 0;
167    int non_support_rsrc = 0;
168    int non_support_finfo = 0;
169    int non_support_acl = 0;
170    int non_support_progname = 0;
171    int non_support_crypto = 0;
172
173 #ifdef HAVE_DARWIN_OS
174    struct attrlist attrList;
175    memset(&attrList, 0, sizeof(attrList));
176    attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
177    attrList.commonattr = ATTR_CMN_FNDRINFO;
178 #endif
179
180
181    sd = jcr->store_bsock;
182    set_jcr_job_status(jcr, JS_Running);
183
184    LockRes();
185    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
186    UnlockRes();
187    if (client) {
188       buf_size = client->max_network_buffer_size;
189    } else {
190       buf_size = 0;                   /* use default */
191    }
192    if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
193       set_jcr_job_status(jcr, JS_ErrorTerminated);
194       return;
195    }
196    jcr->buf_size = sd->msglen;
197
198    /* St Bernard code goes here if implemented -- see end of file */
199
200    if (have_libz) {
201       uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
202       jcr->compress_buf = (char *)bmalloc(compress_buf_size);
203       jcr->compress_buf_size = compress_buf_size;
204    }
205
206    if (have_crypto) {
207       rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
208       if (have_darwin_os) {
209          rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
210       }
211    }
212    
213    /*
214     * Get a record from the Storage daemon. We are guaranteed to
215     *   receive records in the following order:
216     *   1. Stream record header
217     *   2. Stream data (one or more of the following in the order given)
218     *        a. Attributes (Unix or Win32)
219     *        b. Possibly stream encryption session data (e.g., symmetric session key)
220     *        c. File data for the file
221     *        d. Alternate data stream (e.g. Resource Fork)
222     *        e. Finder info
223     *        f. ACLs
224     *        g. Possibly a cryptographic signature
225     *        h. Possibly MD5 or SHA1 record
226     *   3. Repeat step 1
227     *
228     * NOTE: We keep track of two bacula file descriptors:
229     *   1. bfd for file data.
230     *      This fd is opened for non empty files when an attribute stream is
231     *      encountered and closed when we find the next attribute stream.
232     *   2. fork_bfd for alternate data streams
233     *      This fd is opened every time we encounter a new alternate data
234     *      stream for the current file. When we find any other stream, we
235     *      close it again.
236     *      The expected size of the stream, fork_len, should be set when
237     *      opening the fd.
238     *   3. Not all the stream data records are required -- e.g. if there
239     *      is no fork, there is no alternate data stream, no ACL, ...
240     */
241    binit(&rctx.bfd);
242    binit(&rctx.forkbfd);
243    attr = new_attr(jcr);
244    jcr->acl_text = get_pool_memory(PM_MESSAGE);
245
246    
247
248    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
249       /* Remember previous stream type */
250       rctx.prev_stream = rctx.stream;
251
252       /* First we expect a Stream Record Header */
253       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
254           &rctx.stream, &rctx.size) != 5) {
255          Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
256          goto bail_out;
257       }
258       Dmsg4(30, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n", 
259             jcr->JobFiles, file_index, rctx.stream, stream_to_ascii(rctx.stream));
260
261       /* * Now we expect the Stream Data */
262       if (bget_msg(sd) < 0) {
263          Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
264          goto bail_out;
265       }
266       if (rctx.size != (uint32_t)sd->msglen) {
267          Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), 
268                sd->msglen, rctx.size);
269          goto bail_out;
270       }
271       Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream), 
272             sd->msglen, extract);
273
274       /* If we change streams, close and reset alternate data streams */
275       if (rctx.prev_stream != rctx.stream) {
276          if (is_bopen(&rctx.forkbfd)) {
277             deallocate_fork_cipher(rctx);
278             bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
279          }
280          rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
281          rctx.fork_addr = 0;
282       }
283
284       /* File Attributes stream */
285       switch (rctx.stream) {
286       case STREAM_UNIX_ATTRIBUTES:
287       case STREAM_UNIX_ATTRIBUTES_EX:
288          /*
289           * If extracting, it was from previous stream, so
290           * close the output file and validate the signature.
291           */
292          if (extract) {
293             if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
294                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
295             }
296
297             if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
298                deallocate_cipher(rctx);
299                deallocate_fork_cipher(rctx);
300             }
301
302             if (jcr->plugin) {
303                plugin_set_attributes(jcr, attr, &rctx.bfd);
304             } else {
305                set_attributes(jcr, attr, &rctx.bfd);
306             }
307             extract = false;
308
309             /* Verify the cryptographic signature, if any */
310             rctx.type = attr->type;
311             verify_signature(jcr, rctx);
312
313             /* Free Signature */
314             free_signature(rctx);
315             free_session(rctx);
316             jcr->ff->flags = 0;
317             Dmsg0(30, "Stop extracting.\n");
318          } else if (is_bopen(&rctx.bfd)) {
319             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
320             bclose(&rctx.bfd);
321          }
322
323          /*
324           * Unpack attributes and do sanity check them
325           */
326          if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
327             goto bail_out;
328          }
329          if (file_index != attr->file_index) {
330             Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
331                  file_index, attr->file_index);
332             Dmsg0(100, "File index error\n");
333             goto bail_out;
334          }
335
336          Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
337                attr->attr, attr->attrEx);
338
339          attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
340
341          if (!is_restore_stream_supported(attr->data_stream)) {
342             if (!non_support_data++) {
343                Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
344                   stream_to_ascii(attr->data_stream));
345             }
346             continue;
347          }
348
349          build_attr_output_fnames(jcr, attr);
350
351          /*
352           * Try to actually create the file, which returns a status telling
353           *  us if we need to extract or not.
354           */
355          jcr->num_files_examined++;
356          extract = false;
357          if (jcr->plugin) {
358             stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
359          } else {
360             stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
361          }
362          Dmsg2(30, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
363          switch (stat) {
364          case CF_ERROR:
365          case CF_SKIP:
366             break;
367          case CF_EXTRACT:        /* File created and we expect file data */
368             extract = true;
369             /* FALLTHROUGH */
370          case CF_CREATED:        /* File created, but there is no content */
371             jcr->lock();  
372             pm_strcpy(jcr->last_fname, attr->ofname);
373             jcr->last_type = attr->type;
374             jcr->JobFiles++;
375             jcr->unlock();
376             rctx.fileAddr = 0;
377             print_ls_output(jcr, attr);
378
379             if (have_darwin_os) {
380                /* Only restore the resource fork for regular files */
381                from_base64(&rsrc_len, attr->attrEx);
382                if (attr->type == FT_REG && rsrc_len > 0) {
383                   extract = true;
384                }
385             }
386             if (!extract) {
387                /* set attributes now because file will not be extracted */
388                if (jcr->plugin) {
389                   plugin_set_attributes(jcr, attr, &rctx.bfd);
390                } else {
391                   set_attributes(jcr, attr, &rctx.bfd);
392                }
393             }
394             break;
395          }
396          break;
397
398       /* Data stream */
399       case STREAM_ENCRYPTED_SESSION_DATA:
400          crypto_error_t cryptoerr;
401
402          /* Is this an unexpected session data entry? */
403          if (rctx.cs) {
404             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
405             extract = false;
406             bclose(&rctx.bfd);
407             continue;
408          }
409
410          /* Do we have any keys at all? */
411          if (!jcr->crypto.pki_recipients) {
412             Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
413             extract = false;
414             bclose(&rctx.bfd);
415             break;
416          }
417
418          if (jcr->crypto.digest) {
419             crypto_digest_free(jcr->crypto.digest);
420          }  
421          jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
422          if (!jcr->crypto.digest) {
423             Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
424             extract = false;
425             bclose(&rctx.bfd);
426             break;
427          }
428
429          /* Decode and save session keys. */
430          cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, 
431                         jcr->crypto.pki_recipients, &rctx.cs);
432          switch(cryptoerr) {
433          case CRYPTO_ERROR_NONE:
434             /* Success */
435             break;
436          case CRYPTO_ERROR_NORECIPIENT:
437             Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
438             break;
439          case CRYPTO_ERROR_DECRYPTION:
440             Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
441             break;
442          default:
443             /* Shouldn't happen */
444             Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
445             break;
446          }
447
448          if (cryptoerr != CRYPTO_ERROR_NONE) {
449             extract = false;
450             bclose(&rctx.bfd);
451             continue;
452          }
453
454          break;
455
456       case STREAM_FILE_DATA:
457       case STREAM_SPARSE_DATA:
458       case STREAM_WIN32_DATA:
459       case STREAM_GZIP_DATA:
460       case STREAM_SPARSE_GZIP_DATA:
461       case STREAM_WIN32_GZIP_DATA:
462       case STREAM_ENCRYPTED_FILE_DATA:
463       case STREAM_ENCRYPTED_WIN32_DATA:
464       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
465       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
466          /* Force an expected, consistent stream type here */
467          if (extract && (rctx.prev_stream == rctx.stream 
468                          || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
469                          || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
470                          || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
471             rctx.flags = 0;
472
473             if (rctx.stream == STREAM_SPARSE_DATA || 
474                 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
475                rctx.flags |= FO_SPARSE;
476             }
477
478             if (rctx.stream == STREAM_GZIP_DATA 
479                   || rctx.stream == STREAM_SPARSE_GZIP_DATA
480                   || rctx.stream == STREAM_WIN32_GZIP_DATA
481                   || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
482                   || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
483                rctx.flags |= FO_GZIP;
484             }
485
486             if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
487                   || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
488                   || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
489                   || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {               
490                /* Set up a decryption context */
491                if (!rctx.cipher_ctx.cipher) {
492                   if (!rctx.cs) {
493                      Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
494                      extract = false;
495                      bclose(&rctx.bfd);
496                      continue;
497                   }
498
499                   if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, 
500                            &rctx.cipher_ctx.block_size)) == NULL) {
501                      Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
502                      free_session(rctx);
503                      extract = false;
504                      bclose(&rctx.bfd);
505                      continue;
506                   }
507                }
508                rctx.flags |= FO_ENCRYPT;
509             }
510
511             if (is_win32_stream(rctx.stream) && !have_win32_api()) {
512                set_portable_backup(&rctx.bfd);
513                rctx.flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
514             }
515
516             if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr, 
517                              rctx.flags, &rctx.cipher_ctx) < 0) {
518                extract = false;
519                bclose(&rctx.bfd);
520                continue;
521             }
522          }
523          break;
524
525       /* Resource fork stream - only recorded after a file to be restored */
526       /* Silently ignore if we cannot write - we already reported that */
527       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
528       case STREAM_MACOS_FORK_DATA:
529 #ifdef HAVE_DARWIN_OS
530          rctx.fork_flags = 0;
531          jcr->ff->flags |= FO_HFSPLUS;
532
533          if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
534             rctx.fork_flags |= FO_ENCRYPT;
535
536             /* Set up a decryption context */
537             if (extract && !rctx.fork_cipher_ctx.cipher) {
538                if (!rctx.cs) {
539                   Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
540                   extract = false;
541                   bclose(&rctx.bfd);
542                   continue;
543                }
544
545                if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
546                   Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
547                   free_session(rctx);
548                   extract = false;
549                   bclose(&rctx.bfd);
550                   continue;
551                }
552             }
553          }
554
555          if (extract) {
556             if (rctx.prev_stream != rctx.stream) {
557                if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
558                   Jmsg(jcr, M_ERROR, 0, _("     Cannot open resource fork for %s.\n"), jcr->last_fname);
559                   extract = false;
560                   continue;
561                }
562
563                rctx.fork_size = rsrc_len;
564                Dmsg0(30, "Restoring resource fork\n");
565             }
566
567             if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, 
568                              &rctx.fork_cipher_ctx) < 0) {
569                extract = false;
570                bclose(&rctx.forkbfd);
571                continue;
572             }
573          }
574 #else
575          non_support_rsrc++;
576 #endif
577          break;
578
579       case STREAM_HFSPLUS_ATTRIBUTES:
580 #ifdef HAVE_DARWIN_OS
581          Dmsg0(30, "Restoring Finder Info\n");
582          jcr->ff->flags |= FO_HFSPLUS;
583          if (sd->msglen != 32) {
584             Jmsg(jcr, M_ERROR, 0, _("     Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
585             continue;
586          }
587          if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
588             Jmsg(jcr, M_ERROR, 0, _("     Could not set Finder Info on %s\n"), jcr->last_fname);
589             continue;
590          }
591 #else
592          non_support_finfo++;
593 #endif
594          break;
595
596       case STREAM_UNIX_ACCESS_ACL:
597          if (have_acl) {
598             pm_strcpy(jcr->acl_text, sd->msg);
599             Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
600             if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
601                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
602             }
603          } else {
604             non_support_acl++;
605          }
606          break;
607
608       case STREAM_UNIX_DEFAULT_ACL:
609          if (have_acl) {
610             pm_strcpy(jcr->acl_text, sd->msg);
611             Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
612             if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
613                Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
614             }
615          } else {
616             non_support_acl++;
617          }
618          break;
619
620       case STREAM_SIGNED_DIGEST:
621          /* Is this an unexpected signature? */
622          if (rctx.sig) {
623             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
624             free_signature(rctx);
625             continue;
626          }
627          /* Save signature. */
628          if (extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
629             Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
630          }
631          break;
632
633       case STREAM_MD5_DIGEST:
634       case STREAM_SHA1_DIGEST:
635       case STREAM_SHA256_DIGEST:
636       case STREAM_SHA512_DIGEST:
637          break;
638
639       case STREAM_PROGRAM_NAMES:
640       case STREAM_PROGRAM_DATA:
641          if (!non_support_progname) {
642             Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
643             non_support_progname++;
644          }
645          break;
646
647       case STREAM_PLUGIN_NAME:
648          plugin_name_stream(jcr, sd->msg);
649          break;
650
651       default:
652          /* If extracting, wierd stream (not 1 or 2), close output file anyway */
653          if (extract) {
654             Dmsg1(30, "Found wierd stream %d\n", rctx.stream);
655             if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
656                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
657             }
658             /* Flush and deallocate cipher context */
659             deallocate_cipher(rctx);
660             deallocate_fork_cipher(rctx);
661
662             if (jcr->plugin) {
663                plugin_set_attributes(jcr, attr, &rctx.bfd);
664             } else {
665                set_attributes(jcr, attr, &rctx.bfd);
666             }
667
668             /* Verify the cryptographic signature if any */
669             rctx.type = attr->type;
670             verify_signature(jcr, rctx);
671             extract = false;
672          } else if (is_bopen(&rctx.bfd)) {
673             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
674             bclose(&rctx.bfd);
675          }
676          Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
677               rctx.stream);
678          Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
679          break;
680       } /* end switch(stream) */
681
682    } /* end while get_msg() */
683
684    /* If output file is still open, it was the last one in the
685     * archive since we just hit an end of file, so close the file.
686     */
687    if (is_bopen(&rctx.forkbfd)) {
688       bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
689    }
690    if (extract) {
691       /* Flush and deallocate cipher context */
692       deallocate_cipher(rctx);
693       deallocate_fork_cipher(rctx);
694
695       if (jcr->plugin) {
696          plugin_set_attributes(jcr, attr, &rctx.bfd);
697       } else {
698          set_attributes(jcr, attr, &rctx.bfd);
699       }
700
701       /* Verify the cryptographic signature on the last file, if any */
702       rctx.type = attr->type;
703       verify_signature(jcr, rctx);
704    }
705
706    if (is_bopen(&rctx.bfd)) {
707       bclose(&rctx.bfd);
708    }
709
710    set_jcr_job_status(jcr, JS_Terminated);
711    goto ok_out;
712
713 bail_out:
714    set_jcr_job_status(jcr, JS_ErrorTerminated);
715
716 ok_out:
717    /* Free Signature & Crypto Data */
718    free_signature(rctx);
719    free_session(rctx);
720    if (jcr->crypto.digest) {
721       crypto_digest_free(jcr->crypto.digest);
722       jcr->crypto.digest = NULL;
723    }
724
725    /* Free file cipher restore context */
726    if (rctx.cipher_ctx.cipher) {
727       crypto_cipher_free(rctx.cipher_ctx.cipher);
728       rctx.cipher_ctx.cipher = NULL;
729    }
730    if (rctx.cipher_ctx.buf) {
731       free_pool_memory(rctx.cipher_ctx.buf);
732       rctx.cipher_ctx.buf = NULL;
733    }
734
735    /* Free alternate stream cipher restore context */
736    if (rctx.fork_cipher_ctx.cipher) {
737       crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
738       rctx.fork_cipher_ctx.cipher = NULL;
739    }
740    if (rctx.fork_cipher_ctx.buf) {
741       free_pool_memory(rctx.fork_cipher_ctx.buf);
742       rctx.fork_cipher_ctx.buf = NULL;
743    }
744
745    if (jcr->compress_buf) {
746       free(jcr->compress_buf);
747       jcr->compress_buf = NULL;
748       jcr->compress_buf_size = 0;
749    }
750    bclose(&rctx.forkbfd);
751    bclose(&rctx.bfd);
752    free_attr(attr);
753    free_pool_memory(jcr->acl_text);
754    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
755       edit_uint64(jcr->JobBytes, ec1));
756    if (non_support_data > 1 || non_support_attr > 1) {
757       Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
758          non_support_data, non_support_attr);
759    }
760    if (non_support_rsrc) {
761       Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
762    }
763    if (non_support_finfo) {
764       Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
765    }
766    if (non_support_acl) {
767       Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
768    }
769    if (non_support_crypto) {
770       Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
771    }
772
773 }
774
775 #ifdef HAVE_LIBZ
776 /*
777  * Convert ZLIB error code into an ASCII message
778  */
779 static const char *zlib_strerror(int stat)
780 {
781    if (stat >= 0) {
782       return _("None");
783    }
784    switch (stat) {
785    case Z_ERRNO:
786       return _("Zlib errno");
787    case Z_STREAM_ERROR:
788       return _("Zlib stream error");
789    case Z_DATA_ERROR:
790       return _("Zlib data error");
791    case Z_MEM_ERROR:
792       return _("Zlib memory error");
793    case Z_BUF_ERROR:
794       return _("Zlib buffer error");
795    case Z_VERSION_ERROR:
796       return _("Zlib version error");
797    default:
798       return _("*none*");
799    }
800 }
801 #endif
802
803 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level) 
804 {
805    Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
806    return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
807 }
808
809 /*
810  * Verify the signature for the last restored file
811  * Return value is either true (signature correct)
812  * or false (signature could not be verified).
813  * TODO landonf: Implement without using find_one_file and
814  * without re-reading the file.
815  */
816 static bool verify_signature(JCR *jcr, r_ctx &rctx)
817 {
818    X509_KEYPAIR *keypair;
819    DIGEST *digest = NULL;
820    crypto_error_t err;
821    uint64_t saved_bytes;
822    crypto_digest_t signing_algorithm = have_sha2 ? 
823                                        CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
824    crypto_digest_t algorithm;
825    SIGNATURE *sig = rctx.sig;
826
827
828    if (!jcr->crypto.pki_sign) {
829       return true;                    /* no signature OK */
830    }
831    if (!sig) {
832       if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) { 
833          Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), 
834                jcr->last_fname);
835          goto bail_out;
836       }
837       return true;
838    }
839
840    /* Iterate through the trusted signers */
841    foreach_alist(keypair, jcr->crypto.pki_signers) {
842       err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
843       switch (err) {
844       case CRYPTO_ERROR_NONE:
845          Dmsg0(50, "== Got digest\n");
846          /*
847           * We computed jcr->crypto.digest using signing_algorithm while writing
848           * the file. If it is not the same as the algorithm used for 
849           * this file, punt by releasing the computed algorithm and 
850           * computing by re-reading the file.
851           */
852          if (algorithm != signing_algorithm) {
853             if (jcr->crypto.digest) {
854                crypto_digest_free(jcr->crypto.digest);
855                jcr->crypto.digest = NULL;
856             }  
857          }
858          if (jcr->crypto.digest) {
859              /* Use digest computed while writing the file to verify the signature */
860             if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
861                Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
862                Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), 
863                      jcr->last_fname, crypto_strerror(err));
864                goto bail_out;
865             }
866          } else {   
867             /* Signature found, digest allocated.  Old method, 
868              * re-read the file and compute the digest
869              */
870             jcr->crypto.digest = digest;
871
872             /* Checksum the entire file */
873             /* Make sure we don't modify JobBytes by saving and restoring it */
874             saved_bytes = jcr->JobBytes;                     
875             if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
876                Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"), 
877                     jcr->last_fname);
878                jcr->JobBytes = saved_bytes;
879                goto bail_out;
880             }
881             jcr->JobBytes = saved_bytes;
882
883             /* Verify the signature */
884             if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
885                Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
886                Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), 
887                      jcr->last_fname, crypto_strerror(err));
888                goto bail_out;
889             }
890             jcr->crypto.digest = NULL;
891          }
892
893          /* Valid signature */
894          Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
895          crypto_digest_free(digest);
896          return true;
897
898       case CRYPTO_ERROR_NOSIGNER:
899          /* Signature not found, try again */
900          if (digest) {
901             crypto_digest_free(digest);
902             digest = NULL;
903          }
904          continue;
905       default:
906          /* Something strange happened (that shouldn't happen!)... */
907          Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
908          goto bail_out;
909       }
910    }
911
912    /* No signer */
913    Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
914
915 bail_out:
916    if (digest) {
917       crypto_digest_free(digest);
918    }
919    return false;
920 }
921
922 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
923 {
924       unser_declare;
925       uint64_t faddr;
926       char ec1[50];
927       unser_begin(*data, SPARSE_FADDR_SIZE);
928       unser_uint64(faddr);
929       if (*addr != faddr) {
930          *addr = faddr;
931          if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
932             berrno be;
933             Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
934                   edit_uint64(*addr, ec1), jcr->last_fname, 
935                   be.bstrerror(bfd->berrno));
936             return false;
937          }
938       }
939       *data += SPARSE_FADDR_SIZE;
940       *length -= SPARSE_FADDR_SIZE;
941       return true;
942 }
943
944 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
945 {
946 #ifdef HAVE_LIBZ
947    uLong compress_len;
948    int stat;
949    char ec1[50];                      /* Buffer printing huge values */
950
951    /* 
952     * NOTE! We only use uLong and Byte because they are
953     *  needed by the zlib routines, they should not otherwise
954     *  be used in Bacula.
955     */
956    compress_len = jcr->compress_buf_size;
957    Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
958    if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
959                (const Byte *)*data, (uLong)*length)) != Z_OK) {
960       Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
961             jcr->last_fname, zlib_strerror(stat));
962       return false;
963    }
964    *data = jcr->compress_buf;
965    *length = compress_len;
966    Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
967    return true;
968 #else
969    Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
970    return false;
971 #endif
972 }
973
974 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
975 {
976    unser_declare;
977    if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
978       unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
979       unser_uint32(ctx->packet_len);
980       ctx->packet_len += CRYPTO_LEN_SIZE;
981    }
982 }
983
984 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
985 {
986    if (jcr->crypto.digest) {
987       crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
988    }
989    if (win32_decomp) {
990       if (!processWin32BackupAPIBlock(bfd, data, length)) {
991          berrno be;
992          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
993                jcr->last_fname, be.bstrerror(bfd->berrno));
994          return false;
995       }
996    } else if (bwrite(bfd, data, length) != (ssize_t)length) {
997       berrno be;
998       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
999             jcr->last_fname, be.bstrerror(bfd->berrno));
1000       return false;
1001    }
1002
1003    return true;
1004 }
1005
1006 /*
1007  * In the context of jcr, write data to bfd.
1008  * We write buflen bytes in buf at addr. addr is updated in place.
1009  * The flags specify whether to use sparse files or compression.
1010  * Return value is the number of bytes written, or -1 on errors.
1011  */
1012 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
1013       uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1014 {
1015    char *wbuf;                        /* write buffer */
1016    uint32_t wsize;                    /* write size */
1017    uint32_t rsize;                    /* read size */
1018    uint32_t decrypted_len = 0;        /* Decryption output length */
1019    char ec1[50];                      /* Buffer printing huge values */
1020
1021    rsize = buflen;
1022    jcr->ReadBytes += rsize;
1023    wsize = rsize;
1024    wbuf = buf;
1025
1026    if (flags & FO_ENCRYPT) {
1027       ASSERT(cipher_ctx->cipher);
1028
1029       /* NOTE: We must implement block preserving semantics for the
1030        * non-streaming compression and sparse code. */
1031
1032       /*
1033        * Grow the crypto buffer, if necessary.
1034        * crypto_cipher_update() will process only whole blocks,
1035        * buffering the remaining input.
1036        */
1037       cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, 
1038                         cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1039
1040       /* Decrypt the input block */
1041       if (!crypto_cipher_update(cipher_ctx->cipher, 
1042                                 (const u_int8_t *)wbuf, 
1043                                 wsize, 
1044                                 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len], 
1045                                 &decrypted_len)) {
1046          /* Decryption failed. Shouldn't happen. */
1047          Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1048          return -1;
1049       }
1050
1051       if (decrypted_len == 0) {
1052          /* No full block of encrypted data available, write more data */
1053          return 0;
1054       }
1055
1056       Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1057
1058       cipher_ctx->buf_len += decrypted_len;
1059       wbuf = cipher_ctx->buf;
1060
1061       /* If one full preserved block is available, write it to disk,
1062        * and then buffer any remaining data. This should be effecient
1063        * as long as Bacula's block size is not significantly smaller than the
1064        * encryption block size (extremely unlikely!) */
1065       unser_crypto_packet_len(cipher_ctx);
1066       Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1067
1068       if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1069          /* No full preserved block is available. */
1070          return 0;
1071       }
1072
1073       /* We have one full block, set up the filter input buffers */
1074       wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1075       wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1076       cipher_ctx->buf_len -= cipher_ctx->packet_len;
1077       Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1078    }
1079
1080    if (flags & FO_SPARSE) {
1081       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1082          return -1;
1083       }
1084    }
1085
1086    if (flags & FO_GZIP) {
1087       if (!decompress_data(jcr, &wbuf, &wsize)) {
1088          return -1;
1089       }
1090    }
1091
1092    if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1093       return -1;
1094    }
1095    jcr->JobBytes += wsize;
1096    *addr += wsize;
1097    Dmsg2(30, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1098
1099    /* Clean up crypto buffers */
1100    if (flags & FO_ENCRYPT) {
1101       /* Move any remaining data to start of buffer */
1102       if (cipher_ctx->buf_len > 0) {
1103          Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1104          memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], 
1105             cipher_ctx->buf_len);
1106       }
1107       /* The packet was successfully written, reset the length so that the next
1108        * packet length may be re-read by unser_crypto_packet_len() */
1109       cipher_ctx->packet_len = 0;
1110    }
1111
1112    return wsize;
1113 }
1114
1115 /*
1116  * In the context of jcr, flush any remaining data from the cipher context,
1117  * writing it to bfd.
1118  * Return value is true on success, false on failure.
1119  */
1120 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1121                   RESTORE_CIPHER_CTX *cipher_ctx)
1122 {
1123    uint32_t decrypted_len = 0;
1124    char *wbuf;                        /* write buffer */
1125    uint32_t wsize;                    /* write size */
1126    char ec1[50];                      /* Buffer printing huge values */
1127    bool second_pass = false;
1128
1129 again:
1130    /* Write out the remaining block and free the cipher context */
1131    cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len + 
1132                      cipher_ctx->block_size);
1133
1134    if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1135         &decrypted_len)) {
1136       /* Writing out the final, buffered block failed. Shouldn't happen. */
1137       Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"), 
1138             cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1139    }
1140
1141    Dmsg2(30, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1142    /* If nothing new was decrypted, and our output buffer is empty, return */
1143    if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1144       return true;
1145    }
1146
1147    cipher_ctx->buf_len += decrypted_len;
1148
1149    unser_crypto_packet_len(cipher_ctx);
1150    Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1151    wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1152    wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1153    cipher_ctx->buf_len -= cipher_ctx->packet_len;
1154    Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1155
1156    if (flags & FO_SPARSE) {
1157       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1158          return false;
1159       }
1160    }
1161
1162    if (flags & FO_GZIP) {
1163       if (!decompress_data(jcr, &wbuf, &wsize)) {
1164          return false;
1165       }
1166    }
1167
1168    Dmsg0(30, "Call store_data\n");
1169    if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1170       return false;
1171    }
1172    jcr->JobBytes += wsize;
1173    Dmsg2(30, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1174
1175    /* Move any remaining data to start of buffer */
1176    if (cipher_ctx->buf_len > 0) {
1177       Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1178       memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], 
1179          cipher_ctx->buf_len);
1180    }
1181    /* The packet was successfully written, reset the length so that the next
1182     * packet length may be re-read by unser_crypto_packet_len() */
1183    cipher_ctx->packet_len = 0;
1184
1185    if (cipher_ctx->buf_len >0 && !second_pass) {
1186       second_pass = true;
1187       goto again;
1188    }
1189
1190    /* Stop decryption */
1191    cipher_ctx->buf_len = 0;
1192    cipher_ctx->packet_len = 0;
1193
1194    return true;
1195 }
1196
1197 static void deallocate_cipher(r_ctx &rctx)
1198 {
1199    /* Flush and deallocate previous stream's cipher context */
1200    if (rctx.cipher_ctx.cipher) {
1201       flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1202       crypto_cipher_free(rctx.cipher_ctx.cipher);
1203       rctx.cipher_ctx.cipher = NULL;
1204    }
1205 }
1206
1207 static void deallocate_fork_cipher(r_ctx &rctx)
1208 {
1209
1210    /* Flush and deallocate previous stream's fork cipher context */
1211    if (rctx.fork_cipher_ctx.cipher) {
1212       flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1213       crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1214       rctx.fork_cipher_ctx.cipher = NULL;
1215    }
1216 }
1217
1218 static void free_signature(r_ctx &rctx)
1219 {
1220    if (rctx.sig) {
1221       crypto_sign_free(rctx.sig);
1222       rctx.sig = NULL;
1223    }
1224 }
1225
1226 static void free_session(r_ctx &rctx)
1227 {
1228    if (rctx.cs) {
1229       crypto_session_free(rctx.cs);
1230       rctx.cs = NULL;
1231    }
1232 }
1233
1234
1235 /* This code if implemented goes above */
1236 #ifdef stbernard_implemented
1237 /  #if defined(HAVE_WIN32)
1238    bool        bResumeOfmOnExit = FALSE;
1239    if (isOpenFileManagerRunning()) {
1240        if ( pauseOpenFileManager() ) {
1241           Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1242           bResumeOfmOnExit = TRUE;
1243        }
1244        else {
1245           Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1246        }
1247    }
1248    {
1249        char username[UNLEN+1];
1250        DWORD usize = sizeof(username);
1251        int privs = enable_backup_privileges(NULL, 1);
1252        if (GetUserName(username, &usize)) {
1253           Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1254        } else {
1255           Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
1256        }
1257    }
1258 #endif