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