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