]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/restore.c
630e80ce9ca287361d927cbd0c83fab6078f8f8e
[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, size_t cipher_block_size);
51 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_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    size_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          /* Decode and save session keys. */
354          cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (size_t)sd->msglen, jcr->pki_recipients, &cs);
355          switch(cryptoerr) {
356          case CRYPTO_ERROR_NONE:
357             /* Success */
358             break;
359          case CRYPTO_ERROR_NORECIPIENT:
360             Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
361             break;
362          case CRYPTO_ERROR_DECRYPTION:
363             Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
364             break;
365          default:
366             /* Shouldn't happen */
367             Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
368             break;
369          }
370
371          if (cryptoerr != CRYPTO_ERROR_NONE) {
372             extract = false;
373             bclose(&bfd);
374             continue;
375          }
376
377          /* Set up a decryption context */
378          if ((cipher_ctx = crypto_cipher_new(cs, false, &cipher_block_size)) == NULL) {
379             Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
380             crypto_session_free(cs);
381             cs = NULL;
382             extract = false;
383             bclose(&bfd);
384             continue;
385          }
386          break;
387
388       case STREAM_FILE_DATA:
389       case STREAM_SPARSE_DATA:
390       case STREAM_WIN32_DATA:
391       case STREAM_GZIP_DATA:
392       case STREAM_SPARSE_GZIP_DATA:
393       case STREAM_WIN32_GZIP_DATA:
394       case STREAM_ENCRYPTED_FILE_DATA:
395       case STREAM_ENCRYPTED_WIN32_DATA:
396       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
397       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
398          /* Force an expected, consistent stream type here */
399          if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
400                   || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
401                   || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
402             flags = 0;
403
404             if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
405                flags |= FO_SPARSE;
406             }
407
408             if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
409                   || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
410                   || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
411                flags |= FO_GZIP;
412             }
413
414             if (stream == STREAM_ENCRYPTED_FILE_DATA
415                   || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
416                   || stream == STREAM_ENCRYPTED_WIN32_DATA
417                   || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
418                flags |= FO_ENCRYPT;
419             }
420
421             if (is_win32_stream(stream) && !have_win32_api()) {
422                set_portable_backup(&bfd);
423                flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
424             }
425
426             if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags, cipher_ctx, cipher_block_size) < 0) {
427                extract = false;
428                bclose(&bfd);
429                continue;
430             }
431          }
432          break;
433
434       /* Resource fork stream - only recorded after a file to be restored */
435       /* Silently ignore if we cannot write - we already reported that */
436       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
437          flags |= FO_ENCRYPT;
438       case STREAM_MACOS_FORK_DATA:
439 #ifdef HAVE_DARWIN_OS
440          if (extract) {
441             if (prev_stream != stream) {
442                if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
443                   Jmsg(jcr, M_ERROR, 0, _("     Cannot open resource fork for %s.\n"), jcr->last_fname);
444                   extract = false;
445                   continue;
446                }
447                alt_size = rsrc_len;
448                Dmsg0(30, "Restoring resource fork\n");
449             }
450             flags = 0;
451             if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags, cipher_ctx, cipher_block_size) < 0) {
452                extract = false;
453                bclose(&altbfd);
454                continue;
455             }
456          }
457 #else
458          non_support_rsrc++;
459 #endif
460          break;
461
462       case STREAM_HFSPLUS_ATTRIBUTES:
463 #ifdef HAVE_DARWIN_OS
464          Dmsg0(30, "Restoring Finder Info\n");
465          if (sd->msglen != 32) {
466             Jmsg(jcr, M_ERROR, 0, _("     Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
467             continue;
468          }
469          if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
470             Jmsg(jcr, M_ERROR, 0, _("     Could not set Finder Info on %s\n"), jcr->last_fname);
471             continue;
472          }
473 #else
474          non_support_finfo++;
475 #endif
476
477       case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
478 #ifdef HAVE_ACL
479          pm_strcpy(jcr->acl_text, sd->msg);
480          Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
481          if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
482                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
483          }
484 #else 
485          non_support_acl++;
486 #endif
487          break;
488
489       case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
490 #ifdef HAVE_ACL
491          pm_strcpy(jcr->acl_text, sd->msg);
492          Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
493          if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
494                Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
495          }
496 #else 
497          non_support_acl++;
498 #endif
499          break;
500
501       case STREAM_SIGNED_DIGEST:
502          /* Save signature. */
503          if ((sig = crypto_sign_decode((uint8_t *)sd->msg, (size_t)sd->msglen)) == NULL) {
504             Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
505          }
506          break;
507
508       case STREAM_MD5_DIGEST:
509       case STREAM_SHA1_DIGEST:
510       case STREAM_SHA256_DIGEST:
511       case STREAM_SHA512_DIGEST:
512          break;
513
514       case STREAM_PROGRAM_NAMES:
515       case STREAM_PROGRAM_DATA:
516          if (!non_support_progname) {
517             Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
518             non_support_progname++;
519          }
520          break;
521
522       default:
523          /* If extracting, wierd stream (not 1 or 2), close output file anyway */
524          if (extract) {
525             Dmsg1(30, "Found wierd stream %d\n", stream);
526             if (size > 0 && !is_bopen(&bfd)) {
527                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
528             }
529             /* Flush and deallocate cipher context */
530             if (cipher_ctx) {
531                flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
532                crypto_cipher_free(cipher_ctx);
533                cipher_ctx = NULL;
534             }
535             set_attributes(jcr, attr, &bfd);
536
537             /* Verify the cryptographic signature if any */
538             if (jcr->pki_sign) {
539                if (sig) {
540                   // Failure is reported in verify_signature() ...
541                   verify_signature(jcr, sig);
542                } else {
543                   Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
544                }
545             }
546
547             extract = false;
548          } else if (is_bopen(&bfd)) {
549             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
550             bclose(&bfd);
551          }
552          Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
553          Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
554          break;
555       } /* end switch(stream) */
556
557    } /* end while get_msg() */
558
559    /* If output file is still open, it was the last one in the
560     * archive since we just hit an end of file, so close the file.
561     */
562    if (is_bopen(&altbfd)) {
563       bclose_chksize(jcr, &altbfd, alt_size);
564    }
565    if (extract) {
566       /* Flush and deallocate cipher context */
567       if (cipher_ctx) {
568          flush_cipher(jcr, &bfd, flags, cipher_ctx, cipher_block_size);
569          crypto_cipher_free(cipher_ctx);
570          cipher_ctx = NULL;
571       }
572       set_attributes(jcr, attr, &bfd);
573
574       /* Verify the cryptographic signature on the last file, if any */
575       if (jcr->pki_sign) {
576          if (sig) {
577             // Failure is reported in verify_signature() ...
578             verify_signature(jcr, sig);
579          } else {
580             Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
581          }
582       }
583    }
584
585    if (is_bopen(&bfd)) {
586       bclose(&bfd);
587    }
588
589    set_jcr_job_status(jcr, JS_Terminated);
590    goto ok_out;
591
592 bail_out:
593    set_jcr_job_status(jcr, JS_ErrorTerminated);
594 ok_out:
595
596    /* Free Signature & Crypto Data */
597    if (sig) {
598       crypto_sign_free(sig);
599       sig = NULL;
600    }
601    if (cs) {
602       crypto_session_free(cs);
603       cs = NULL;
604    }
605    if (cipher_ctx) {
606       crypto_cipher_free(cipher_ctx);
607       cipher_ctx = NULL;
608    }
609    if (jcr->compress_buf) {
610       free(jcr->compress_buf);
611       jcr->compress_buf = NULL;
612       jcr->compress_buf_size = 0;
613    }
614    if (jcr->crypto_buf) {
615       free_pool_memory(jcr->crypto_buf);
616       jcr->crypto_buf = NULL;
617    }
618    bclose(&altbfd);
619    bclose(&bfd);
620    free_attr(attr);
621    free_pool_memory(jcr->acl_text);
622    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
623       edit_uint64(jcr->JobBytes, ec1));
624    if (non_support_data > 1 || non_support_attr > 1) {
625       Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
626          non_support_data, non_support_attr);
627    }
628    if (non_support_rsrc) {
629       Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
630    }
631    if (non_support_finfo) {
632       Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
633    }
634    if (non_support_acl) {
635       Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
636    }
637
638 }
639
640 /*
641  * Convert ZLIB error code into an ASCII message
642  */
643 static const char *zlib_strerror(int stat)
644 {
645    if (stat >= 0) {
646       return _("None");
647    }
648    switch (stat) {
649    case Z_ERRNO:
650       return _("Zlib errno");
651    case Z_STREAM_ERROR:
652       return _("Zlib stream error");
653    case Z_DATA_ERROR:
654       return _("Zlib data error");
655    case Z_MEM_ERROR:
656       return _("Zlib memory error");
657    case Z_BUF_ERROR:
658       return _("Zlib buffer error");
659    case Z_VERSION_ERROR:
660       return _("Zlib version error");
661    default:
662       return _("*none*");
663    }
664 }
665
666 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) 
667 {
668    JCR *jcr = (JCR *)pkt;
669    return (digest_file(jcr, ff_pkt, jcr->digest));
670 }
671
672 /*
673  * Verify the signature for the last restored file
674  * Return value is either true (signature correct)
675  * or false (signature could not be verified).
676  * TODO landonf: Better signature failure handling.
677  */
678 int verify_signature(JCR *jcr, SIGNATURE *sig)
679 {
680    X509_KEYPAIR *keypair;
681    DIGEST *digest = NULL;
682    crypto_error_t err;
683
684    /* Iterate through the trusted signers */
685    foreach_alist(keypair, jcr->pki_signers) {
686       err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
687
688       switch (err) {
689       case CRYPTO_ERROR_NONE:
690          /* Signature found, digest allocated */
691          jcr->digest = digest;
692
693          /* Checksum the entire file */
694          if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
695             Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
696             return false;
697          }
698
699          /* Verify the signature */
700          if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
701             Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
702             Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
703             crypto_digest_free(digest);
704             return false;
705          }
706
707          /* Valid signature */
708          Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
709          crypto_digest_free(digest);
710          return true;
711
712       case CRYPTO_ERROR_NOSIGNER:
713          /* Signature not found, try again */
714          continue;
715       default:
716          /* Something strange happened (that shouldn't happen!)... */
717          Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
718          if (digest) {
719             crypto_digest_free(digest);
720          }
721          return false;
722       }
723    }
724
725    /* No signer */
726    Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
727    crypto_digest_free(digest);
728    return false;
729 }
730
731 /*
732  * In the context of jcr, write data to bfd.
733  * We write buflen bytes in buf at addr. addr is updated in place.
734  * The flags specify whether to use sparse files or compression.
735  * Return value is the number of bytes written, or -1 on errors.
736  */
737 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
738       uint64_t *addr, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
739 {
740    int stat;
741    char *wbuf;                        /* write buffer */
742    uint32_t wsize;                    /* write size */
743    uint32_t rsize;                    /* read size */
744    char ec1[50];                      /* Buffer printing huge values */
745    const uint8_t *cipher_input;       /* Decryption input */
746    uint32_t cipher_input_len;         /* Decryption input length */
747    uint32_t decrypted_len = 0;        /* Decryption output length */
748
749    if (flags & FO_SPARSE) {
750       ser_declare;
751       uint64_t faddr;
752       char ec1[50];
753       wbuf = buf + SPARSE_FADDR_SIZE;
754       rsize = buflen - SPARSE_FADDR_SIZE;
755       ser_begin(buf, SPARSE_FADDR_SIZE);
756       unser_uint64(faddr);
757       if (*addr != faddr) {
758          *addr = faddr;
759          if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
760             berrno be;
761             Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
762                   edit_uint64(*addr, ec1), jcr->last_fname, 
763                   be.strerror(bfd->berrno));
764             return -1;
765          }
766       }
767    } else {
768       wbuf = buf;
769       rsize = buflen;
770    }
771    wsize = rsize;
772    cipher_input = (uint8_t *)wbuf;
773    cipher_input_len = (uint32_t)wsize;
774
775    if (flags & FO_GZIP) {
776 #ifdef HAVE_LIBZ
777       uLong compress_len;
778       /* 
779        * NOTE! We only use uLong and Byte because they are
780        *  needed by the zlib routines, they should not otherwise
781        *  be used in Bacula.
782        */
783       compress_len = jcr->compress_buf_size;
784       Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
785       if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
786                   (const Byte *)wbuf, (uLong)rsize)) != Z_OK) {
787          Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
788                jcr->last_fname, zlib_strerror(stat));
789          return -1;
790       }
791       wbuf = jcr->compress_buf;
792       wsize = compress_len;
793       cipher_input = (uint8_t *)jcr->compress_buf; /* decrypt decompressed data */
794       cipher_input_len = compress_len;
795       Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
796 #else
797       Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
798       return -1;
799 #endif
800    } else {
801       Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
802    }
803
804    if (flags & FO_ENCRYPT) {
805       ASSERT(cipher);
806
807       /*
808        * Grow the crypto buffer, if necessary.
809        * crypto_cipher_update() will process only whole blocks,
810        * buffering the remaining input.
811        */
812       jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_input_len + cipher_block_size);
813
814
815       /* Encrypt the input block */
816       if (!crypto_cipher_update(cipher, cipher_input, cipher_input_len, (uint8_t *)jcr->crypto_buf, &decrypted_len)) {
817          /* Decryption failed. Shouldn't happen. */
818          Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
819          return -1;
820       }
821
822       if (decrypted_len == 0) {
823          /* No full block of data available, write more data */
824          goto ok;
825       }
826
827       Dmsg2(400, "decrypted len=%d undecrypted len=%d\n",
828          decrypted_len, cipher_input_len);
829       wsize = decrypted_len;
830       wbuf = jcr->crypto_buf; /* Decrypted, possibly decompressed output here. */
831    }
832
833
834    if (flags & FO_WIN32DECOMP) {
835       if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
836          berrno be;
837          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
838                jcr->last_fname, be.strerror(bfd->berrno));
839          return -1;
840       }
841    } else if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
842       berrno be;
843       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
844             jcr->last_fname, be.strerror(bfd->berrno));
845       return -1;
846    }
847
848    if (decrypted_len && decrypted_len > wsize) {
849       /* If more than wsize is output, it was previously buffered
850        * and reported, and should not be reported again */
851       wsize = wsize - decrypted_len;
852    }
853
854 ok:
855    jcr->JobBytes += wsize;
856    jcr->ReadBytes += rsize;
857    *addr += wsize;
858
859    return wsize;
860 }
861
862 /*
863  * In the context of jcr, flush any remaining data from the cipher context,
864  * writing it to bfd.
865  * Return value is true on success, false on failure.
866  */
867 bool flush_cipher(JCR *jcr, BFILE *bfd, int flags, CIPHER_CONTEXT *cipher, size_t cipher_block_size)
868 {
869    size_t decrypted_len;
870
871    /* Write out the remaining block and free the cipher context */
872    jcr->crypto_buf = check_pool_memory_size(jcr->crypto_buf, cipher_block_size);
873
874    if (!crypto_cipher_finalize(cipher, (uint8_t *)jcr->crypto_buf, &decrypted_len)) {
875       /* Writing out the final, buffered block failed. Shouldn't happen. */
876       Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
877    }
878
879    if (flags & FO_WIN32DECOMP) {
880       if (!processWin32BackupAPIBlock(bfd, jcr->crypto_buf, decrypted_len)) {
881          berrno be;
882          Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
883                jcr->last_fname, be.strerror(bfd->berrno));
884          return false;
885       }
886    } else if (bwrite(bfd, jcr->crypto_buf, decrypted_len) != (ssize_t)decrypted_len) {
887       berrno be;
888       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
889             jcr->last_fname, be.strerror(bfd->berrno));
890       return false;
891    }
892
893    return true;
894 }