} else if (crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
Dmsg2(400, "stream=Digest inx=%d Digest=%s\n", file_index, Opts_Digest);
/*
- * When ever we get a digest is MUST have been
+ * When ever we get a digest it MUST have been
* preceded by an attributes record, which sets attr_file_index
*/
if (jcr->FileIndex != (uint32_t)file_index) {
/* Allocate buffer */
jcr->pki_session_encoded = (uint8_t *)malloc(size);
- if (!jcr->pki_session_encoded) {
- return 0;
- }
/* Encode session data */
if (crypto_session_encode(jcr->pki_session, jcr->pki_session_encoded, &size) == false) {
stop_heartbeat_monitor(jcr);
- bnet_sig(sd, BNET_EOD); /* end of sending data */
+ sd->signal(BNET_EOD); /* end of sending data */
if (jcr->big_buf) {
free(jcr->big_buf);
}
if (jcr->pki_session_encoded) {
free(jcr->pki_session_encoded);
+ jcr->pki_session_encoded = NULL;
}
Dmsg1(100, "end blast_data ok=%d\n", ok);
DIGEST *signing_digest = NULL;
int digest_stream = STREAM_NONE;
SIGNATURE *sig = NULL;
- uint8_t *buf = NULL;
bool has_file_data = false;
// TODO landonf: Allow the user to specify the digest algorithm
#ifdef HAVE_SHA2
if (has_file_data) {
/*
* Setup for digest handling. If this fails, the digest will be set to NULL
- * and not used.
+ * and not used. Note, the digest (file hash) can be any one of the four
+ * algorithms below.
+ *
+ * The signing digest is a single algorithm depending on
+ * whether or not we have SHA2.
+ * ****FIXME**** the signing algoritm should really be
+ * determined a different way!!!!!! What happens if
+ * sha2 was available during backup but not restore?
*/
if (ff_pkt->flags & FO_MD5) {
digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
if (has_file_data && jcr->pki_encrypt) {
/* Send our header */
Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
- bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
+ sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
/* Grow the bsock buffer to fit our message if necessary */
if (sizeof_pool_memory(sd->msg) < jcr->pki_session_encoded_size) {
jcr->JobBytes += sd->msglen;
Dmsg1(100, "Send data len=%d\n", sd->msglen);
- bnet_send(sd);
- bnet_sig(sd, BNET_EOD);
+ sd->send();
+ sd->signal(BNET_EOD);
}
/*
}
Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
- bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
+ sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
sd->msglen = 32;
if (signing_digest) {
crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
}
- bnet_send(sd);
- bnet_sig(sd, BNET_EOD);
+ sd->send();
+ sd->signal(BNET_EOD);
}
#endif
goto bail_out;
}
- if (crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair) == false) {
+ if (!crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair)) {
Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
goto bail_out;
}
/* Get signature size */
- if (crypto_sign_encode(sig, NULL, &size) == false) {
+ if (!crypto_sign_encode(sig, NULL, &size)) {
Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
goto bail_out;
}
- /* Allocate signature data buffer */
- buf = (uint8_t *)malloc(size);
- if (!buf) {
- goto bail_out;
- }
-
- /* Encode signature data */
- if (crypto_sign_encode(sig, buf, &size) == false) {
- Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
- goto bail_out;
+ /* Grow the bsock buffer to fit our message if necessary */
+ if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
+ sd->msg = realloc_pool_memory(sd->msg, size);
}
/* Send our header */
- bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
+ sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
- /* Grow the bsock buffer to fit our message if necessary */
- if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
- sd->msg = realloc_pool_memory(sd->msg, size);
+ /* Encode signature data */
+ if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
+ Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
+ goto bail_out;
}
- /* Copy our message over and send it */
- memcpy(sd->msg, buf, size);
sd->msglen = size;
- bnet_send(sd);
- bnet_sig(sd, BNET_EOD); /* end of checksum */
+ sd->send();
+ sd->signal(BNET_EOD); /* end of checksum */
}
/* Terminate any digest and send it to Storage daemon and the Director */
if (digest) {
- uint8_t md[CRYPTO_DIGEST_MAX_SIZE];
uint32_t size;
- size = sizeof(md);
+ sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
+ Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
+
+ size = sizeof(CRYPTO_DIGEST_MAX_SIZE);
+ /* Grow the bsock buffer to fit our message if necessary */
+ if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
+ sd->msg = realloc_pool_memory(sd->msg, size);
+ }
- if (crypto_digest_finalize(digest, md, &size)) {
- bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, digest_stream);
- Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
- memcpy(sd->msg, md, size);
- sd->msglen = size;
- bnet_send(sd);
- bnet_sig(sd, BNET_EOD); /* end of checksum */
+ if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
+ Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
+ goto bail_out;
}
+
+ sd->msglen = size;
+ sd->send();
+ sd->signal(BNET_EOD); /* end of checksum */
}
good_rtn:
if (sig) {
crypto_sign_free(sig);
}
- if (buf) {
- free(buf);
- }
return rtnstat;
}
* Send Data header to Storage daemon
* <file-index> <stream> <info>
*/
- if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
+ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
goto err;
}
Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
}
sd->msg = wbuf; /* set correct write buffer */
- if (!bnet_send(sd)) {
+ if (!sd->send()) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
goto err;
}
Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
if (encrypted_len > 0) {
sd->msglen = encrypted_len; /* set encrypted length */
sd->msg = jcr->crypto_buf; /* set correct write buffer */
- if (!bnet_send(sd)) {
+ if (!sd->send()) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
goto err;
}
Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
}
}
- if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */
+ if (!sd->signal(BNET_EOD)) { /* indicate end of file data */
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
goto err;
}
}
/* Send header */
- if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
+ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
return false;
}
msgsave = sd->msg;
sd->msg = jcr->acl_text;
sd->msglen = len + 1;
- if (!bnet_send(sd)) {
+ if (!sd->send()) {
sd->msg = msgsave;
sd->msglen = 0;
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
return false;
}
jcr->JobBytes += sd->msglen;
sd->msg = msgsave;
- if (!bnet_sig(sd, BNET_EOD)) {
+ if (!sd->signal(BNET_EOD)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
return false;
}
* Send Attributes header to Storage daemon
* <file-index> <stream> <info>
*/
- if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
+ if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
return false;
}
Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
strip_path(ff_pkt);
if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
- stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
+ stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
attribsEx, 0);
} else if (ff_pkt->type == FT_DIREND) {
/* Here link is the canonical filename (i.e. with trailing slash) */
- stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
+ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
} else {
- stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
+ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
}
unstrip_path(ff_pkt);
Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
if (!stat) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ sd->bstrerror());
return false;
}
- bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */
+ sd->signal(BNET_EOD); /* indicate end of attributes data */
return true;
}
const bool have_acl = false;
#endif
+#ifdef HAVE_SHA2
+ const bool have_sha2 = true;
+#else
+ const bool have_sha2 = false;
+#endif
+
+
/* Data received from Storage Daemon */
static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
SIGNATURE *sig; /* Cryptographic signature (if any) for file */
CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */
- RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
+ RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */
RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
};
ATTR *attr;
intmax_t rsrc_len = 0; /* Original length of resource fork */
r_ctx rctx;
-
+ /* ***FIXME*** make configurable */
+ crypto_digest_t signing_algorithm = have_sha2 ?
+ CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
memset(&rctx, 0, sizeof(rctx));
rctx.jcr = jcr;
}
jcr->buf_size = sd->msglen;
- /* St Bernard code goes here if implemented */
+ /* St Bernard code goes here if implemented -- see end of file */
if (have_libz) {
uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
* Get a record from the Storage daemon. We are guaranteed to
* receive records in the following order:
* 1. Stream record header
- * 2. Stream data
+ * 2. Stream data (one or more of the following in the order given)
* a. Attributes (Unix or Win32)
* b. Possibly stream encryption session data (e.g., symmetric session key)
- * or c. File data for the file
- * or d. Alternate data stream (e.g. Resource Fork)
- * or e. Finder info
- * or f. ACLs
- * or g. Possibly a cryptographic signature
- * or h. Possibly MD5 or SHA1 record
+ * c. File data for the file
+ * d. Alternate data stream (e.g. Resource Fork)
+ * e. Finder info
+ * f. ACLs
+ * g. Possibly a cryptographic signature
+ * h. Possibly MD5 or SHA1 record
* 3. Repeat step 1
*
* NOTE: We keep track of two bacula file descriptors:
* close it again.
* The expected size of the stream, fork_len, should be set when
* opening the fd.
+ * 3. Not all the stream data records are required -- e.g. if there
+ * is no fork, there is no alternate data stream, no ACL, ...
*/
binit(&rctx.bfd);
binit(&rctx.forkbfd);
attr = new_attr();
jcr->acl_text = get_pool_memory(PM_MESSAGE);
+
+
while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
/* Remember previous stream type */
rctx.prev_stream = rctx.stream;
/* * Now we expect the Stream Data */
if (bget_msg(sd) < 0) {
- Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
+ Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror());
goto bail_out;
}
if (rctx.size != (uint32_t)sd->msglen) {
break;
}
+ if (jcr->digest) {
+ crypto_digest_free(jcr->digest);
+ }
+ jcr->digest = crypto_digest_new(jcr, signing_algorithm);
+ if (!jcr->digest) {
+ Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n"));
+ extract = false;
+ bclose(&rctx.bfd);
+ break;
+ }
+
/* Decode and save session keys. */
cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen,
jcr->pki_recipients, &rctx.cs);
/* Free Signature & Crypto Data */
free_signature(rctx);
free_session(rctx);
+ if (jcr->digest) {
+ crypto_digest_free(jcr->digest);
+ jcr->digest = NULL;
+ }
/* Free file cipher restore context */
if (rctx.cipher_ctx.cipher) {
DIGEST *digest = NULL;
crypto_error_t err;
uint64_t saved_bytes;
+ crypto_digest_t signing_algorithm = have_sha2 ?
+ CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
+ crypto_digest_t algorithm;
+
if (!jcr->pki_sign) {
return true; /* no signature OK */
/* Iterate through the trusted signers */
foreach_alist(keypair, jcr->pki_signers) {
- err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
+ err = crypto_sign_get_digest(sig, jcr->pki_keypair, algorithm, &digest);
switch (err) {
case CRYPTO_ERROR_NONE:
Dmsg0(50, "== Got digest\n");
- /* Signature found, digest allocated */
- jcr->digest = digest;
-
- /* Checksum the entire file */
- /* 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, _("Digest one file failed for file: %s\n"),
- jcr->last_fname);
- jcr->JobBytes = saved_bytes;
- goto bail_out;
+ /*
+ * We computed jcr->digest using signing_algorithm while writing
+ * the file. If it is not the same as the algorithm used for
+ * this file, punt by releasing the computed algorithm and
+ * computing by re-reading the file.
+ */
+ if (algorithm != signing_algorithm) {
+ if (jcr->digest) {
+ crypto_digest_free(jcr->digest);
+ jcr->digest = NULL;
+ }
}
- jcr->JobBytes = saved_bytes;
+ if (jcr->digest) {
+ /* Use digest computed while writing the file to verify the signature */
+ if ((err = crypto_sign_verify(sig, keypair, jcr->digest)) != CRYPTO_ERROR_NONE) {
+ Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
+ Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
+ jcr->last_fname, crypto_strerror(err));
+ goto bail_out;
+ }
+ } else {
+ /* Signature found, digest allocated. Old method,
+ * re-read the file and compute the digest
+ */
+ jcr->digest = digest;
+
+ /* Checksum the entire file */
+ /* 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, _("Digest one file failed for file: %s\n"),
+ jcr->last_fname);
+ jcr->JobBytes = saved_bytes;
+ goto bail_out;
+ }
+ jcr->JobBytes = saved_bytes;
- /* Verify the signature */
- if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
- Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
- Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
- jcr->last_fname, crypto_strerror(err));
- goto bail_out;
+ /* Verify the signature */
+ if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
+ Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
+ Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
+ jcr->last_fname, crypto_strerror(err));
+ goto bail_out;
+ }
+ jcr->digest = NULL;
}
/* Valid signature */
Dmsg1(50, "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;
+ digest = NULL;
}
continue;
default:
bail_out:
if (digest) {
crypto_digest_free(digest);
- jcr->digest = NULL;
}
return false;
}
bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
{
+ if (jcr->digest) {
+ crypto_digest_update(jcr->digest, (uint8_t *)data, length);
+ }
if (win32_decomp) {
if (!processWin32BackupAPIBlock(bfd, data, length)) {
berrno be;
static char buf[20];
switch (stream) {
- case STREAM_GZIP_DATA:
- return _("GZIP data");
- case STREAM_SPARSE_GZIP_DATA:
- return _("GZIP sparse data");
- case STREAM_WIN32_DATA:
- return _("Win32 data");
- case STREAM_WIN32_GZIP_DATA:
- return _("Win32 GZIP data");
case STREAM_UNIX_ATTRIBUTES:
- return _("File attributes");
+ return _("Unix attributes");
case STREAM_FILE_DATA:
return _("File data");
case STREAM_MD5_DIGEST:
return _("MD5 digest");
+ case STREAM_GZIP_DATA:
+ return _("GZIP data");
case STREAM_UNIX_ATTRIBUTES_EX:
return _("Extended attributes");
case STREAM_SPARSE_DATA:
return _("Sparse data");
+ case STREAM_SPARSE_GZIP_DATA:
+ return _("GZIP sparse data");
case STREAM_PROGRAM_NAMES:
return _("Program names");
case STREAM_PROGRAM_DATA:
return _("Program data");
case STREAM_SHA1_DIGEST:
return _("SHA1 digest");
+ case STREAM_WIN32_DATA:
+ return _("Win32 data");
+ case STREAM_WIN32_GZIP_DATA:
+ return _("Win32 GZIP data");
case STREAM_MACOS_FORK_DATA:
- return _("HFS+ resource fork");
+ return _("MacOS Fork data");
case STREAM_HFSPLUS_ATTRIBUTES:
- return _("HFS+ Finder Info");
+ return _("HFS+ attribs");
+ case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
+ return _("Standard Unix ACL attribs");
+ case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
+ return _("Default Unix ACL attribs");
case STREAM_SHA256_DIGEST:
return _("SHA256 digest");
case STREAM_SHA512_DIGEST:
return _("Signed digest");
case STREAM_ENCRYPTED_FILE_DATA:
return _("Encrypted File data");
- case STREAM_ENCRYPTED_FILE_GZIP_DATA:
- return _("Encrypted GZIP data");
case STREAM_ENCRYPTED_WIN32_DATA:
return _("Encrypted Win32 data");
+ case STREAM_ENCRYPTED_SESSION_DATA:
+ return _("Encrypted session data");
+ case STREAM_ENCRYPTED_FILE_GZIP_DATA:
+ return _("Encrypted GZIP data");
case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
return _("Encrypted Win32 GZIP data");
case STREAM_ENCRYPTED_MACOS_FORK_DATA:
- return _("Encrypted HFS+ resource fork");
+ return _("Encrypted MacOS fork data");
default:
sprintf(buf, "%d", stream);
return (const char *)buf;
-/*
- * attr.h Definition of attributes packet for unpacking from tape
- *
- * Kern Sibbald, June MMIII
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2003-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2003-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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * attr.h Definition of attributes packet for unpacking from tape
+ *
+ * Kern Sibbald, June MMIII
+ *
+ * Version $Id$
+ */
struct ATTR {
/*
* For a given public key, find the associated SignatureInfo record
- * and create a digest context for signature validation
+ * and create a digest context for signature validation
+ *
* Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest.
* A crypto_error_t value on failure.
*/
-crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest)
+crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair,
+ crypto_digest_t &type, DIGEST **digest)
{
STACK_OF(SignerInfo) *signers;
SignerInfo *si;
Dmsg1(50, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
switch (OBJ_obj2nid(si->digestAlgorithm)) {
case NID_md5:
+ Dmsg0(100, "sign digest algorithm is MD5\n");
+ type = CRYPTO_DIGEST_MD5;
*digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_MD5);
break;
case NID_sha1:
+ Dmsg0(100, "sign digest algorithm is SHA1\n");
+ type = CRYPTO_DIGEST_SHA1;
*digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA1);
break;
#ifdef HAVE_SHA2
case NID_sha256:
+ Dmsg0(100, "sign digest algorithm is SHA256\n");
+ type = CRYPTO_DIGEST_SHA256;
*digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA256);
break;
case NID_sha512:
+ Dmsg0(100, "sign digest algorithm is SHA512\n");
+ type = CRYPTO_DIGEST_SHA512;
*digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA512);
break;
#endif
default:
+ type = CRYPTO_DIGEST_NONE;
*digest = NULL;
return CRYPTO_ERROR_INVALID_DIGEST;
}
memset(lf, 0, sizeof(LEX));
lf->next = nf; /* if have lf, push it behind new one */
lf->options = nf->options; /* preserve user options */
+ /*
+ * preserve err_type to prevent bacula exiting on 'reload'
+ * if config is invalid. Fixes bug #877
+ */
+ lf->err_type = nf->err_type;
} else {
lf = nf; /* start new packet */
memset(lf, 0, sizeof(LEX));
lf->state = lex_none;
} else {
token = T_ERROR;
- }
+ }
break;
case lex_utf16_le_bom:
/* we only end up in this state if we have read an 0xFF
as the first byte of the file -- indicating that we are
probably dealing with an Intel based (little endian) UTF-16 file*/
- if (ch == 0xFE) {
- token = T_UTF16_BOM;
- lf->state = lex_none;
- } else {
- token = T_ERROR;
- }
+ if (ch == 0xFE) {
+ token = T_UTF16_BOM;
+ lf->state = lex_none;
+ } else {
+ token = T_ERROR;
+ }
break;
}
Dmsg4(dbglvl, "ch=%d state=%s token=%s %c\n", ch, lex_state_to_str(lf->state),
bool crypto_digest_finalize (DIGEST *digest, uint8_t *dest, uint32_t *length);
void crypto_digest_free (DIGEST *digest);
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_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair,
+ crypto_digest_t &algorithm, 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);
int crypto_sign_encode (SIGNATURE *sig, uint8_t *dest, uint32_t *length);
*/
#undef VERSION
-#define VERSION "2.1.14"
-#define BDATE "14 June 2007"
-#define LSMDATE "14Jun07"
+#define VERSION "2.1.16"
+#define BDATE "16 June 2007"
+#define LSMDATE "16Jun07"
#define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
#define BYEAR "2007" /* year for copyright messages in progs */
Technical notes on version 2.1
General:
+16Jun07
+kes Remove a few malloc()s from the encryption code.
+kes Use the class calls to bsock in filed/backup.c and restore.c in
+ place of the old bnet_xxx code.
+kes Implement code that does an on the fly calculation of the
+ signing digest during restore of encrypted files. It makes
+ a best guess at the algorithm, and if it is not correct, will
+ then revert to the old code which reads the file after it is
+ restored.
+kes Implement at least one missing crypto stream in stream_to_ascii()
+kes Apply patch from William <chowmeined@gmail.com> that fixes bug
+ #877 where a reload with bad syntax causes Dir to exit.
14Jun07
kes Do not free a volume on a tape drive until another volume is
mounted and read, or the autochanger unloads the volume.