Index: head/sbin/hastctl/Makefile =================================================================== --- head/sbin/hastctl/Makefile (revision 313191) +++ head/sbin/hastctl/Makefile (revision 313192) @@ -1,46 +1,42 @@ # $FreeBSD$ .include PACKAGE=hast .PATH: ${.CURDIR}/../hastd PROG= hastctl SRCS= activemap.c SRCS+= crc32.c SRCS+= ebuf.c SRCS+= hast_checksum.c hast_compression.c hast_proto.c hastctl.c SRCS+= lzf.c SRCS+= metadata.c SRCS+= nv.c SRCS+= parse.y pjdlog.c SRCS+= proto.c proto_common.c proto_uds.c SRCS+= token.l SRCS+= subr.c SRCS+= y.tab.h MAN= hastctl.8 NO_WFORMAT= NO_WCAST_ALIGN= NO_WMISSING_VARIABLE_DECLARATIONS= CFLAGS+=-I${.CURDIR}/../hastd CFLAGS+=-DHAVE_CAPSICUM CFLAGS+=-DINET .if ${MK_INET6_SUPPORT} != "no" CFLAGS+=-DINET6 .endif # This is needed to have WARNS > 1. CFLAGS+=-DYY_NO_UNPUT CFLAGS+=-DYY_NO_INPUT -LIBADD= util -.if ${MK_OPENSSL} != "no" -LIBADD+= crypto -CFLAGS+=-DHAVE_CRYPTO -.endif +LIBADD= md util YFLAGS+=-v CLEANFILES=y.tab.c y.tab.h y.output .include Index: head/sbin/hastd/Makefile =================================================================== --- head/sbin/hastd/Makefile (revision 313191) +++ head/sbin/hastd/Makefile (revision 313192) @@ -1,44 +1,40 @@ # $FreeBSD$ .include PACKAGE=hast PROG= hastd SRCS= activemap.c SRCS+= control.c crc32.c SRCS+= ebuf.c event.c SRCS+= hast_checksum.c hast_compression.c hast_proto.c hastd.c hooks.c SRCS+= lzf.c SRCS+= metadata.c SRCS+= nv.c SRCS+= secondary.c SRCS+= parse.y pjdlog.c primary.c SRCS+= proto.c proto_common.c proto_socketpair.c proto_tcp.c proto_uds.c SRCS+= rangelock.c SRCS+= subr.c SRCS+= token.l SRCS+= y.tab.h MAN= hastd.8 hast.conf.5 NO_WFORMAT= NO_WCAST_ALIGN= NO_WMISSING_VARIABLE_DECLARATIONS= CFLAGS+=-I${.CURDIR} CFLAGS+=-DHAVE_CAPSICUM CFLAGS+=-DPROTO_TCP_DEFAULT_PORT=8457 CFLAGS+=-DINET .if ${MK_INET6_SUPPORT} != "no" CFLAGS+=-DINET6 .endif -LIBADD= geom pthread util -.if ${MK_OPENSSL} != "no" -LIBADD+= crypto -CFLAGS+=-DHAVE_CRYPTO -.endif +LIBADD= geom md pthread util YFLAGS+=-v CLEANFILES=y.tab.c y.tab.h y.output .include Index: head/sbin/hastd/hast_checksum.c =================================================================== --- head/sbin/hastd/hast_checksum.c (revision 313191) +++ head/sbin/hastd/hast_checksum.c (revision 313192) @@ -1,160 +1,147 @@ /*- * Copyright (c) 2011 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include -#ifdef HAVE_CRYPTO -#include -#endif - #include #include #include +#include #include #include "hast_checksum.h" -#ifdef HAVE_CRYPTO #define MAX_HASH_SIZE SHA256_DIGEST_LENGTH -#else -#define MAX_HASH_SIZE 4 -#endif static void hast_crc32_checksum(const unsigned char *data, size_t size, unsigned char *hash, size_t *hsizep) { uint32_t crc; crc = crc32(data, size); /* XXXPJD: Do we have to use htole32() on crc first? */ bcopy(&crc, hash, sizeof(crc)); *hsizep = sizeof(crc); } -#ifdef HAVE_CRYPTO static void hast_sha256_checksum(const unsigned char *data, size_t size, unsigned char *hash, size_t *hsizep) { SHA256_CTX ctx; SHA256_Init(&ctx); SHA256_Update(&ctx, data, size); SHA256_Final(hash, &ctx); *hsizep = SHA256_DIGEST_LENGTH; } -#endif /* HAVE_CRYPTO */ const char * checksum_name(int num) { switch (num) { case HAST_CHECKSUM_NONE: return ("none"); case HAST_CHECKSUM_CRC32: return ("crc32"); case HAST_CHECKSUM_SHA256: return ("sha256"); } return ("unknown"); } int checksum_send(const struct hast_resource *res, struct nv *nv, void **datap, size_t *sizep, bool *freedatap __unused) { unsigned char hash[MAX_HASH_SIZE]; size_t hsize; switch (res->hr_checksum) { case HAST_CHECKSUM_NONE: return (0); case HAST_CHECKSUM_CRC32: hast_crc32_checksum(*datap, *sizep, hash, &hsize); break; -#ifdef HAVE_CRYPTO case HAST_CHECKSUM_SHA256: hast_sha256_checksum(*datap, *sizep, hash, &hsize); break; -#endif default: PJDLOG_ABORT("Invalid checksum: %d.", res->hr_checksum); } nv_add_string(nv, checksum_name(res->hr_checksum), "checksum"); nv_add_uint8_array(nv, hash, hsize, "hash"); if (nv_error(nv) != 0) { errno = nv_error(nv); return (-1); } return (0); } int checksum_recv(const struct hast_resource *res __unused, struct nv *nv, void **datap, size_t *sizep, bool *freedatap __unused) { unsigned char chash[MAX_HASH_SIZE]; const unsigned char *rhash; size_t chsize, rhsize; const char *algo; algo = nv_get_string(nv, "checksum"); if (algo == NULL) return (0); /* No checksum. */ rhash = nv_get_uint8_array(nv, &rhsize, "hash"); if (rhash == NULL) { pjdlog_error("Hash is missing."); return (-1); /* Hash not found. */ } if (strcmp(algo, "crc32") == 0) hast_crc32_checksum(*datap, *sizep, chash, &chsize); -#ifdef HAVE_CRYPTO else if (strcmp(algo, "sha256") == 0) hast_sha256_checksum(*datap, *sizep, chash, &chsize); -#endif else { pjdlog_error("Unknown checksum algorithm '%s'.", algo); return (-1); /* Unknown checksum algorithm. */ } if (rhsize != chsize) { pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", rhsize, algo, chsize); return (-1); /* Different hash size. */ } if (bcmp(rhash, chash, chsize) != 0) { pjdlog_error("Hash mismatch."); return (-1); /* Hash mismatch. */ } return (0); } Index: head/sbin/hastd/hast_proto.c =================================================================== --- head/sbin/hastd/hast_proto.c (revision 313191) +++ head/sbin/hastd/hast_proto.c (revision 313192) @@ -1,222 +1,218 @@ /*- * Copyright (c) 2009-2010 The FreeBSD Foundation * Copyright (c) 2011 Pawel Jakub Dawidek * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from * the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include -#ifdef HAVE_CRYPTO #include "hast_checksum.h" -#endif #include "hast_compression.h" #include "hast_proto.h" struct hast_main_header { /* Protocol version. */ uint8_t version; /* Size of nv headers. */ uint32_t size; } __packed; typedef int hps_send_t(const struct hast_resource *, struct nv *nv, void **, size_t *, bool *); typedef int hps_recv_t(const struct hast_resource *, struct nv *nv, void **, size_t *, bool *); struct hast_pipe_stage { const char *hps_name; hps_send_t *hps_send; hps_recv_t *hps_recv; }; static struct hast_pipe_stage pipeline[] = { { "compression", compression_send, compression_recv }, -#ifdef HAVE_CRYPTO { "checksum", checksum_send, checksum_recv } -#endif }; /* * Send the given nv structure via conn. * We keep headers in nv structure and pass data in separate argument. * There can be no data at all (data is NULL then). */ int hast_proto_send(const struct hast_resource *res, struct proto_conn *conn, struct nv *nv, const void *data, size_t size) { struct hast_main_header hdr; struct ebuf *eb; bool freedata; void *dptr, *hptr; size_t hsize; int ret; dptr = (void *)(uintptr_t)data; freedata = false; ret = -1; if (data != NULL) { unsigned int ii; for (ii = 0; ii < sizeof(pipeline) / sizeof(pipeline[0]); ii++) { (void)pipeline[ii].hps_send(res, nv, &dptr, &size, &freedata); } nv_add_uint32(nv, size, "size"); if (nv_error(nv) != 0) { errno = nv_error(nv); goto end; } } eb = nv_hton(nv); if (eb == NULL) goto end; hdr.version = res != NULL ? res->hr_version : HAST_PROTO_VERSION; hdr.size = htole32((uint32_t)ebuf_size(eb)); if (ebuf_add_head(eb, &hdr, sizeof(hdr)) == -1) goto end; hptr = ebuf_data(eb, &hsize); if (proto_send(conn, hptr, hsize) == -1) goto end; if (data != NULL && proto_send(conn, dptr, size) == -1) goto end; ret = 0; end: if (freedata) free(dptr); return (ret); } int hast_proto_recv_hdr(const struct proto_conn *conn, struct nv **nvp) { struct hast_main_header hdr; struct nv *nv; struct ebuf *eb; void *hptr; eb = NULL; nv = NULL; if (proto_recv(conn, &hdr, sizeof(hdr)) == -1) goto fail; if (hdr.version > HAST_PROTO_VERSION) { errno = ERPCMISMATCH; goto fail; } hdr.size = le32toh(hdr.size); eb = ebuf_alloc(hdr.size); if (eb == NULL) goto fail; if (ebuf_add_tail(eb, NULL, hdr.size) == -1) goto fail; hptr = ebuf_data(eb, NULL); PJDLOG_ASSERT(hptr != NULL); if (proto_recv(conn, hptr, hdr.size) == -1) goto fail; nv = nv_ntoh(eb); if (nv == NULL) goto fail; *nvp = nv; return (0); fail: if (eb != NULL) ebuf_free(eb); return (-1); } int hast_proto_recv_data(const struct hast_resource *res, struct proto_conn *conn, struct nv *nv, void *data, size_t size) { unsigned int ii; bool freedata; size_t dsize; void *dptr; int ret; PJDLOG_ASSERT(data != NULL); PJDLOG_ASSERT(size > 0); ret = -1; freedata = false; dptr = data; dsize = nv_get_uint32(nv, "size"); if (dsize > size) { errno = EINVAL; goto end; } else if (dsize == 0) { (void)nv_set_error(nv, 0); } else { if (proto_recv(conn, data, dsize) == -1) goto end; for (ii = sizeof(pipeline) / sizeof(pipeline[0]); ii > 0; ii--) { ret = pipeline[ii - 1].hps_recv(res, nv, &dptr, &dsize, &freedata); if (ret == -1) goto end; } ret = -1; if (dsize > size) { errno = EINVAL; goto end; } if (dptr != data) bcopy(dptr, data, dsize); } ret = 0; end: if (freedata) free(dptr); return (ret); }