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