]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/restore.c
- Start implementing Christopher's St.Bernard code.
[bacula/bacula] / bacula / src / filed / restore.c
1 /*
2  *  Bacula File Daemon  restore.c Restorefiles.
3  *
4  *    Kern Sibbald, November MM
5  *
6  *   Version $Id$
7  *
8  */
9 /*
10    Copyright (C) 2000-2005 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "filed.h"
26
27 #ifdef HAVE_DARWIN_OS
28 #include <sys/attr.h>
29 #endif
30
31 /* Data received from Storage Daemon */
32 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
33
34 /* Forward referenced functions */
35 #ifdef HAVE_LIBZ
36 static const char *zlib_strerror(int stat);
37 #endif
38
39 int verify_signature(JCR *jcr, SIGNATURE *sig);
40 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
41       uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size);
42 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size);
43
44 #define RETRY 10                      /* retry wait time */
45
46 /*
47  * Close a bfd check that we are at the expected file offset.
48  * Makes some code in set_attributes().
49  */
50 int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize)
51 {
52    char ec1[50], ec2[50];
53    off_t fsize;
54
55    fsize = blseek(bfd, 0, SEEK_CUR);
56    bclose(bfd);                              /* first close file */
57    if (fsize > 0 && fsize != osize) {
58       Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
59             jcr->last_fname, edit_uint64(osize, ec1),
60             edit_uint64(fsize, ec2));
61       return -1;
62    }
63    return 0;
64 }
65
66 /*
67  * Restore the requested files.
68  *
69  */
70 void do_restore(JCR *jcr)
71 {
72    BSOCK *sd;
73    int32_t stream = 0;
74    int32_t prev_stream;
75    uint32_t VolSessionId, VolSessionTime;
76    bool extract = false;
77    int32_t file_index;
78    char ec1[50];                      /* Buffer printing huge values */
79
80    BFILE bfd;                         /* File content */
81    uint64_t fileAddr = 0;             /* file write address */
82    uint32_t size;                     /* Size of file */
83    BFILE altbfd;                      /* Alternative data stream */
84    uint64_t alt_addr = 0;             /* Write address for alternative stream */
85    intmax_t alt_size = 0;             /* Size of alternate stream */
86    SIGNATURE *sig = NULL;             /* Cryptographic signature (if any) for file */
87    CRYPTO_SESSION *cs = NULL;         /* Cryptographic session data (if any) for file */
88    CIPHER_CONTEXT *cipher_ctx = NULL; /* Cryptographic cipher context (if any) for file */
89    size_t cipher_block_size = 0;      /* Cryptographic algorithm block size for file */
90    int flags = 0;                     /* Options for extract_data() */
91    int stat;
92    ATTR *attr;
93
94    /* The following variables keep track of "known unknowns" */
95    int non_support_data = 0;
96    int non_support_attr = 0;
97    int non_support_rsrc = 0;
98    int non_support_finfo = 0;
99    int non_support_acl = 0;
100    int non_support_progname = 0;
101
102    /* Finally, set up for special configurations */
103 #ifdef HAVE_DARWIN_OS
104    intmax_t rsrc_len = 0;             /* Original length of resource fork */
105    struct attrlist attrList;
106
107    memset(&attrList, 0, sizeof(attrList));
108    attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
109    attrList.commonattr = ATTR_CMN_FNDRINFO;
110 #endif
111
112    sd = jcr->store_bsock;
113    set_jcr_job_status(jcr, JS_Running);
114
115    LockRes();
116    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
117    UnlockRes();
118    uint32_t buf_size;
119    if (client) {
120       buf_size = client->max_network_buffer_size;
121    } else {
122       buf_size = 0;                   /* use default */
123    }
124    if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
125       set_jcr_job_status(jcr, JS_ErrorTerminated);
126       return;
127    }
128    jcr->buf_size = sd->msglen;
129
130 #ifdef stbernard_implemented
131 /  #if defined(HAVE_WIN32)
132    bool        bResumeOfmOnExit = FALSE;
133    if (isOpenFileManagerRunning()) {
134        if ( pauseOpenFileManager() ) {
135           Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
136           bResumeOfmOnExit = TRUE;
137        }
138        else {
139           Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
140        }
141    }
142    {
143        char username[UNLEN+1];
144        DWORD usize = sizeof(username);
145        int privs = enable_backup_privileges(NULL, 1);
146        if (GetUserName(username, &usize)) {
147           Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
148        } else {
149           Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
150        }
151    }
152 #endif
153
154 #ifdef HAVE_LIBZ
155    uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
156    jcr->compress_buf = (char *)bmalloc(compress_buf_size);
157    jcr->compress_buf_size = compress_buf_size;
158 #endif
159
160 #ifdef HAVE_CRYPTO
161    jcr->crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
162 #endif
163    
164    /*
165     * Get a record from the Storage daemon. We are guaranteed to
166     *   receive records in the following order:
167     *   1. Stream record header
168     *   2. Stream data
169     *        a. Attributes (Unix or Win32)
170     *        b. Possibly stream encryption session data (e.g., symmetric session key)
171     *    or  c. File data for the file
172     *    or  d. Alternate data stream (e.g. Resource Fork)
173     *    or  e. Finder info
174     *    or  f. ACLs
175     *    or  g. Possibly a cryptographic signature
176     *    or  h. Possibly MD5 or SHA1 record
177     *   3. Repeat step 1
178     *
179     * NOTE: We keep track of two bacula file descriptors:
180     *   1. bfd for file data.
181     *      This fd is opened for non empty files when an attribute stream is
182     *      encountered and closed when we find the next attribute stream.
183     *   2. alt_bfd for alternate data streams
184     *      This fd is opened every time we encounter a new alternate data
185     *      stream for the current file. When we find any other stream, we
186     *      close it again.
187     *      The expected size of the stream, alt_len, should be set when
188     *      opening the fd.
189     */
190    binit(&bfd);
191    binit(&altbfd);
192    attr = new_attr();
193    jcr->acl_text = get_pool_memory(PM_MESSAGE);
194
195    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
196       /* Remember previous stream type */
197       prev_stream = stream;
198
199       /* First we expect a Stream Record Header */
200       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
201           &stream, &size) != 5) {
202          Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
203          goto bail_out;
204       }
205       Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
206
207       /* * Now we expect the Stream Data */
208       if (bget_msg(sd) < 0) {
209          Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
210          goto bail_out;
211       }
212       if (size != (uint32_t)sd->msglen) {
213          Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
214          goto bail_out;
215       }
216       Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
217
218       /* If we change streams, close and reset alternate data streams */
219       if (prev_stream != stream) {
220          if (is_bopen(&altbfd)) {
221             bclose_chksize(jcr, &altbfd, alt_size);
222          }
223          alt_size = -1; /* Use an impossible value and set a proper one below */
224          alt_addr = 0;
225       }
226
227       /* File Attributes stream */
228       switch (stream) {
229       case STREAM_UNIX_ATTRIBUTES:
230       case STREAM_UNIX_ATTRIBUTES_EX:
231          Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
232          /*
233           * If extracting, it was from previous stream, so
234           * close the output file and validate the signature.
235           */
236          if (extract) {
237             if (size > 0 && !is_bopen(&bfd)) {
238                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
239             }
240             /* Flush and deallocate previous stream's cipher context */
241             if (cipher_ctx && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
242                flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
243                crypto_cipher_free(cipher_ctx);
244                cipher_ctx = NULL;
245             }
246             set_attributes(jcr, attr, &bfd);
247             extract = false;
248
249             /* Verify the cryptographic signature, if any */
250             if (jcr->pki_sign) {
251                if (sig) {
252                   // Failure is reported in verify_signature() ...
253                   verify_signature(jcr, sig);
254                } else {
255                   Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
256                }
257             }
258             /* Free Signature */
259             if (sig) {
260                crypto_sign_free(sig);
261                sig = NULL;
262             }
263             if (cs) {
264                crypto_session_free(cs);
265                cs = NULL;
266             }
267             Dmsg0(30, "Stop extracting.\n");
268          } else if (is_bopen(&bfd)) {
269             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
270             bclose(&bfd);
271          }
272
273          /*
274           * Unpack and do sanity check fo attributes.
275           */
276          if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
277             goto bail_out;
278          }
279          if (file_index != attr->file_index) {
280             Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
281                  file_index, attr->file_index);
282             Dmsg0(100, "File index error\n");
283             goto bail_out;
284          }
285
286          Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
287                attr->attr, attr->attrEx);
288
289          attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
290
291          if (!is_restore_stream_supported(attr->data_stream)) {
292             if (!non_support_data++) {
293                Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
294                   stream_to_ascii(attr->data_stream));
295             }
296             continue;
297          }
298
299          build_attr_output_fnames(jcr, attr);
300
301          /*
302           * Now determine if we are extracting or not.
303           */
304          jcr->num_files_examined++;
305          Dmsg1(30, "Outfile=%s\n", attr->ofname);
306          extract = false;
307          stat = create_file(jcr, attr, &bfd, jcr->replace);
308          switch (stat) {
309          case CF_ERROR:
310          case CF_SKIP:
311             break;
312          case CF_EXTRACT:        /* File created and we expect file data */
313             extract = true;
314             /* FALLTHROUGH */
315          case CF_CREATED:        /* File created, but there is no content */
316             jcr->lock();  
317             pm_strcpy(jcr->last_fname, attr->ofname);
318             jcr->JobFiles++;
319             jcr->unlock();
320             fileAddr = 0;
321             print_ls_output(jcr, attr);
322 #ifdef HAVE_DARWIN_OS
323             /* Only restore the resource fork for regular files */
324             from_base64(&rsrc_len, attr->attrEx);
325             if (attr->type == FT_REG && rsrc_len > 0) {
326                extract = true;
327             }
328 #endif
329             if (!extract) {
330                /* set attributes now because file will not be extracted */
331                set_attributes(jcr, attr, &bfd);
332             }
333             break;
334          }
335          break;
336
337       /* Data stream */
338       case STREAM_ENCRYPTED_SESSION_DATA:
339          crypto_error_t cryptoerr;
340
341          Dmsg1(30, "Stream=Encrypted Session Data, size: %d\n", sd->msglen);
342
343          /* Decode and save session keys. */
344          cryptoerr = crypto_session_decode(sd->msg, (size_t) sd->msglen, jcr->pki_recipients, &cs);
345          switch(cryptoerr) {
346          case CRYPTO_ERROR_NONE:
347             /* Success */
348             break;
349          case CRYPTO_ERROR_NORECIPIENT:
350             Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
351             break;
352          case CRYPTO_ERROR_DECRYPTION:
353             Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
354             break;
355          default:
356             /* Shouldn't happen */
357             Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
358             break;
359          }
360
361          if (cryptoerr != CRYPTO_ERROR_NONE) {
362             extract = false;
363             bclose(&bfd);
364             continue;
365          }
366
367          /* Set up a decryption context */
368          if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
369             Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
370             crypto_session_free(cs);
371             cs = NULL;
372             extract = false;
373             bclose(&bfd);
374             continue;
375          }
376          break;
377
378       case STREAM_FILE_DATA:
379       case STREAM_SPARSE_DATA:
380       case STREAM_WIN32_DATA:
381       case STREAM_GZIP_DATA:
382       case STREAM_SPARSE_GZIP_DATA:
383       case STREAM_WIN32_GZIP_DATA:
384       case STREAM_ENCRYPTED_FILE_DATA:
385       case STREAM_ENCRYPTED_WIN32_DATA:
386       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
387       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
388          /* Force an expected, consistent stream type here */
389          if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
390                   || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
391                   || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
392             flags = 0;
393
394             if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
395                flags |= FO_SPARSE;
396             }
397
398             if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
399                   || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
400                   || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
401                flags |= FO_GZIP;
402             }
403
404             if (stream == STREAM_ENCRYPTED_FILE_DATA
405                   || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
406                   || stream == STREAM_ENCRYPTED_WIN32_DATA
407                   || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
408                flags |= FO_ENCRYPT;
409             }
410
411             if (is_win32_stream(stream) && !have_win32_api()) {
412                set_portable_backup(&bfd);
413                flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
414             }
415
416             if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
417                extract = false;
418                bclose(&bfd);
419                continue;
420             }
421          }
422          break;
423
424       /* Resource fork stream - only recorded after a file to be restored */
425       /* Silently ignore if we cannot write - we already reported that */
426       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
427          flags |= FO_ENCRYPT;
428       case STREAM_MACOS_FORK_DATA:
429 #ifdef HAVE_DARWIN_OS
430          if (extract) {
431             if (prev_stream != stream) {
432                if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
433                   Jmsg(jcr, M_ERROR, 0, _("     Cannot open resource fork for %s.\n"), jcr->last_fname);
434                   extract = false;
435                   continue;
436                }
437                alt_size = rsrc_len;
438                Dmsg0(30, "Restoring resource fork\n");
439             }
440             flags = 0;
441             if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
442                extract = false;
443                bclose(&altbfd);
444                continue;
445             }
446          }
447 #else
448          non_support_rsrc++;
449 #endif
450          break;
451
452       case STREAM_HFSPLUS_ATTRIBUTES:
453 #ifdef HAVE_DARWIN_OS
454          Dmsg0(30, "Restoring Finder Info\n");
455          if (sd->msglen != 32) {
456             Jmsg(jcr, M_ERROR, 0, _("     Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
457             continue;
458          }
459          if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
460             Jmsg(jcr, M_ERROR, 0, _("     Could not set Finder Info on %s\n"), jcr->last_fname);
461             continue;
462          }
463 #else
464          non_support_finfo++;
465 #endif
466
467       case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
468 #ifdef HAVE_ACL
469          pm_strcpy(jcr->acl_text, sd->msg);
470          Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
471          if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
472                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
473          }
474 #else 
475          non_support_acl++;
476 #endif
477          break;
478
479       case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
480 #ifdef HAVE_ACL
481          pm_strcpy(jcr->acl_text, sd->msg);
482          Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
483          if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
484                Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
485          }
486 #else 
487          non_support_acl++;
488 #endif
489          break;
490
491       case STREAM_SIGNED_DIGEST:
492          /* Save signature. */
493          if ((sig = crypto_sign_decode(sd->msg, (size_t) sd->msglen)) == NULL) {
494             Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
495          }
496          break;
497
498       case STREAM_MD5_DIGEST:
499       case STREAM_SHA1_DIGEST:
500       case STREAM_SHA256_DIGEST:
501       case STREAM_SHA512_DIGEST:
502          break;
503
504       case STREAM_PROGRAM_NAMES:
505       case STREAM_PROGRAM_DATA:
506          if (!non_support_progname) {
507             Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
508             non_support_progname++;
509          }
510          break;
511
512       default:
513          /* If extracting, wierd stream (not 1 or 2), close output file anyway */
514          if (extract) {
515             Dmsg1(30, "Found wierd stream %d\n", stream);
516             if (size > 0 && !is_bopen(&bfd)) {
517                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
518             }
519             /* Flush and deallocate cipher context */
520             if (cipher_ctx) {
521                flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
522                crypto_cipher_free(cipher_ctx);
523                cipher_ctx = NULL;
524             }
525             set_attributes(jcr, attr, &bfd);
526
527             /* Verify the cryptographic signature if any */
528             if (jcr->pki_sign) {
529                if (sig) {
530                   // Failure is reported in verify_signature() ...
531                   verify_signature(jcr, sig);
532                } else {
533                   Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
534                }
535             }
536
537             extract = false;
538          } else if (is_bopen(&bfd)) {
539             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
540             bclose(&bfd);
541          }
542          Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
543          Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
544          break;
545       } /* end switch(stream) */
546
547    } /* end while get_msg() */
548
549    /* If output file is still open, it was the last one in the
550     * archive since we just hit an end of file, so close the file.
551     */
552    if (is_bopen(&altbfd)) {
553       bclose_chksize(jcr, &altbfd, alt_size);
554    }
555    if (extract) {
556       /* Flush and deallocate cipher context */
557       if (cipher_ctx) {
558          flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
559          crypto_cipher_free(cipher_ctx);
560          cipher_ctx = NULL;
561       }
562       set_attributes(jcr, attr, &bfd);
563
564       /* Verify the cryptographic signature on the last file, if any */
565       if (jcr->pki_sign) {
566          if (sig) {
567             // Failure is reported in verify_signature() ...
568             verify_signature(jcr, sig);
569          } else {
570             Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
571          }
572       }
573    }
574
575    if (is_bopen(&bfd)) {
576       bclose(&bfd);
577    }
578
579    set_jcr_job_status(jcr, JS_Terminated);
580    goto ok_out;
581
582 bail_out:
583    set_jcr_job_status(jcr, JS_ErrorTerminated);
584 ok_out:
585
586    /* Free Signature & Crypto Data */
587    if (sig) {
588       crypto_sign_free(sig);
589       sig = NULL;
590    }
591    if (cs) {
592       crypto_session_free(cs);
593       cs = NULL;
594    }
595    if (cipher_ctx) {
596       crypto_cipher_free(cipher_ctx);
597       cipher_ctx = NULL;
598    }
599    if (jcr->compress_buf) {
600       free(jcr->compress_buf);
601       jcr->compress_buf = NULL;
602       jcr->compress_buf_size = 0;
603    }
604    if (jcr->crypto_buf) {
605       free_pool_memory(jcr->crypto_buf);
606       jcr->crypto_buf = NULL;
607    }
608    bclose(&altbfd);
609    bclose(&bfd);
610    free_attr(attr);
611    free_pool_memory(jcr->acl_text);
612    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
613       edit_uint64(jcr->JobBytes, ec1));
614    if (non_support_data > 1 || non_support_attr > 1) {
615       Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
616          non_support_data, non_support_attr);
617    }
618    if (non_support_rsrc) {
619       Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
620    }
621    if (non_support_finfo) {
622       Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
623    }
624    if (non_support_acl) {
625       Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
626    }
627
628 }
629
630 #ifdef HAVE_LIBZ
631 /*
632  * Convert ZLIB error code into an ASCII message
633  */
634 static const char *zlib_strerror(int stat)
635 {
636    if (stat >= 0) {
637       return _("None");
638    }
639    switch (stat) {
640    case Z_ERRNO:
641       return _("Zlib errno");
642    case Z_STREAM_ERROR:
643       return _("Zlib stream error");
644    case Z_DATA_ERROR:
645       return _("Zlib data error");
646    case Z_MEM_ERROR:
647       return _("Zlib memory error");
648    case Z_BUF_ERROR:
649       return _("Zlib buffer error");
650    case Z_VERSION_ERROR:
651       return _("Zlib version error");
652    default:
653       return _("*none*");
654    }
655 }
656 #endif
657
658 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) {
659    JCR *jcr = (JCR *) pkt;
660    return (digest_file(jcr, ff_pkt, jcr->digest));
661 }
662
663 /*
664  * Verify the signature for the last restored file
665  * Return value is either true (signature correct)
666  * or false (signature could not be verified).
667  * TODO landonf: Better signature failure handling.
668  */
669 int verify_signature(JCR *jcr, SIGNATURE *sig)
670 {
671    X509_KEYPAIR *keypair;
672    DIGEST *digest = NULL;
673    crypto_error_t err;
674
675    /* Iterate through the trusted signers */
676    foreach_alist(keypair, jcr->pki_signers) {
677       err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
678
679       switch (err) {
680       case CRYPTO_ERROR_NONE:
681          /* Signature found, digest allocated */
682          jcr->digest = digest;
683
684          /* Checksum the entire file */
685          if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
686             Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
687             return false;
688          }
689
690          /* Verify the signature */
691          if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
692             Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
693             Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
694             crypto_digest_free(digest);
695             return false;
696          }
697
698          /* Valid signature */
699          Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
700          crypto_digest_free(digest);
701          return true;
702
703       case CRYPTO_ERROR_NOSIGNER:
704          /* Signature not found, try again */
705          continue;
706       default:
707          /* Something strange happened (that shouldn't happen!)... */
708          Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
709          if (digest) {
710             crypto_digest_free(digest);
711          }
712          return false;
713       }
714    }
715
716    /* No signer */
717    Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
718    crypto_digest_free(digest);
719    return false;
720 }
721
722 /*
723  * In the context of jcr, write data to bfd.
724  * We write buflen bytes in buf at addr. addr is updated in place.
725  * The flags specify whether to use sparse files or compression.
726  * Return value is the number of bytes written, or -1 on errors.
727  */
728 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
729       uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
730 {
731    int stat;
732    char *wbuf;                        /* write buffer */
733    uint32_t wsize;                    /* write size */
734    uint32_t rsize;                    /* read size */
735    char ec1[50];                      /* Buffer printing huge values */
736    const void *cipher_input;          /* Decryption input */
737    size_t cipher_input_len;           /* Decryption input length */
738    size_t decrypted_len = 0;          /* Decryption output length */
739
740    if (flags & FO_SPARSE) {
741       ser_declare;
742       uint64_t faddr;
743       char ec1[50];
744       wbuf = buf + SPARSE_FADDR_SIZE;
745       rsize = buflen - SPARSE_FADDR_SIZE;
746       ser_begin(buf, SPARSE_FADDR_SIZE);
747       unser_uint64(faddr);
748       if (*addr != faddr) {
749          *addr = faddr;
750          if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
751             berrno be;
752             Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
753                   edit_uint64(*addr, ec1), jcr->last_fname, 
754                   be.strerror(bfd->berrno));
755             return -1;
756          }
757       }
758    } else {
759       wbuf = buf;
760       rsize = buflen;
761    }
762    wsize = rsize;
763    cipher_input = wbuf;
764    cipher_input_len = wsize;
765
766    if (flags & FO_GZIP) {
767 #ifdef HAVE_LIBZ
768       uLong compress_len;
769       /* 
770        * NOTE! We only use uLong and Byte because they are
771        *  needed by the zlib routines, they should not otherwise
772        *  be used in Bacula.
773        */
774       compress_len = jcr->compress_buf_size;
775       Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
776       if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
777                   (const Byte *)wbuf, (uLong)rsize)) != Z_OK) {
778          Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
779                jcr->last_fname, zlib_strerror(stat));
780          return -1;
781       }
782       wbuf = jcr->compress_buf;
783       wsize = compress_len;
784       cipher_input = jcr->compress_buf; /* decrypt decompressed data */
785       cipher_input_len = compress_len;
786       Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
787 #else
788       Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
789       return -1;
790 #endif
791    } else {
792       Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
793    }
794
795    if (flags & FO_ENCRYPT) {
796       ASSERT(cipher);
797
798       /*
799        * Grow the crypto buffer, if necessary.
800        * crypto_cipher_update() will process only whole blocks,
801        * buffering the remaining input.
802        */
803       jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_input_len + cipher_block_size);
804
805
806       /* Encrypt the input block */
807       if (!crypto_cipher_update(cipher, cipher_input, cipher_input_len, jcr->crypto_buf, &decrypted_len)) {
808          /* Decryption failed. Shouldn't happen. */
809          Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
810          return -1;
811       }
812
813       if (decrypted_len == 0) {
814          /* No full block of data available, write more data */
815          goto ok;
816       }
817
818       Dmsg2(400, "decrypted len=%d undecrypted len=%d\n",
819          decrypted_len, cipher_input_len);
820       wsize = decrypted_len;
821       wbuf = jcr->crypto_buf; /* Decrypted, possibly decompressed output here. */
822    }
823
824
825    if (flags & FO_WIN32DECOMP) {
826       if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
827          berrno be;
828          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
829                jcr->last_fname, be.strerror(bfd->berrno));
830          return -1;
831       }
832    } else if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
833       berrno be;
834       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
835             jcr->last_fname, be.strerror(bfd->berrno));
836       return -1;
837    }
838
839    if (decrypted_len && decrypted_len > wsize) {
840       /* If more than wsize is output, it was previously buffered
841        * and reported, and should not be reported again */
842       wsize = wsize - decrypted_len;
843    }
844
845 ok:
846    jcr->JobBytes += wsize;
847    jcr->ReadBytes += rsize;
848    *addr += wsize;
849
850    return wsize;
851 }
852
853 /*
854  * In the context of jcr, flush any remaining data from the cipher context,
855  * writing it to bfd.
856  * Return value is true on success, false on failure.
857  */
858 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
859 {
860    size_t decrypted_len;
861
862    /* Write out the remaining block and free the cipher context */
863    jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_block_size);
864
865    if (!crypto_cipher_finalize(cipher, jcr->crypto_buf, &decrypted_len)) {
866       /* Writing out the final, buffered block failed. Shouldn't happen. */
867       Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
868    }
869
870    if (flags & FO_WIN32DECOMP) {
871       if (!processWin32BackupAPIBlock(bfd, jcr->crypto_buf, decrypted_len)) {
872          berrno be;
873          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
874                jcr->last_fname, be.strerror(bfd->berrno));
875          return false;
876       }
877    } else if (bwrite(bfd, jcr->crypto_buf, decrypted_len) != (ssize_t)decrypted_len) {
878       berrno be;
879       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
880             jcr->last_fname, be.strerror(bfd->berrno));
881       return false;
882    }
883
884    return true;
885 }