From b244d71bdd2a96899160c3ad72ee6d24cab7e1e7 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 3 May 2007 17:10:55 +0000 Subject: [PATCH] kes First cut strip path. The data should be passed to the FD, but nothing is done with it yet. kes Enhance the digest and signature routines in the crypto library to accept a JCR and to use it to print error messages so that they will go in the Job report rather than the daemon's messages. kes Simplify some of the verify signature code. kes Simplify a few of the alternative returns in the signature code. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4685 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/inc_conf.c | 14 +++++- bacula/src/filed/Makefile.in | 0 bacula/src/filed/backup.c | 14 +++--- bacula/src/filed/filed.c | 22 ++++----- bacula/src/filed/job.c | 19 ++++++-- bacula/src/filed/restore.c | 84 +++++++++++++++-------------------- bacula/src/filed/verify.c | 12 ++--- bacula/src/findlib/find.c | 1 + bacula/src/findlib/find.h | 15 ++++--- bacula/src/findlib/find_one.c | 28 ++++++------ bacula/src/findlib/match.c | 30 ++++++------- bacula/src/lib/bpipe.c | 16 +++---- bacula/src/lib/bpipe.h | 12 ++--- bacula/src/lib/crypto.c | 67 +++++++++++++++++----------- bacula/src/lib/crypto.h | 38 ++++++++-------- bacula/src/lib/openssl.c | 47 +++++++++++--------- bacula/src/lib/openssl.h | 39 ++++++++-------- bacula/src/lib/protos.h | 4 +- bacula/src/version.h | 4 +- bacula/technotes-2.1 | 10 +++++ 20 files changed, 259 insertions(+), 217 deletions(-) mode change 100755 => 100644 bacula/src/filed/Makefile.in diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index c9ebc37995..14260597d5 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -121,6 +121,7 @@ static RES_ITEM options_items[] = { {"enhancedwild", store_opts, {0}, 0, 0, 0}, {"drivetype", store_drivetype, {0}, 0, 0, 0}, {"checkfilechanges",store_opts, {0}, 0, 0, 0}, + {"strippath", store_opts, {0}, 0, 0, 0}, {NULL, NULL, {0}, 0, 0, 0} }; @@ -147,7 +148,8 @@ enum { INC_KW_HFSPLUS, INC_KW_NOATIME, INC_KW_ENHANCEDWILD, - INC_KW_CHKCHANGES + INC_KW_CHKCHANGES, + INC_KW_STRIPPATH }; /* @@ -177,6 +179,7 @@ static struct s_kw FS_option_kw[] = { {"noatime", INC_KW_NOATIME}, {"enhancedwild", INC_KW_ENHANCEDWILD}, {"checkfilechanges", INC_KW_CHKCHANGES}, + {"strippath", INC_KW_STRIPPATH}, {NULL, 0} }; @@ -271,7 +274,14 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); - + } else if (keyword == INC_KW_STRIPPATH) { /* another special case */ + if (!is_an_integer(lc->str)) { + scan_err1(lc, _("Expected a strip path integer, got:%s:"), lc->str); + } + bstrncat(opts, "P", optlen); /* indicate strip path */ + bstrncat(opts, lc->str, optlen); + bstrncat(opts, ":", optlen); /* terminate it */ + Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); /* * Standard keyword options for Include/Exclude */ diff --git a/bacula/src/filed/Makefile.in b/bacula/src/filed/Makefile.in old mode 100755 new mode 100644 diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 156542bfde..4a38ef4867 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -337,19 +337,19 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) * and not used. */ if (ff_pkt->flags & FO_MD5) { - digest = crypto_digest_new(CRYPTO_DIGEST_MD5); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); digest_stream = STREAM_MD5_DIGEST; } else if (ff_pkt->flags & FO_SHA1) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA1); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); digest_stream = STREAM_SHA1_DIGEST; } else if (ff_pkt->flags & FO_SHA256) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA256); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); digest_stream = STREAM_SHA256_DIGEST; } else if (ff_pkt->flags & FO_SHA512) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA512); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); digest_stream = STREAM_SHA512_DIGEST; } @@ -365,7 +365,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) */ // TODO landonf: We should really only calculate the digest once, for both verification and signing. if (jcr->pki_sign) { - signing_digest = crypto_digest_new(signing_algorithm); + signing_digest = crypto_digest_new(jcr, signing_algorithm); /* Full-stop if a failure occurred initializing the signature digest */ if (signing_digest == NULL) { @@ -542,8 +542,8 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) if (signing_digest) { uint32_t size = 0; - if ((sig = crypto_sign_new()) == NULL) { - Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for stream signature.\n")); + if ((sig = crypto_sign_new(jcr)) == NULL) { + Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n")); goto bail_out; } diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 2d4090587c..069472e362 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -1,15 +1,7 @@ -/* - * Bacula File Daemon - * - * Kern Sibbald, March MM - * - * Version $Id$ - * - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -33,6 +25,14 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula File Daemon + * + * Kern Sibbald, March MM + * + * Version $Id$ + * + */ #include "bacula.h" #include "filed.h" @@ -42,7 +42,7 @@ extern void *handle_client_request(void *dir_sock); /* Forward referenced functions */ void terminate_filed(int sig); -static int check_resources(); +static bool check_resources(); /* Exported variables */ CLIENT *me; /* my resource */ @@ -254,7 +254,7 @@ void terminate_filed(int sig) * Make a quick check to see that we have all the * resources needed. */ -static int check_resources() +static bool check_resources() { bool OK = true; DIRRES *director; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index b75369d872..5d41d55a30 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -924,6 +924,7 @@ static void set_options(findFOPTS *fo, const char *opts) { int j; const char *p; + char strip[100]; for (p=opts; *p; p++) { switch (*p) { @@ -1009,6 +1010,18 @@ static void set_options(findFOPTS *fo, const char *opts) } fo->VerifyOpts[j] = 0; break; + case 'P': /* strip path */ + /* Get integer */ + for (j=0; *p && *p != ':'; p++) { + strip[j] = *p; + if (j < (int)sizeof(strip) - 1) { + j++; + } + } + strip[j] = 0; + fo->strip_path = atoi(strip); + fo->flags |= FO_STRIPPATH; + break; case 'w': fo->flags |= FO_IF_NEWER; break; @@ -1609,9 +1622,9 @@ static int restore_cmd(JCR *jcr) if (use_regexwhere) { jcr->where_bregexp = get_bregexps(args); if (!jcr->where_bregexp) { - Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args); - free_pool_memory(args); - return 0; + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args); + free_pool_memory(args); + return 0; } } else { jcr->where = bstrdup(args); diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index d7b56ff7ce..a85cbec6ad 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -67,7 +67,7 @@ typedef struct restore_cipher_ctx { int32_t packet_len; /* Total bytes in packet */ } RESTORE_CIPHER_CTX; -int verify_signature(JCR *jcr, SIGNATURE *sig); +static bool verify_signature(JCR *jcr, SIGNATURE *sig); int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx); bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx); @@ -302,14 +302,8 @@ void do_restore(JCR *jcr) extract = false; /* Verify the cryptographic signature, if any */ - if (jcr->pki_sign) { - if (sig) { - // Failure is reported in verify_signature() ... - verify_signature(jcr, sig); - } else { - Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname); - } - } + verify_signature(jcr, sig); + /* Free Signature */ if (sig) { crypto_sign_free(sig); @@ -604,6 +598,8 @@ void do_restore(JCR *jcr) /* Is this an unexpected signature? */ if (sig) { Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n")); + crypto_sign_free(sig); + sig = NULL; continue; } @@ -651,15 +647,7 @@ void do_restore(JCR *jcr) set_attributes(jcr, attr, &bfd); /* Verify the cryptographic signature if any */ - if (jcr->pki_sign) { - if (sig) { - // Failure is reported in verify_signature() ... - verify_signature(jcr, sig); - } else { - Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname); - } - } - + verify_signature(jcr, sig); extract = false; } else if (is_bopen(&bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); @@ -696,14 +684,7 @@ void do_restore(JCR *jcr) set_attributes(jcr, attr, &bfd); /* Verify the cryptographic signature on the last file, if any */ - if (jcr->pki_sign) { - if (sig) { - // Failure is reported in verify_signature() ... - verify_signature(jcr, sig); - } else { - Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname); - } - } + verify_signature(jcr, sig); } if (is_bopen(&bfd)) { @@ -815,17 +796,24 @@ static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) * TODO landonf: Implement without using find_one_file and * without re-reading the file. */ -int verify_signature(JCR *jcr, SIGNATURE *sig) +static bool verify_signature(JCR *jcr, SIGNATURE *sig) { X509_KEYPAIR *keypair; DIGEST *digest = NULL; crypto_error_t err; uint64_t saved_bytes; + if (!jcr->pki_sign) { + return true; /* no signature OK */ + } + if (!sig) { + Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), + jcr->last_fname); + } + /* Iterate through the trusted signers */ foreach_alist(keypair, jcr->pki_signers) { err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest); - switch (err) { case CRYPTO_ERROR_NONE: /* Signature found, digest allocated */ @@ -835,41 +823,49 @@ int verify_signature(JCR *jcr, SIGNATURE *sig) /* Make sure we don't modify JobBytes by saving and restoring it */ saved_bytes = jcr->JobBytes; if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) { - Jmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname); + Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"), + jcr->last_fname); jcr->JobBytes = saved_bytes; - return false; + goto bail_out; } jcr->JobBytes = saved_bytes; /* Verify the signature */ if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) { Dmsg1(100, "Bad signature on %s\n", jcr->last_fname); - Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err)); - crypto_digest_free(digest); - return false; + Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), + jcr->last_fname, crypto_strerror(err)); + goto bail_out; } /* Valid signature */ Dmsg1(100, "Signature good on %s\n", jcr->last_fname); crypto_digest_free(digest); + jcr->digest = NULL; return true; case CRYPTO_ERROR_NOSIGNER: /* Signature not found, try again */ + if (digest) { + crypto_digest_free(digest); + jcr->digest = NULL; + } continue; default: /* Something strange happened (that shouldn't happen!)... */ Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err)); - if (digest) { - crypto_digest_free(digest); - } - return false; + goto bail_out; } } /* No signer */ Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname); - crypto_digest_free(digest); + +bail_out: + if (digest) { + crypto_digest_free(digest); + jcr->digest = NULL; + } return false; } @@ -1071,7 +1067,7 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx) { - uint32_t decrypted_len; + uint32_t decrypted_len = 0; char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ char ec1[50]; /* Buffer printing huge values */ @@ -1104,16 +1100,6 @@ again: cipher_ctx->buf_len -= cipher_ctx->packet_len; Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len); -#ifdef xxx - Dmsg2(30, "check buf_len=%d pkt_len=%d\n", cipher_ctx->buf_len, cipher_ctx->packet_len); - if (second_pass && cipher_ctx->buf_len != cipher_ctx->packet_len) { - Jmsg2(jcr, M_FATAL, 0, - _("Unexpected number of bytes remaining at end of file, received %u, expected %u\n"), - cipher_ctx->packet_len, cipher_ctx->buf_len); - return false; - } -#endif - if (flags & FO_SPARSE) { if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) { return false; diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 5727706047..4456e42675 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -217,19 +217,19 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level) * and not used. */ if (ff_pkt->flags & FO_MD5) { - digest = crypto_digest_new(CRYPTO_DIGEST_MD5); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); digest_stream = STREAM_MD5_DIGEST; } else if (ff_pkt->flags & FO_SHA1) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA1); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); digest_stream = STREAM_SHA1_DIGEST; } else if (ff_pkt->flags & FO_SHA256) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA256); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); digest_stream = STREAM_SHA256_DIGEST; } else if (ff_pkt->flags & FO_SHA512) { - digest = crypto_digest_new(CRYPTO_DIGEST_SHA512); + digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); digest_stream = STREAM_SHA512_DIGEST; } @@ -294,7 +294,7 @@ int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest) ff_pkt->ff_errno = errno; berrno be; be.set_errno(bfd.berrno); - Jmsg(jcr, M_NOTSAVED, 1, _(" Cannot open %s: ERR=%s.\n"), + Jmsg(jcr, M_ERROR, 1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, be.strerror()); return 1; } @@ -308,7 +308,7 @@ int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest) if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; - Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), + Jmsg(jcr, M_ERROR, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname, be.strerror()); if (is_bopen(&ff_pkt->bfd)) { bclose(&ff_pkt->bfd); diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 121e37559c..a90bd9c23f 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -187,6 +187,7 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool t findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); ff->flags |= fo->flags; ff->GZIP_level = fo->GZIP_level; + ff->strip_path = fo->strip_path; ff->fstypes = fo->fstype; ff->drivetypes = fo->drivetype; bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 9c2e6b4c23..6172182f37 100644 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -1,12 +1,7 @@ -/* - * File types as returned by find_files() - * - * Kern Sibbald MMI - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2006 Free Software Foundation Europe e.V. + Copyright (C) 2001-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -30,6 +25,11 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * File types as returned by find_files() + * + * Kern Sibbald MMI + */ #ifndef __FILES_H #define __FILES_H @@ -108,6 +108,7 @@ enum { #define FO_NOATIME (1<<22) /* Use O_NOATIME to prevent atime change */ #define FO_ENHANCEDWILD (1<<23) /* Enhanced wild card processing */ #define FO_CHKCHANGES (1<<24) /* Check if file have been modified during backup */ +#define FO_STRIPPATH (1<<25) /* Check for stripping path */ struct s_included_file { struct s_included_file *next; @@ -144,6 +145,7 @@ enum { struct findFOPTS { uint32_t flags; /* options in bits */ int GZIP_level; /* GZIP level */ + int strip_path; /* strip path count */ char VerifyOpts[MAX_FOPTS]; /* verify options */ alist regex; /* regex string(s) */ alist regexdir; /* regex string(s) for directories */ @@ -216,6 +218,7 @@ struct FF_PKT { /* Values set by accept_file while processing Options */ uint32_t flags; /* backup options */ int GZIP_level; /* compression level */ + int strip_path; /* strip path count */ char *reader; /* reader program */ char *writer; /* writer program */ alist fstypes; /* allowed file system types */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index d6c25fbdee..84792fa0ea 100644 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -1,19 +1,7 @@ -/* - - This file is based on GNU TAR source code. Except for a few key - ideas, it has been entirely rewritten for Bacula. - - Kern Sibbald, MM - - Thanks to the TAR programmers. - - Version $Id$ - - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -37,6 +25,18 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + + This file was derived from GNU TAR source code. Except for a few key + ideas, it has been entirely rewritten for Bacula. + + Kern Sibbald, MM + + Thanks to the TAR programmers. + + Version $Id$ + + */ #include "bacula.h" #include "find.h" @@ -194,7 +194,7 @@ bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt) if (lstat(ff_pkt->fname, &statp) != 0) { berrno be; Jmsg(jcr, M_WARNING, 0, - _("Cannot stat file %s: ERR=%s\n"),ff_pkt->fname,be.strerror()); + _("Cannot stat file %s: ERR=%s\n"),ff_pkt->fname,be.strerror()); return true; } diff --git a/bacula/src/findlib/match.c b/bacula/src/findlib/match.c index e08c863fdf..145aa041f6 100644 --- a/bacula/src/findlib/match.c +++ b/bacula/src/findlib/match.c @@ -1,21 +1,7 @@ -/* - * Old style - * - * Routines used to keep and match include and exclude - * filename/pathname patterns. - * - * Note, this file is used for the old style include and - * excludes, so is deprecated. The new style code is - * found in find.c. - * This code is still used for lists in testls and bextract. - * - * Kern E. Sibbald, December MMI - * - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -39,6 +25,20 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Old style + * + * Routines used to keep and match include and exclude + * filename/pathname patterns. + * + * Note, this file is used for the old style include and + * excludes, so is deprecated. The new style code is + * found in find.c. + * This code is still used for lists in testls and bextract. + * + * Kern E. Sibbald, December MMI + * + */ #include "bacula.h" #include "find.h" diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index aecb3b0c51..f2de9b6835 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -1,14 +1,7 @@ -/* - * bpipe.c bi-directional pipe - * - * Kern Sibbald, November MMII - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2006 Free Software Foundation Europe e.V. + Copyright (C) 2002-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -32,6 +25,13 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * bpipe.c bi-directional pipe + * + * Kern Sibbald, November MMII + * + * Version $Id$ + */ #include "bacula.h" diff --git a/bacula/src/lib/bpipe.h b/bacula/src/lib/bpipe.h index 2d75b7e353..f5cbac3440 100644 --- a/bacula/src/lib/bpipe.h +++ b/bacula/src/lib/bpipe.h @@ -1,12 +1,7 @@ -/* - * Bi-directional pipe structure - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2006 Free Software Foundation Europe e.V. + Copyright (C) 2002-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -30,6 +25,11 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bi-directional pipe structure + * + * Version $Id$ + */ class BPIPE { public: diff --git a/bacula/src/lib/crypto.c b/bacula/src/lib/crypto.c index 83ea648fda..2dc1b9a208 100644 --- a/bacula/src/lib/crypto.c +++ b/bacula/src/lib/crypto.c @@ -46,6 +46,7 @@ #include "bacula.h" +#include "jcr.h" #include /* @@ -273,12 +274,14 @@ struct X509_Keypair { /* Message Digest Structure */ struct Digest { crypto_digest_t type; + JCR *jcr; EVP_MD_CTX ctx; }; /* Message Signature Structure */ struct Signature { SignatureData *sigData; + JCR *jcr; }; /* Encryption Session Data */ @@ -304,7 +307,7 @@ typedef struct PEM_CB_Context { * Returns: On success, an ASN1_OCTET_STRING that must be freed via M_ASN1_OCTET_STRING_free(). * NULL on failure. */ -static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert){ +static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) { X509_EXTENSION *ext; X509V3_EXT_METHOD *method; ASN1_OCTET_STRING *keyid; @@ -359,7 +362,7 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert){ * Returns: A pointer to a X509 KEYPAIR object on success. * NULL on failure. */ -X509_KEYPAIR *crypto_keypair_new (void) { +X509_KEYPAIR *crypto_keypair_new(void) { X509_KEYPAIR *keypair; /* Allocate our keypair structure */ @@ -382,7 +385,7 @@ X509_KEYPAIR *crypto_keypair_new (void) { * API is available. Instead, the reference count is * incremented. */ -X509_KEYPAIR *crypto_keypair_dup (X509_KEYPAIR *keypair) +X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair) { X509_KEYPAIR *newpair; @@ -424,7 +427,7 @@ X509_KEYPAIR *crypto_keypair_dup (X509_KEYPAIR *keypair) * Returns: true on success * false on failure */ -int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file) +int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file) { BIO *bio; X509 *cert; @@ -484,7 +487,7 @@ static int crypto_pem_callback_dispatch (char *buf, int size, int rwflag, void * * Returns: true if a private key is found * false otherwise */ -bool crypto_keypair_has_key (const char *file) { +bool crypto_keypair_has_key(const char *file) { BIO *bio; char *name = NULL; char *header = NULL; @@ -532,7 +535,7 @@ bool crypto_keypair_has_key (const char *file) { * Returns: true on success * false on failure */ -int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file, +int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { @@ -567,7 +570,7 @@ int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file, /* * Free memory associated with a keypair object. */ -void crypto_keypair_free (X509_KEYPAIR *keypair) +void crypto_keypair_free(X509_KEYPAIR *keypair) { if (keypair->pubkey) { EVP_PKEY_free(keypair->pubkey); @@ -586,13 +589,14 @@ void crypto_keypair_free (X509_KEYPAIR *keypair) * Returns: A pointer to a DIGEST object on success. * NULL on failure. */ -DIGEST *crypto_digest_new (crypto_digest_t type) +DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; const EVP_MD *md = NULL; /* Quell invalid uninitialized warnings */ digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; + digest->jcr = jcr; /* Initialize the OpenSSL message digest context */ EVP_MD_CTX_init(&digest->ctx); @@ -614,7 +618,7 @@ DIGEST *crypto_digest_new (crypto_digest_t type) break; #endif default: - Emsg1(M_ERROR, 0, _("Unsupported digest type: %d\n"), type); + Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type: %d\n"), type); goto err; } @@ -627,7 +631,7 @@ DIGEST *crypto_digest_new (crypto_digest_t type) err: /* This should not happen, but never say never ... */ - openssl_post_errors(M_ERROR, _("OpenSSL digest initialization failed")); + openssl_post_errors(jcr, M_ERROR, _("OpenSSL digest initialization failed")); crypto_digest_free(digest); return NULL; } @@ -640,6 +644,7 @@ err: bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) { + openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest update failed")); return true; } else { return false; @@ -653,9 +658,10 @@ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) * Returns: true on success * false on failure */ -bool crypto_digest_finalize (DIGEST *digest, uint8_t *dest, uint32_t *length) +bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) { if (!EVP_DigestFinal(&digest->ctx, dest, (unsigned int *)length)) { + openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest finalize failed")); return false; } else { return true; @@ -665,10 +671,10 @@ bool crypto_digest_finalize (DIGEST *digest, uint8_t *dest, uint32_t *length) /* * Free memory associated with a digest object. */ -void crypto_digest_free (DIGEST *digest) +void crypto_digest_free(DIGEST *digest) { EVP_MD_CTX_cleanup(&digest->ctx); - free (digest); + free(digest); } /* @@ -676,16 +682,17 @@ void crypto_digest_free (DIGEST *digest) * Returns: A pointer to a SIGNATURE object on success. * NULL on failure. */ -SIGNATURE *crypto_sign_new (void) +SIGNATURE *crypto_sign_new(JCR *jcr) { SIGNATURE *sig; - sig = (SIGNATURE *) malloc(sizeof(SIGNATURE)); + sig = (SIGNATURE *)malloc(sizeof(SIGNATURE)); if (!sig) { return NULL; } sig->sigData = SignatureData_new(); + sig->jcr = jcr; if (!sig->sigData) { /* Allocation failed in OpenSSL */ @@ -719,17 +726,17 @@ crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIG /* Get the digest algorithm and allocate a digest context */ switch (OBJ_obj2nid(si->digestAlgorithm)) { case NID_md5: - *digest = crypto_digest_new(CRYPTO_DIGEST_MD5); + *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_MD5); break; case NID_sha1: - *digest = crypto_digest_new(CRYPTO_DIGEST_SHA1); + *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA1); break; #ifdef HAVE_SHA2 case NID_sha256: - *digest = crypto_digest_new(CRYPTO_DIGEST_SHA256); + *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA256); break; case NID_sha512: - *digest = crypto_digest_new(CRYPTO_DIGEST_SHA512); + *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA512); break; #endif default: @@ -739,11 +746,15 @@ crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIG /* Shouldn't happen */ if (*digest == NULL) { + openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest_new failed")); return CRYPTO_ERROR_INVALID_DIGEST; } else { return CRYPTO_ERROR_NONE; } + } else { + openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL sign get digest failed")); } + } return CRYPTO_ERROR_NOSIGNER; @@ -780,15 +791,16 @@ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST if (ok >= 1) { return CRYPTO_ERROR_NONE; } else if (ok == 0) { + openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest Verify final failed")); return CRYPTO_ERROR_BAD_SIGNATURE; } else if (ok < 0) { /* Shouldn't happen */ - openssl_post_errors(M_ERROR, _("OpenSSL error occurred")); + openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest Verify final failed")); return CRYPTO_ERROR_INTERNAL; } } } - + Jmsg(sig->jcr, M_ERROR, 0, _("No signers found for crypto verify.\n")); /* Signer wasn't found. */ return CRYPTO_ERROR_NOSIGNER; } @@ -1247,7 +1259,7 @@ void crypto_session_free (CRYPTO_SESSION *cs) * Returns: A pointer to a CIPHER_CONTEXT object on success. The cipher block size is returned in blocksize. * NULL on failure. */ -CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) +CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { CIPHER_CONTEXT *cipher_ctx; const EVP_CIPHER *ec; @@ -1446,12 +1458,13 @@ struct Digest { struct Signature { }; -DIGEST *crypto_digest_new (crypto_digest_t type) +DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; + digest->jcr = jcr; switch (type) { case CRYPTO_DIGEST_MD5: @@ -1461,7 +1474,7 @@ DIGEST *crypto_digest_new (crypto_digest_t type) SHA1Init(&digest->sha1); break; default: - Emsg0(M_ERROR, 0, _("Unsupported digest type specified\n")); + Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type=%d specified\n"), type); free(digest); return NULL; } @@ -1521,14 +1534,14 @@ bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) void crypto_digest_free(DIGEST *digest) { - free (digest); + free(digest); } /* Dummy routines */ int init_crypto (void) { return 0; } int cleanup_crypto (void) { return 0; } -SIGNATURE *crypto_sign_new (void) { return NULL; } +SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; } crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; } crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; } @@ -1540,7 +1553,7 @@ SIGNATURE *crypto_sign_decode (const uint8_t *sigData, uint32_t length) { return void crypto_sign_free (SIGNATURE *sig) { } -X509_KEYPAIR *crypto_keypair_new (void) { return NULL; } +X509_KEYPAIR *crypto_keypair_new(void) { return NULL; } X509_KEYPAIR *crypto_keypair_dup (X509_KEYPAIR *keypair) { return NULL; } int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file) { return false; } bool crypto_keypair_has_key (const char *file) { return false; } diff --git a/bacula/src/lib/crypto.h b/bacula/src/lib/crypto.h index 975d980837..2b8831c1ed 100644 --- a/bacula/src/lib/crypto.h +++ b/bacula/src/lib/crypto.h @@ -1,25 +1,7 @@ -/* - * crypto.h Encryption support functions - * - * Author: Landon Fuller - * - * Version $Id$ - * - * This file was contributed to the Bacula project by Landon Fuller. - * - * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, - * no-charge, royalty-free, irrevocable copyright * license to reproduce, - * prepare derivative works of, publicly display, publicly perform, - * sublicense, and distribute the original work contributed by Landon Fuller - * to the Bacula project in source or object form. - * - * If you wish to license these contributions under an alternate open source - * license please contact Landon Fuller . - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2006 Free Software Foundation Europe e.V. + Copyright (C) 2005-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -43,6 +25,24 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * crypto.h Encryption support functions + * + * Author: Landon Fuller + * + * Version $Id$ + * + * This file was contributed to the Bacula project by Landon Fuller. + * + * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, + * no-charge, royalty-free, irrevocable copyright * license to reproduce, + * prepare derivative works of, publicly display, publicly perform, + * sublicense, and distribute the original work contributed by Landon Fuller + * to the Bacula project in source or object form. + * + * If you wish to license these contributions under an alternate open source + * license please contact Landon Fuller . + */ #ifndef __CRYPTO_H_ #define __CRYPTO_H_ diff --git a/bacula/src/lib/openssl.c b/bacula/src/lib/openssl.c index 2aa83c4e35..8650ca8956 100644 --- a/bacula/src/lib/openssl.c +++ b/bacula/src/lib/openssl.c @@ -1,25 +1,7 @@ -/* - * openssl.c OpenSSL support functions - * - * Author: Landon Fuller - * - * Version $Id$ - * - * This file was contributed to the Bacula project by Landon Fuller. - * - * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, - * no-charge, royalty-free, irrevocable copyright license to reproduce, - * prepare derivative works of, publicly display, publicly perform, - * sublicense, and distribute the original work contributed by Landon Fuller - * to the Bacula project in source or object form. - * - * If you wish to license these contributions under an alternate open source - * license please contact Landon Fuller . - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2006 Free Software Foundation Europe e.V. + Copyright (C) 2005-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -43,6 +25,24 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * openssl.c OpenSSL support functions + * + * Author: Landon Fuller + * + * Version $Id$ + * + * This file was contributed to the Bacula project by Landon Fuller. + * + * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, + * no-charge, royalty-free, irrevocable copyright license to reproduce, + * prepare derivative works of, publicly display, publicly perform, + * sublicense, and distribute the original work contributed by Landon Fuller + * to the Bacula project in source or object form. + * + * If you wish to license these contributions under an alternate open source + * license please contact Landon Fuller . + */ #include "bacula.h" @@ -58,11 +58,16 @@ struct CRYPTO_dynlock_value { pthread_mutex_t mutex; }; +void openssl_post_errors(int code, const char *errstring) +{ + openssl_post_errors(NULL, code, errstring); +} + /* * Post all per-thread openssl errors */ -void openssl_post_errors(int code, const char *errstring) +void openssl_post_errors(JCR *jcr, int code, const char *errstring) { char buf[512]; unsigned long sslerr; @@ -71,7 +76,7 @@ void openssl_post_errors(int code, const char *errstring) while((sslerr = ERR_get_error()) != 0) { /* Acquire the human readable string */ ERR_error_string_n(sslerr, (char *) &buf, sizeof(buf)); - Emsg2(M_ERROR, 0, "%s: ERR=%s\n", errstring, buf); + Jmsg2(jcr, M_ERROR, 0, "%s: ERR=%s\n", errstring, buf); } } diff --git a/bacula/src/lib/openssl.h b/bacula/src/lib/openssl.h index b55e3afb79..f007d10317 100644 --- a/bacula/src/lib/openssl.h +++ b/bacula/src/lib/openssl.h @@ -1,25 +1,7 @@ -/* - * openssl.h OpenSSL support functions - * - * Author: Landon Fuller - * - * Version $Id$ - * - * This file was contributed to the Bacula project by Landon Fuller. - * - * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, - * no-charge, royalty-free, irrevocable copyright * license to reproduce, - * prepare derivative works of, publicly display, publicly perform, - * sublicense, and distribute the original work contributed by Landon Fuller - * to the Bacula project in source or object form. - * - * If you wish to license these contributions under an alternate open source - * license please contact Landon Fuller . - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2006 Free Software Foundation Europe e.V. + Copyright (C) 2005-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -43,12 +25,31 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * openssl.h OpenSSL support functions + * + * Author: Landon Fuller + * + * Version $Id$ + * + * This file was contributed to the Bacula project by Landon Fuller. + * + * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, + * no-charge, royalty-free, irrevocable copyright * license to reproduce, + * prepare derivative works of, publicly display, publicly perform, + * sublicense, and distribute the original work contributed by Landon Fuller + * to the Bacula project in source or object form. + * + * If you wish to license these contributions under an alternate open source + * license please contact Landon Fuller . + */ #ifndef __OPENSSL_H_ #define __OPENSSL_H_ #ifdef HAVE_OPENSSL void openssl_post_errors (int code, const char *errstring); +void openssl_post_errors (JCR *jcr, int code, const char *errstring); int openssl_init_threads (void); void openssl_cleanup_threads (void); int openssl_seed_prng (void); diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 5862349bdc..14d202f225 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -134,11 +134,11 @@ uint32_t bcrc32(uint8_t *buf, int len); /* crypto.c */ int init_crypto (void); int cleanup_crypto (void); -DIGEST * crypto_digest_new (crypto_digest_t type); +DIGEST * crypto_digest_new (JCR *jcr, crypto_digest_t type); bool crypto_digest_update (DIGEST *digest, const uint8_t *data, uint32_t length); bool crypto_digest_finalize (DIGEST *digest, uint8_t *dest, uint32_t *length); void crypto_digest_free (DIGEST *digest); -SIGNATURE * crypto_sign_new (void); +SIGNATURE * crypto_sign_new (JCR *jcr); crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest); crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest); int crypto_sign_add_signer (SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair); diff --git a/bacula/src/version.h b/bacula/src/version.h index 1d84bea14e..3a891316bf 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.1.8" -#define BDATE "02 May 2007" -#define LSMDATE "02May07" +#define BDATE "03 May 2007" +#define LSMDATE "03May07" #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n" #define BYEAR "2007" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index dff98e35f8..696d548a04 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,16 @@ Technical notes on version 2.1 General: +03May07 +kes First cut strip path. The data should be passed to the FD, + but nothing is done with it yet. +kes Enhance the digest and signature routines in the crypto + library to accept a JCR and to use it to print error messages + so that they will go in the Job report rather than the daemon's + messages. +kes Simplify some of the verify signature code. +kes Simplify a few of the alternative returns in the signature + code. 02May07 ebl Use only POSIX regex instead of GNU regex in breg.c for File relocation. It fix broken freebsd compilation. -- 2.39.5