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