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