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