]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/restore.c
ebl Commit accurate patch project.
[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          /* TODO: manage deleted files */
324          if (rctx.type == FT_DELETED) { /* deleted file */
325             continue;
326          }
327
328          /*
329           * Unpack attributes and do sanity check them
330           */
331          if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
332             goto bail_out;
333          }
334          if (file_index != attr->file_index) {
335             Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
336                  file_index, attr->file_index);
337             Dmsg0(100, "File index error\n");
338             goto bail_out;
339          }
340
341          Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
342                attr->attr, attr->attrEx);
343
344          attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
345
346          if (!is_restore_stream_supported(attr->data_stream)) {
347             if (!non_support_data++) {
348                Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
349                   stream_to_ascii(attr->data_stream));
350             }
351             continue;
352          }
353
354          build_attr_output_fnames(jcr, attr);
355
356          /*
357           * Try to actually create the file, which returns a status telling
358           *  us if we need to extract or not.
359           */
360          jcr->num_files_examined++;
361          extract = false;
362          if (jcr->plugin) {
363             stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
364          } else {
365             stat = create_file(jcr, attr, &rctx.bfd, jcr->replace);
366          }
367          Dmsg2(30, "Outfile=%s create_file stat=%d\n", attr->ofname, stat);
368          switch (stat) {
369          case CF_ERROR:
370          case CF_SKIP:
371             break;
372          case CF_EXTRACT:        /* File created and we expect file data */
373             extract = true;
374             /* FALLTHROUGH */
375          case CF_CREATED:        /* File created, but there is no content */
376             jcr->lock();  
377             pm_strcpy(jcr->last_fname, attr->ofname);
378             jcr->last_type = attr->type;
379             jcr->JobFiles++;
380             jcr->unlock();
381             rctx.fileAddr = 0;
382             print_ls_output(jcr, attr);
383
384             if (have_darwin_os) {
385                /* Only restore the resource fork for regular files */
386                from_base64(&rsrc_len, attr->attrEx);
387                if (attr->type == FT_REG && rsrc_len > 0) {
388                   extract = true;
389                }
390             }
391             if (!extract) {
392                /* set attributes now because file will not be extracted */
393                if (jcr->plugin) {
394                   plugin_set_attributes(jcr, attr, &rctx.bfd);
395                } else {
396                   set_attributes(jcr, attr, &rctx.bfd);
397                }
398             }
399             break;
400          }
401          break;
402
403       /* Data stream */
404       case STREAM_ENCRYPTED_SESSION_DATA:
405          crypto_error_t cryptoerr;
406
407          /* Is this an unexpected session data entry? */
408          if (rctx.cs) {
409             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
410             extract = false;
411             bclose(&rctx.bfd);
412             continue;
413          }
414
415          /* Do we have any keys at all? */
416          if (!jcr->crypto.pki_recipients) {
417             Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
418             extract = false;
419             bclose(&rctx.bfd);
420             break;
421          }
422
423          if (jcr->crypto.digest) {
424             crypto_digest_free(jcr->crypto.digest);
425          }  
426          jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm);
427          if (!jcr->crypto.digest) {
428             Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
429             extract = false;
430             bclose(&rctx.bfd);
431             break;
432          }
433
434          /* Decode and save session keys. */
435          cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, 
436                         jcr->crypto.pki_recipients, &rctx.cs);
437          switch(cryptoerr) {
438          case CRYPTO_ERROR_NONE:
439             /* Success */
440             break;
441          case CRYPTO_ERROR_NORECIPIENT:
442             Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n"));
443             break;
444          case CRYPTO_ERROR_DECRYPTION:
445             Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n"));
446             break;
447          default:
448             /* Shouldn't happen */
449             Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr));
450             break;
451          }
452
453          if (cryptoerr != CRYPTO_ERROR_NONE) {
454             extract = false;
455             bclose(&rctx.bfd);
456             continue;
457          }
458
459          break;
460
461       case STREAM_FILE_DATA:
462       case STREAM_SPARSE_DATA:
463       case STREAM_WIN32_DATA:
464       case STREAM_GZIP_DATA:
465       case STREAM_SPARSE_GZIP_DATA:
466       case STREAM_WIN32_GZIP_DATA:
467       case STREAM_ENCRYPTED_FILE_DATA:
468       case STREAM_ENCRYPTED_WIN32_DATA:
469       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
470       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
471          /* Force an expected, consistent stream type here */
472          if (extract && (rctx.prev_stream == rctx.stream 
473                          || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
474                          || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
475                          || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
476             rctx.flags = 0;
477
478             if (rctx.stream == STREAM_SPARSE_DATA || 
479                 rctx.stream == STREAM_SPARSE_GZIP_DATA) {
480                rctx.flags |= FO_SPARSE;
481             }
482
483             if (rctx.stream == STREAM_GZIP_DATA 
484                   || rctx.stream == STREAM_SPARSE_GZIP_DATA
485                   || rctx.stream == STREAM_WIN32_GZIP_DATA
486                   || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
487                   || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
488                rctx.flags |= FO_GZIP;
489             }
490
491             if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
492                   || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
493                   || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
494                   || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {               
495                /* Set up a decryption context */
496                if (!rctx.cipher_ctx.cipher) {
497                   if (!rctx.cs) {
498                      Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
499                      extract = false;
500                      bclose(&rctx.bfd);
501                      continue;
502                   }
503
504                   if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, 
505                            &rctx.cipher_ctx.block_size)) == NULL) {
506                      Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
507                      free_session(rctx);
508                      extract = false;
509                      bclose(&rctx.bfd);
510                      continue;
511                   }
512                }
513                rctx.flags |= FO_ENCRYPT;
514             }
515
516             if (is_win32_stream(rctx.stream) && !have_win32_api()) {
517                set_portable_backup(&rctx.bfd);
518                rctx.flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
519             }
520
521             if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr, 
522                              rctx.flags, &rctx.cipher_ctx) < 0) {
523                extract = false;
524                bclose(&rctx.bfd);
525                continue;
526             }
527          }
528          break;
529
530       /* Resource fork stream - only recorded after a file to be restored */
531       /* Silently ignore if we cannot write - we already reported that */
532       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
533       case STREAM_MACOS_FORK_DATA:
534 #ifdef HAVE_DARWIN_OS
535          rctx.fork_flags = 0;
536          jcr->ff->flags |= FO_HFSPLUS;
537
538          if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
539             rctx.fork_flags |= FO_ENCRYPT;
540
541             /* Set up a decryption context */
542             if (extract && !rctx.fork_cipher_ctx.cipher) {
543                if (!rctx.cs) {
544                   Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
545                   extract = false;
546                   bclose(&rctx.bfd);
547                   continue;
548                }
549
550                if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) {
551                   Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
552                   free_session(rctx);
553                   extract = false;
554                   bclose(&rctx.bfd);
555                   continue;
556                }
557             }
558          }
559
560          if (extract) {
561             if (rctx.prev_stream != rctx.stream) {
562                if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
563                   Jmsg(jcr, M_ERROR, 0, _("     Cannot open resource fork for %s.\n"), jcr->last_fname);
564                   extract = false;
565                   continue;
566                }
567
568                rctx.fork_size = rsrc_len;
569                Dmsg0(30, "Restoring resource fork\n");
570             }
571
572             if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, 
573                              &rctx.fork_cipher_ctx) < 0) {
574                extract = false;
575                bclose(&rctx.forkbfd);
576                continue;
577             }
578          }
579 #else
580          non_support_rsrc++;
581 #endif
582          break;
583
584       case STREAM_HFSPLUS_ATTRIBUTES:
585 #ifdef HAVE_DARWIN_OS
586          Dmsg0(30, "Restoring Finder Info\n");
587          jcr->ff->flags |= FO_HFSPLUS;
588          if (sd->msglen != 32) {
589             Jmsg(jcr, M_ERROR, 0, _("     Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
590             continue;
591          }
592          if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
593             Jmsg(jcr, M_ERROR, 0, _("     Could not set Finder Info on %s\n"), jcr->last_fname);
594             continue;
595          }
596 #else
597          non_support_finfo++;
598 #endif
599          break;
600
601       case STREAM_UNIX_ACCESS_ACL:
602          if (have_acl) {
603             pm_strcpy(jcr->acl_text, sd->msg);
604             Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
605             if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
606                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
607             }
608          } else {
609             non_support_acl++;
610          }
611          break;
612
613       case STREAM_UNIX_DEFAULT_ACL:
614          if (have_acl) {
615             pm_strcpy(jcr->acl_text, sd->msg);
616             Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
617             if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
618                Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
619             }
620          } else {
621             non_support_acl++;
622          }
623          break;
624
625       case STREAM_SIGNED_DIGEST:
626          /* Is this an unexpected signature? */
627          if (rctx.sig) {
628             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
629             free_signature(rctx);
630             continue;
631          }
632          /* Save signature. */
633          if (extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
634             Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
635          }
636          break;
637
638       case STREAM_MD5_DIGEST:
639       case STREAM_SHA1_DIGEST:
640       case STREAM_SHA256_DIGEST:
641       case STREAM_SHA512_DIGEST:
642          break;
643
644       case STREAM_PROGRAM_NAMES:
645       case STREAM_PROGRAM_DATA:
646          if (!non_support_progname) {
647             Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
648             non_support_progname++;
649          }
650          break;
651
652       case STREAM_PLUGIN_NAME:
653          Dmsg1(000, "restore stream_plugin_name=%s\n", sd->msg);
654          plugin_name_stream(jcr, sd->msg);
655          break;
656
657       default:
658          /* If extracting, wierd stream (not 1 or 2), close output file anyway */
659          if (extract) {
660             Dmsg1(30, "Found wierd stream %d\n", rctx.stream);
661             if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
662                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
663             }
664             /* Flush and deallocate cipher context */
665             deallocate_cipher(rctx);
666             deallocate_fork_cipher(rctx);
667
668             if (jcr->plugin) {
669                plugin_set_attributes(jcr, attr, &rctx.bfd);
670             } else {
671                set_attributes(jcr, attr, &rctx.bfd);
672             }
673
674             /* Verify the cryptographic signature if any */
675             rctx.type = attr->type;
676             verify_signature(jcr, rctx);
677             extract = false;
678          } else if (is_bopen(&rctx.bfd)) {
679             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
680             bclose(&rctx.bfd);
681          }
682          Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
683               rctx.stream);
684          Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
685          break;
686       } /* end switch(stream) */
687
688    } /* end while get_msg() */
689
690    /* If output file is still open, it was the last one in the
691     * archive since we just hit an end of file, so close the file.
692     */
693    if (is_bopen(&rctx.forkbfd)) {
694       bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
695    }
696    if (extract) {
697       /* Flush and deallocate cipher context */
698       deallocate_cipher(rctx);
699       deallocate_fork_cipher(rctx);
700
701       if (jcr->plugin) {
702          plugin_set_attributes(jcr, attr, &rctx.bfd);
703       } else {
704          set_attributes(jcr, attr, &rctx.bfd);
705       }
706
707       /* Verify the cryptographic signature on the last file, if any */
708       rctx.type = attr->type;
709       verify_signature(jcr, rctx);
710    }
711
712    if (is_bopen(&rctx.bfd)) {
713       bclose(&rctx.bfd);
714    }
715
716    set_jcr_job_status(jcr, JS_Terminated);
717    goto ok_out;
718
719 bail_out:
720    set_jcr_job_status(jcr, JS_ErrorTerminated);
721
722 ok_out:
723    /* Free Signature & Crypto Data */
724    free_signature(rctx);
725    free_session(rctx);
726    if (jcr->crypto.digest) {
727       crypto_digest_free(jcr->crypto.digest);
728       jcr->crypto.digest = NULL;
729    }
730
731    /* Free file cipher restore context */
732    if (rctx.cipher_ctx.cipher) {
733       crypto_cipher_free(rctx.cipher_ctx.cipher);
734       rctx.cipher_ctx.cipher = NULL;
735    }
736    if (rctx.cipher_ctx.buf) {
737       free_pool_memory(rctx.cipher_ctx.buf);
738       rctx.cipher_ctx.buf = NULL;
739    }
740
741    /* Free alternate stream cipher restore context */
742    if (rctx.fork_cipher_ctx.cipher) {
743       crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
744       rctx.fork_cipher_ctx.cipher = NULL;
745    }
746    if (rctx.fork_cipher_ctx.buf) {
747       free_pool_memory(rctx.fork_cipher_ctx.buf);
748       rctx.fork_cipher_ctx.buf = NULL;
749    }
750
751    if (jcr->compress_buf) {
752       free(jcr->compress_buf);
753       jcr->compress_buf = NULL;
754       jcr->compress_buf_size = 0;
755    }
756    bclose(&rctx.forkbfd);
757    bclose(&rctx.bfd);
758    free_attr(attr);
759    free_pool_memory(jcr->acl_text);
760    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
761       edit_uint64(jcr->JobBytes, ec1));
762    if (non_support_data > 1 || non_support_attr > 1) {
763       Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
764          non_support_data, non_support_attr);
765    }
766    if (non_support_rsrc) {
767       Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
768    }
769    if (non_support_finfo) {
770       Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
771    }
772    if (non_support_acl) {
773       Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
774    }
775    if (non_support_crypto) {
776       Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
777    }
778
779 }
780
781 #ifdef HAVE_LIBZ
782 /*
783  * Convert ZLIB error code into an ASCII message
784  */
785 static const char *zlib_strerror(int stat)
786 {
787    if (stat >= 0) {
788       return _("None");
789    }
790    switch (stat) {
791    case Z_ERRNO:
792       return _("Zlib errno");
793    case Z_STREAM_ERROR:
794       return _("Zlib stream error");
795    case Z_DATA_ERROR:
796       return _("Zlib data error");
797    case Z_MEM_ERROR:
798       return _("Zlib memory error");
799    case Z_BUF_ERROR:
800       return _("Zlib buffer error");
801    case Z_VERSION_ERROR:
802       return _("Zlib version error");
803    default:
804       return _("*none*");
805    }
806 }
807 #endif
808
809 static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level) 
810 {
811    Dmsg1(50, "do_file_digest jcr=%p\n", jcr);
812    return (digest_file(jcr, ff_pkt, jcr->crypto.digest));
813 }
814
815 /*
816  * Verify the signature for the last restored file
817  * Return value is either true (signature correct)
818  * or false (signature could not be verified).
819  * TODO landonf: Implement without using find_one_file and
820  * without re-reading the file.
821  */
822 static bool verify_signature(JCR *jcr, r_ctx &rctx)
823 {
824    X509_KEYPAIR *keypair;
825    DIGEST *digest = NULL;
826    crypto_error_t err;
827    uint64_t saved_bytes;
828    crypto_digest_t signing_algorithm = have_sha2 ? 
829                                        CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
830    crypto_digest_t algorithm;
831    SIGNATURE *sig = rctx.sig;
832
833
834    if (!jcr->crypto.pki_sign) {
835       return true;                    /* no signature OK */
836    }
837    if (!sig) {
838       if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) { 
839          Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), 
840                jcr->last_fname);
841          goto bail_out;
842       }
843       return true;
844    }
845
846    /* Iterate through the trusted signers */
847    foreach_alist(keypair, jcr->crypto.pki_signers) {
848       err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
849       switch (err) {
850       case CRYPTO_ERROR_NONE:
851          Dmsg0(50, "== Got digest\n");
852          /*
853           * We computed jcr->crypto.digest using signing_algorithm while writing
854           * the file. If it is not the same as the algorithm used for 
855           * this file, punt by releasing the computed algorithm and 
856           * computing by re-reading the file.
857           */
858          if (algorithm != signing_algorithm) {
859             if (jcr->crypto.digest) {
860                crypto_digest_free(jcr->crypto.digest);
861                jcr->crypto.digest = NULL;
862             }  
863          }
864          if (jcr->crypto.digest) {
865              /* Use digest computed while writing the file to verify the signature */
866             if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
867                Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
868                Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), 
869                      jcr->last_fname, crypto_strerror(err));
870                goto bail_out;
871             }
872          } else {   
873             /* Signature found, digest allocated.  Old method, 
874              * re-read the file and compute the digest
875              */
876             jcr->crypto.digest = digest;
877
878             /* Checksum the entire file */
879             /* Make sure we don't modify JobBytes by saving and restoring it */
880             saved_bytes = jcr->JobBytes;                     
881             if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
882                Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"), 
883                     jcr->last_fname);
884                jcr->JobBytes = saved_bytes;
885                goto bail_out;
886             }
887             jcr->JobBytes = saved_bytes;
888
889             /* Verify the signature */
890             if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
891                Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
892                Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), 
893                      jcr->last_fname, crypto_strerror(err));
894                goto bail_out;
895             }
896             jcr->crypto.digest = NULL;
897          }
898
899          /* Valid signature */
900          Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
901          crypto_digest_free(digest);
902          return true;
903
904       case CRYPTO_ERROR_NOSIGNER:
905          /* Signature not found, try again */
906          if (digest) {
907             crypto_digest_free(digest);
908             digest = NULL;
909          }
910          continue;
911       default:
912          /* Something strange happened (that shouldn't happen!)... */
913          Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
914          goto bail_out;
915       }
916    }
917
918    /* No signer */
919    Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
920
921 bail_out:
922    if (digest) {
923       crypto_digest_free(digest);
924    }
925    return false;
926 }
927
928 bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
929 {
930       unser_declare;
931       uint64_t faddr;
932       char ec1[50];
933       unser_begin(*data, SPARSE_FADDR_SIZE);
934       unser_uint64(faddr);
935       if (*addr != faddr) {
936          *addr = faddr;
937          if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
938             berrno be;
939             Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
940                   edit_uint64(*addr, ec1), jcr->last_fname, 
941                   be.bstrerror(bfd->berrno));
942             return false;
943          }
944       }
945       *data += SPARSE_FADDR_SIZE;
946       *length -= SPARSE_FADDR_SIZE;
947       return true;
948 }
949
950 bool decompress_data(JCR *jcr, char **data, uint32_t *length)
951 {
952 #ifdef HAVE_LIBZ
953    uLong compress_len;
954    int stat;
955    char ec1[50];                      /* Buffer printing huge values */
956
957    /* 
958     * NOTE! We only use uLong and Byte because they are
959     *  needed by the zlib routines, they should not otherwise
960     *  be used in Bacula.
961     */
962    compress_len = jcr->compress_buf_size;
963    Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
964    if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
965                (const Byte *)*data, (uLong)*length)) != Z_OK) {
966       Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
967             jcr->last_fname, zlib_strerror(stat));
968       return false;
969    }
970    *data = jcr->compress_buf;
971    *length = compress_len;
972    Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
973    return true;
974 #else
975    Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
976    return false;
977 #endif
978 }
979
980 static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
981 {
982    unser_declare;
983    if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
984       unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
985       unser_uint32(ctx->packet_len);
986       ctx->packet_len += CRYPTO_LEN_SIZE;
987    }
988 }
989
990 bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
991 {
992    if (jcr->crypto.digest) {
993       crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
994    }
995    if (win32_decomp) {
996       if (!processWin32BackupAPIBlock(bfd, data, length)) {
997          berrno be;
998          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
999                jcr->last_fname, be.bstrerror(bfd->berrno));
1000          return false;
1001       }
1002    } else if (bwrite(bfd, data, length) != (ssize_t)length) {
1003       berrno be;
1004       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
1005             jcr->last_fname, be.bstrerror(bfd->berrno));
1006       return false;
1007    }
1008
1009    return true;
1010 }
1011
1012 /*
1013  * In the context of jcr, write data to bfd.
1014  * We write buflen bytes in buf at addr. addr is updated in place.
1015  * The flags specify whether to use sparse files or compression.
1016  * Return value is the number of bytes written, or -1 on errors.
1017  */
1018 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
1019       uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
1020 {
1021    char *wbuf;                        /* write buffer */
1022    uint32_t wsize;                    /* write size */
1023    uint32_t rsize;                    /* read size */
1024    uint32_t decrypted_len = 0;        /* Decryption output length */
1025    char ec1[50];                      /* Buffer printing huge values */
1026
1027    rsize = buflen;
1028    jcr->ReadBytes += rsize;
1029    wsize = rsize;
1030    wbuf = buf;
1031
1032    if (flags & FO_ENCRYPT) {
1033       ASSERT(cipher_ctx->cipher);
1034
1035       /* NOTE: We must implement block preserving semantics for the
1036        * non-streaming compression and sparse code. */
1037
1038       /*
1039        * Grow the crypto buffer, if necessary.
1040        * crypto_cipher_update() will process only whole blocks,
1041        * buffering the remaining input.
1042        */
1043       cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, 
1044                         cipher_ctx->buf_len + wsize + cipher_ctx->block_size);
1045
1046       /* Decrypt the input block */
1047       if (!crypto_cipher_update(cipher_ctx->cipher, 
1048                                 (const u_int8_t *)wbuf, 
1049                                 wsize, 
1050                                 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len], 
1051                                 &decrypted_len)) {
1052          /* Decryption failed. Shouldn't happen. */
1053          Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
1054          return -1;
1055       }
1056
1057       if (decrypted_len == 0) {
1058          /* No full block of encrypted data available, write more data */
1059          return 0;
1060       }
1061
1062       Dmsg2(100, "decrypted len=%d encrypted len=%d\n", decrypted_len, wsize);
1063
1064       cipher_ctx->buf_len += decrypted_len;
1065       wbuf = cipher_ctx->buf;
1066
1067       /* If one full preserved block is available, write it to disk,
1068        * and then buffer any remaining data. This should be effecient
1069        * as long as Bacula's block size is not significantly smaller than the
1070        * encryption block size (extremely unlikely!) */
1071       unser_crypto_packet_len(cipher_ctx);
1072       Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1073
1074       if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
1075          /* No full preserved block is available. */
1076          return 0;
1077       }
1078
1079       /* We have one full block, set up the filter input buffers */
1080       wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1081       wbuf = &wbuf[CRYPTO_LEN_SIZE]; /* Skip the block length header */
1082       cipher_ctx->buf_len -= cipher_ctx->packet_len;
1083       Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1084    }
1085
1086    if (flags & FO_SPARSE) {
1087       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1088          return -1;
1089       }
1090    }
1091
1092    if (flags & FO_GZIP) {
1093       if (!decompress_data(jcr, &wbuf, &wsize)) {
1094          return -1;
1095       }
1096    }
1097
1098    if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1099       return -1;
1100    }
1101    jcr->JobBytes += wsize;
1102    *addr += wsize;
1103    Dmsg2(30, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1104
1105    /* Clean up crypto buffers */
1106    if (flags & FO_ENCRYPT) {
1107       /* Move any remaining data to start of buffer */
1108       if (cipher_ctx->buf_len > 0) {
1109          Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1110          memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], 
1111             cipher_ctx->buf_len);
1112       }
1113       /* The packet was successfully written, reset the length so that the next
1114        * packet length may be re-read by unser_crypto_packet_len() */
1115       cipher_ctx->packet_len = 0;
1116    }
1117
1118    return wsize;
1119 }
1120
1121 /*
1122  * In the context of jcr, flush any remaining data from the cipher context,
1123  * writing it to bfd.
1124  * Return value is true on success, false on failure.
1125  */
1126 bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
1127                   RESTORE_CIPHER_CTX *cipher_ctx)
1128 {
1129    uint32_t decrypted_len = 0;
1130    char *wbuf;                        /* write buffer */
1131    uint32_t wsize;                    /* write size */
1132    char ec1[50];                      /* Buffer printing huge values */
1133    bool second_pass = false;
1134
1135 again:
1136    /* Write out the remaining block and free the cipher context */
1137    cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len + 
1138                      cipher_ctx->block_size);
1139
1140    if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
1141         &decrypted_len)) {
1142       /* Writing out the final, buffered block failed. Shouldn't happen. */
1143       Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"), 
1144             cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
1145    }
1146
1147    Dmsg2(30, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
1148    /* If nothing new was decrypted, and our output buffer is empty, return */
1149    if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
1150       return true;
1151    }
1152
1153    cipher_ctx->buf_len += decrypted_len;
1154
1155    unser_crypto_packet_len(cipher_ctx);
1156    Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
1157    wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
1158    wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
1159    cipher_ctx->buf_len -= cipher_ctx->packet_len;
1160    Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
1161
1162    if (flags & FO_SPARSE) {
1163       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
1164          return false;
1165       }
1166    }
1167
1168    if (flags & FO_GZIP) {
1169       if (!decompress_data(jcr, &wbuf, &wsize)) {
1170          return false;
1171       }
1172    }
1173
1174    Dmsg0(30, "Call store_data\n");
1175    if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
1176       return false;
1177    }
1178    jcr->JobBytes += wsize;
1179    Dmsg2(30, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
1180
1181    /* Move any remaining data to start of buffer */
1182    if (cipher_ctx->buf_len > 0) {
1183       Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
1184       memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], 
1185          cipher_ctx->buf_len);
1186    }
1187    /* The packet was successfully written, reset the length so that the next
1188     * packet length may be re-read by unser_crypto_packet_len() */
1189    cipher_ctx->packet_len = 0;
1190
1191    if (cipher_ctx->buf_len >0 && !second_pass) {
1192       second_pass = true;
1193       goto again;
1194    }
1195
1196    /* Stop decryption */
1197    cipher_ctx->buf_len = 0;
1198    cipher_ctx->packet_len = 0;
1199
1200    return true;
1201 }
1202
1203 static void deallocate_cipher(r_ctx &rctx)
1204 {
1205    /* Flush and deallocate previous stream's cipher context */
1206    if (rctx.cipher_ctx.cipher) {
1207       flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
1208       crypto_cipher_free(rctx.cipher_ctx.cipher);
1209       rctx.cipher_ctx.cipher = NULL;
1210    }
1211 }
1212
1213 static void deallocate_fork_cipher(r_ctx &rctx)
1214 {
1215
1216    /* Flush and deallocate previous stream's fork cipher context */
1217    if (rctx.fork_cipher_ctx.cipher) {
1218       flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
1219       crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
1220       rctx.fork_cipher_ctx.cipher = NULL;
1221    }
1222 }
1223
1224 static void free_signature(r_ctx &rctx)
1225 {
1226    if (rctx.sig) {
1227       crypto_sign_free(rctx.sig);
1228       rctx.sig = NULL;
1229    }
1230 }
1231
1232 static void free_session(r_ctx &rctx)
1233 {
1234    if (rctx.cs) {
1235       crypto_session_free(rctx.cs);
1236       rctx.cs = NULL;
1237    }
1238 }
1239
1240
1241 /* This code if implemented goes above */
1242 #ifdef stbernard_implemented
1243 /  #if defined(HAVE_WIN32)
1244    bool        bResumeOfmOnExit = FALSE;
1245    if (isOpenFileManagerRunning()) {
1246        if ( pauseOpenFileManager() ) {
1247           Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
1248           bResumeOfmOnExit = TRUE;
1249        }
1250        else {
1251           Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
1252        }
1253    }
1254    {
1255        char username[UNLEN+1];
1256        DWORD usize = sizeof(username);
1257        int privs = enable_backup_privileges(NULL, 1);
1258        if (GetUserName(username, &usize)) {
1259           Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
1260        } else {
1261           Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
1262        }
1263    }
1264 #endif