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