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