Hello community, here is the log from the commit of package open-isns for openSUSE:Factory checked in at 2016-11-05 21:24:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/open-isns (Old) and /work/SRC/openSUSE:Factory/.open-isns.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "open-isns" Changes: -------- --- /work/SRC/openSUSE:Factory/open-isns/open-isns.changes 2016-07-12 23:48:36.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.open-isns.new/open-isns.changes 2016-11-05 21:24:01.000000000 +0100 @@ -1,0 +2,5 @@ +Wed Nov 2 23:53:06 UTC 2016 - [email protected] + +- Updated to version 0.97, replacing main tarball + +------------------------------------------------------------------- Old: ---- open-isns-0.96.tar.gz New: ---- open-isns-0.97.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ open-isns.spec ++++++ --- /var/tmp/diff_new_pack.brjQ36/_old 2016-11-05 21:24:02.000000000 +0100 +++ /var/tmp/diff_new_pack.brjQ36/_new 2016-11-05 21:24:02.000000000 +0100 @@ -20,7 +20,7 @@ Summary: Partial Implementation of iSNS iSCSI registration License: LGPL-2.1+ Group: System Environment/Kernel -Version: 0.96 +Version: 0.97 Release: 0 Source: %{name}-%{version}.tar.gz Url: https://github.com/open-iscsi/%{name} ++++++ open-isns-0.96.tar.gz -> open-isns-0.97.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/.gitignore new/open-isns-0.97/.gitignore --- old/open-isns-0.96/.gitignore 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/.gitignore 2016-10-29 03:28:30.000000000 +0200 @@ -1 +1,7 @@ *.o +TAGS +cscope.files +isnsadm +isnsd +isnsdd +libisns.a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/README new/open-isns-0.97/README --- old/open-isns-0.96/README 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/README 2016-10-29 03:28:30.000000000 +0200 @@ -183,3 +183,13 @@ Current maintainer: Lee Duncan <[email protected]> 2015 + +------------------------------------------------------------------ + +Things to do: + +* fully implement/require device discovery sets +* implement ability to pass in flags to systemd service file for isnsd +* improve automated testing (using PyUnit?) +* ensure all tests pass (!!) +* document testing procedure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/buffer.c new/open-isns-0.97/buffer.c --- old/open-isns-0.96/buffer.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/buffer.c 2016-10-29 03:28:30.000000000 +0200 @@ -146,7 +146,7 @@ bp->head = bp->tail = 0; } -int +static int buf_fill(buf_t *bp) { int n; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/db-file.c new/open-isns-0.97/db-file.c --- old/open-isns-0.96/db-file.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/db-file.c 2016-10-29 03:28:30.000000000 +0200 @@ -50,23 +50,31 @@ /* * Helper functions */ -static const char * -__path_concat(const char *dirname, const char *basename) +static char * +__path_concat(const char *dirname, const char *prefix, const char *basename) { - static char pathname[PATH_MAX]; + size_t capacity = strlen(dirname) + strlen(prefix) + strlen(basename) + 2; + char *pathname; - snprintf(pathname, sizeof(pathname), "%s/%s", - dirname, basename); + pathname = isns_malloc(capacity); + if (!pathname) + isns_fatal("Out of memory."); + snprintf(pathname, capacity, "%s/%s%s", + dirname, prefix, basename); return pathname; } -static const char * +static char * __print_index(uint32_t index) { - static char namebuf[32]; + char namebuf[32]; + char *result; snprintf(namebuf, sizeof(namebuf), "%08x", index); - return namebuf; + result = isns_strdup(namebuf); + if (!result) + isns_fatal("Out of memory."); + return result; } static int @@ -83,25 +91,25 @@ /* * Build path names for an object */ -static const char * +static char * __dbe_file_object_path(const char *dirname, const isns_object_t *obj) { - return __path_concat(dirname, __print_index(obj->ie_index)); + char *index_str = __print_index(obj->ie_index); + char *result = __path_concat(dirname, "", index_str); + isns_free(index_str); + return result; } /* * Build a path name for a temporary file. - * Cannot use __path_concat, because we need both names - * when storing objects */ -static const char * +static char * __dbe_file_object_temp(const char *dirname, const isns_object_t *obj) { - static char pathname[PATH_MAX]; - - snprintf(pathname, sizeof(pathname), "%s/.%s", - dirname, __print_index(obj->ie_index)); - return pathname; + char *index_str = __print_index(obj->ie_index); + char *result = __path_concat(dirname, ".", index_str); + isns_free(index_str); + return result; } /* @@ -150,8 +158,8 @@ __dbe_file_store_object(const char *dirname, const isns_object_t *obj) { struct isns_db_object_info info; - const char *path = __dbe_file_object_path(dirname, obj); - const char *temp = __dbe_file_object_temp(dirname, obj); + char *path = __dbe_file_object_path(dirname, obj); + char *temp = __dbe_file_object_temp(dirname, obj); buf_t *bp = NULL; int status = ISNS_INTERNAL_ERROR; @@ -196,6 +204,8 @@ } out: + isns_free(path); + isns_free(temp); if (bp) buf_close(bp); return status; @@ -231,11 +241,12 @@ static int __dbe_file_remove_object(const char *dirname, const isns_object_t *obj) { - const char *path = __dbe_file_object_path(dirname, obj); + char *path = __dbe_file_object_path(dirname, obj); isns_debug_state("DB: Purging object %u (%s)\n", obj->ie_index, path); if (unlink(path) < 0) isns_error("DB: Cannot remove %s: %m\n", path); + isns_free(path); return ISNS_SUCCESS; } @@ -354,13 +365,13 @@ while ((dp = readdir(dir)) != NULL) { struct stat stb; - const char *path; + char *path; if (dp->d_name[0] == '.' || !strcmp(dp->d_name, "DB")) continue; - path = __path_concat(dirpath, dp->d_name); + path = __path_concat(dirpath, "", dp->d_name); if (lstat(path, &stb) < 0) { isns_error("DB: cannot stat %s: %m\n", path); status = ISNS_INTERNAL_ERROR; @@ -371,6 +382,7 @@ } else { isns_debug_state("DB: ignoring %s\n", path); } + isns_free(path); if (status != ISNS_SUCCESS) break; @@ -387,11 +399,11 @@ __dbe_file_write_info(isns_db_t *db) { isns_db_backend_t *back = db->id_backend; - const char *path; + char *path = NULL; buf_t *bp; int status = ISNS_INTERNAL_ERROR; - path = __path_concat(back->idb_name, "DB"); + path = __path_concat(back->idb_name, "", "DB"); if ((bp = buf_open(path, O_CREAT|O_TRUNC|O_WRONLY)) == NULL) { isns_error("Unable to write %s: %m\n", path); goto out; @@ -403,6 +415,7 @@ status = ISNS_SUCCESS; out: + isns_free(path); if (bp) buf_close(bp); return status; @@ -413,11 +426,11 @@ { isns_db_backend_t *back = db->id_backend; struct isns_db_file_info info; - const char *path; + char *path = NULL; buf_t *bp = NULL; int status = ISNS_NO_SUCH_ENTRY; - path = __path_concat(back->idb_name, "DB"); + path = __path_concat(back->idb_name, "", "DB"); if ((bp = buf_open(path, O_RDONLY)) == NULL) goto out; @@ -445,6 +458,7 @@ } out: + isns_free(path); if (bp) buf_close(bp); return status; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/dd.c new/open-isns-0.97/dd.c --- old/open-isns-0.96/dd.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/dd.c 2016-10-29 03:28:30.000000000 +0200 @@ -2,7 +2,7 @@ * Handle DD registration/deregistration * * Discovery domains are weird, even in the context of - * iSNS. For once thing, all other objects have unique + * iSNS. For one thing, all other objects have unique * attributes; DDs attributes can appear several times. * They should really have made each DD member an object * in its own right. @@ -381,7 +381,7 @@ if (status != ISNS_SUCCESS) goto out; - /* Send notifications. This must be done before after + /* Send notifications. This must be done before * updating the DD. */ isns_dd_notify(dd, dd->dd_members, temp_dd->dd_members, @@ -915,6 +915,9 @@ *tail = new; tail = &new->ddm_next; } + + /* mark this object as a member of this DD */ + isns_object_mark_membership(obj, dd->dd_id); } isns_object_release(obj); } @@ -1040,10 +1043,6 @@ isns_db_insert_limbo(db, obj); mp->ddm_index = obj->ie_index; - /* Record the fact that the object is a member of - * this DD */ - isns_object_mark_membership(obj, dd->dd_id); - switch (mp->ddm_type) { case ISNS_DD_MEMBER_ISCSI_NODE: if (isns_object_get_string(obj, ISNS_TAG_ISCSI_NAME, &node_name)) @@ -1203,6 +1202,10 @@ dd = isns_dd_clone(temp_dd); + /* + * XXX duplicate call? isns_object_get() is already called + * at the end of isns_dd_clone() + */ dd->dd_object = isns_object_get(obj); isns_dd_insert(dd); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/doc/isns_config.5 new/open-isns-0.97/doc/isns_config.5 --- old/open-isns-0.96/doc/isns_config.5 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/doc/isns_config.5 2016-10-29 03:28:30.000000000 +0200 @@ -343,7 +343,7 @@ Functions: This is a bitmap detailing which functions the client is permitted to invoke. The bit names correspond to the shorthand names used in -RFC 4711, such as +RFC 4171, such as .BR DevAttrReg , .BR DevAttrQry , etc. The default is to allow registration, query and deregistration, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/doc/isnsadm.8 new/open-isns-0.97/doc/isnsadm.8 --- old/open-isns-0.96/doc/isnsadm.8 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/doc/isnsadm.8 2016-10-29 03:28:30.000000000 +0200 @@ -136,7 +136,7 @@ .\"--------------------------- .SS Supported attributes Most command modes take a list of attributes as arguments on the -command line. The naming and syntax of these attributes as +command line. The naming and syntax of these attributes are the same for all commands modes, however certain modes support only a limited set of attributes. .PP @@ -332,7 +332,7 @@ This will register a portal group joining the preceding portal and node. Portal groups can be used to describe the preferred portals for a given node; please refer -to RFC 4711 for details. +to RFC 4171 for details. .IP This can be followed by any number of portal group attributes. The attribute list must specify a portal group tag (PGT) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/include/libisns/isns.h new/open-isns-0.97/include/libisns/isns.h --- old/open-isns-0.96/include/libisns/isns.h 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/include/libisns/isns.h 2016-10-29 03:28:30.000000000 +0200 @@ -11,6 +11,7 @@ #define ISNS_H #include <sys/socket.h> +#include <sys/time.h> #include <netinet/in.h> #include <stdio.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/include/libisns/message.h new/open-isns-0.97/include/libisns/message.h --- old/open-isns-0.96/include/libisns/message.h 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/include/libisns/message.h 2016-10-29 03:28:30.000000000 +0200 @@ -13,6 +13,22 @@ typedef struct isns_message_queue isns_message_queue_t; +#ifdef SCM_CREDENTIALS +/* Linux-style SCM_CREDENTIALS + struct ucred */ +typedef struct ucred struct_cmsgcred_t; +#define CMSGCRED_uid uid +#define SCM_CREDENTIALS_portable SCM_CREDENTIALS +#elif defined(SCM_CREDS) +/* FreeBSD-style SCM_CREDS + struct cmsgcred_t */ +typedef struct cmsgcred struct_cmsgcred_t; +#define CMSGCRED_uid cmcred_euid +#define SCM_CREDENTIALS_portable SCM_CREDS +#else +/* If a platform requires something else, this must be added + * here. */ +#error "Neither SCM_CREDENTIALS nor SCM_CREDS supported on your platform for credentials passing over AF_LOCAL sockets." +#endif + struct isns_simple { uint32_t is_function; isns_source_t * is_source; @@ -35,7 +51,7 @@ struct isns_buf * im_payload; isns_socket_t * im_socket; isns_principal_t * im_security; - struct ucred * im_creds; + struct_cmsgcred_t * im_creds; isns_message_queue_t * im_queue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/include/libisns/paths.h.in new/open-isns-0.97/include/libisns/paths.h.in --- old/open-isns-0.96/include/libisns/paths.h.in 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/include/libisns/paths.h.in 2016-10-29 03:28:30.000000000 +0200 @@ -9,8 +9,8 @@ #define ISNS_CONFIG_H #define __OPENISNS_MKVERSION(maj, min) (((maj) << 8) + (min)) -#define OPENISNS_VERSION __OPENISNS_MKVERSION(0, 96); -#define OPENISNS_VERSION_STRING "0.96" +#define OPENISNS_VERSION __OPENISNS_MKVERSION(0, 97); +#define OPENISNS_VERSION_STRING "0.97" #define ISNS_ETCDIR "/etc/isns" #define ISNS_RUNDIR "@RUNDIR@" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/include/libisns/util.h new/open-isns-0.97/include/libisns/util.h --- old/open-isns-0.96/include/libisns/util.h 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/include/libisns/util.h 2016-10-29 03:28:30.000000000 +0200 @@ -100,18 +100,31 @@ * There's no htonll yet */ #ifndef htonll -# include <endian.h> -# include <byteswap.h> -# if __BYTE_ORDER == __BIG_ENDIAN -# define htonll(x) (x) -# define ntohll(x) (x) -# elif __BYTE_ORDER == __LITTLE_ENDIAN -# define htonll(x) __bswap_64(x) -# define ntohll(x) __bswap_64(x) +# ifdef __GLIBC__ +# include <endian.h> +# include <byteswap.h> +# if __BYTE_ORDER == __BIG_ENDIAN +# define htonll(x) (x) +# define ntohll(x) (x) +# elif __BYTE_ORDER == __LITTLE_ENDIAN +# define htonll(x) __bswap_64(x) +# define ntohll(x) __bswap_64(x) +# endif +# else +# include <sys/endian.h> +# define htonll(x) htobe64(x) +# define ntohll(x) be64toh(x) # endif #endif /* + * FreeBSD's libc doesn't define this for userland code + */ +#ifndef s6_addr32 +#define s6_addr32 __u6_addr.__u6_addr32 +#endif + +/* * One of the those eternal staples of C coding: */ #ifndef MIN diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/isnsadm.c new/open-isns-0.97/isnsadm.c --- old/open-isns-0.96/isnsadm.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/isnsadm.c 2016-10-29 03:28:30.000000000 +0200 @@ -70,7 +70,7 @@ static int opt_local = 0; static int opt_control = 0; static int opt_replace = 0; -static const char * opt_keyfile = NULL; +static char * opt_keyfile = NULL; static char * opt_key = NULL; static const char * opt_servername = NULL; static struct sockaddr_storage opt_myaddr; @@ -1051,9 +1051,11 @@ #endif if (!opt_keyfile) { - static char namebuf[PATH_MAX]; - - snprintf(namebuf, sizeof(namebuf), "%s.key", client_name); + size_t capacity = strlen(client_name) + 5; + char *namebuf = isns_malloc(capacity); + if (!namebuf) + isns_fatal("Out of memory."); + snprintf(namebuf, capacity, "%s.key", client_name); opt_keyfile = namebuf; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/local.c new/open-isns-0.97/local.c --- old/open-isns-0.96/local.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/local.c 2016-10-29 03:28:30.000000000 +0200 @@ -131,11 +131,16 @@ static FILE * __isns_local_registry_open_write(char **lock_name) { - char lock_path[PATH_MAX]; + char *lock_path; + size_t capacity; FILE *fp; int fd, retry; - snprintf(lock_path, sizeof(lock_path), "%s.lock", + capacity = strlen(isns_config.ic_local_registry_file) + 6; + lock_path = isns_malloc(capacity); + if (!lock_path) + isns_fatal("Out of memory"); + snprintf(lock_path, capacity, "%s.lock", isns_config.ic_local_registry_file); for (retry = 0; retry < 5; ++retry) { @@ -145,6 +150,7 @@ if (errno != EEXIST) { isns_error("Unable to create %s: %m\n", lock_path); + isns_free(lock_path); return NULL; } isns_error("Cannot lock %s - retry in 1 sec\n", @@ -155,9 +161,11 @@ if (!(fp = fdopen(fd, "w"))) { isns_error("fdopen failed: %m\n"); close(fd); + isns_free(lock_path); return NULL; } - isns_assign_string(lock_name, lock_path); + isns_free(*lock_name); + *lock_name = lock_path; return fp; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/objects.h new/open-isns-0.97/objects.h --- old/open-isns-0.96/objects.h 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/objects.h 2016-10-29 03:28:30.000000000 +0200 @@ -64,7 +64,7 @@ * * The main purpose of these references is to * model some of the weirder life cycle states - * described in RFC 4711. + * described in RFC 4171. * * Every reference via ie_references implies a * reference via ie_users. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/pki.c new/open-isns-0.97/pki.c --- old/open-isns-0.96/pki.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/pki.c 2016-10-29 03:28:30.000000000 +0200 @@ -1,4 +1,4 @@ -/* + /* * PKI related functions * * Copyright (C) 2007 Olaf Kirch <[email protected]> @@ -19,15 +19,53 @@ #ifdef WITH_SECURITY /* versions prior to 9.6.8 didn't seem to have these */ -#if OPADDRCONFIGENSSL_VERSION_NUMBER < 0x00906080L +#if OPENSSL_VERSION_NUMBER < 0x00906080L # define EVP_MD_CTX_init(c) do { } while (0) # define EVP_MD_CTX_cleanup(c) do { } while (0) #endif -#if OPADDRCONFIGENSSL_VERSION_NUMBER < 0x00906070L +#if OPENSSL_VERSION_NUMBER < 0x00906070L # define i2d_DSA_PUBKEY i2d_DSA_PUBKEY_backwards static int i2d_DSA_PUBKEY_backwards(DSA *, unsigned char **); #endif +/* OpenSSL 1.1 made a lot of structures opaque, so we need to + * define the 1.1 wrappers in previous versions. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define EVP_PKEY_base_id(o) ((o)->type) +#define EVP_PKEY_get0_DSA(o) ((o)->pkey.dsa) +static EVP_MD_CTX *EVP_MD_CTX_new(void) +{ + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + EVP_MD_CTX_init(ctx); + return ctx; +} + +static void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} +BN_GENCB *BN_GENCB_new(void) +{ + return OPENSSL_malloc(sizeof(BN_GENCB)); +} +void BN_GENCB_free(BN_GENCB *cb) +{ + OPENSSL_free(cb); +} +#else +/* EVP_dss1 is now gone completely, so just use EVP_sha1 instead. */ +#define EVP_dss1 EVP_sha1 +#endif + static int isns_openssl_init = 0; @@ -117,14 +155,15 @@ { static unsigned char signature[1024]; unsigned int sig_len = sizeof(signature); - EVP_MD_CTX md_ctx; + EVP_MD_CTX *md_ctx; EVP_PKEY *pkey; + const BIGNUM *priv_key = NULL; int err; if ((pkey = peer->is_key) == NULL) return 0; - if (pkey->type != EVP_PKEY_DSA) { + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { isns_debug_message( "Incompatible public key (spi=%s)\n", peer->is_name); @@ -134,7 +173,8 @@ isns_error("isns_dsasig_sign: signature buffer too small\n"); return 0; } - if (pkey->pkey.dsa->priv_key == NULL) { + DSA_get0_key(EVP_PKEY_get0_DSA(pkey), NULL, &priv_key); + if (priv_key == NULL) { isns_error("isns_dsasig_sign: oops, seems to be a public key\n"); return 0; } @@ -142,13 +182,13 @@ isns_debug_auth("Signing messages with spi=%s, DSA/%u\n", peer->is_name, EVP_PKEY_bits(pkey)); - EVP_MD_CTX_init(&md_ctx); - EVP_SignInit(&md_ctx, EVP_dss1()); - isns_message_digest(&md_ctx, pdu, blk); - err = EVP_SignFinal(&md_ctx, + md_ctx = EVP_MD_CTX_new(); + EVP_SignInit(md_ctx, EVP_dss1()); + isns_message_digest(md_ctx, pdu, blk); + err = EVP_SignFinal(md_ctx, signature, &sig_len, pkey); - EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_free(md_ctx); if (err == 0) { isns_dsasig_report_errors("EVP_SignFinal failed", isns_error); @@ -166,27 +206,27 @@ buf_t *pdu, const struct isns_authblk *blk) { - EVP_MD_CTX md_ctx; + EVP_MD_CTX *md_ctx; EVP_PKEY *pkey; int err; if ((pkey = peer->is_key) == NULL) return 0; - if (pkey->type != EVP_PKEY_DSA) { + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { isns_debug_message( "Incompatible public key (spi=%s)\n", peer->is_name); return 0; } - EVP_MD_CTX_init(&md_ctx); - EVP_VerifyInit(&md_ctx, EVP_dss1()); - isns_message_digest(&md_ctx, pdu, blk); - err = EVP_VerifyFinal(&md_ctx, + md_ctx = EVP_MD_CTX_new(); + EVP_VerifyInit(md_ctx, EVP_dss1()); + isns_message_digest(md_ctx, pdu, blk); + err = EVP_VerifyFinal(md_ctx, blk->iab_sig, blk->iab_sig_len, pkey); - EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_free(md_ctx); if (err == 0) { isns_debug_auth("*** Incorrect signature ***\n"); @@ -265,7 +305,7 @@ int bytes; *ptr = NULL; - bytes = i2d_DSA_PUBKEY(pkey->pkey.dsa, (unsigned char **) ptr); + bytes = i2d_DSA_PUBKEY(EVP_PKEY_get0_DSA(pkey), (unsigned char **) ptr); if (bytes < 0) return 0; @@ -398,6 +438,10 @@ { FILE *fp; DSA *dsa; +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + BN_GENCB *cb; +#endif + const int dsa_key_bits = 1024; if (access(filename, R_OK) == 0) return 1; @@ -409,8 +453,19 @@ } isns_notice("Generating DSA parameters; this may take a while\n"); - dsa = DSA_generate_parameters(1024, NULL, 0, +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + cb = BN_GENCB_new(); + BN_GENCB_set(cb, (int (*)(int, int, BN_GENCB *)) isns_dsa_param_gen_callback, NULL); + dsa = DSA_new(); + if (!DSA_generate_parameters_ex(dsa, dsa_key_bits, NULL, 0, NULL, NULL, cb)) { + DSA_free(dsa); + dsa = NULL; + } + BN_GENCB_free(cb); +#else + dsa = DSA_generate_parameters(dsa_key_bits, NULL, 0, NULL, NULL, isns_dsa_param_gen_callback, NULL); +#endif write(1, "\n", 1); if (dsa == NULL) { @@ -487,19 +542,29 @@ const char *name, size_t namelen) { isns_simple_keystore_t *store = (isns_simple_keystore_t *) store_base; - char pathname[PATH_MAX]; + char *pathname; + size_t capacity; + EVP_PKEY *result; /* Refuse to open key files with names * that refer to parent directories */ if (memchr(name, '/', namelen) || name[0] == '.') return NULL; - snprintf(pathname, sizeof(pathname), + capacity = strlen(store->sc_dirpath) + 2 + namelen; + pathname = isns_malloc(capacity); + if (!pathname) + isns_fatal("Out of memory."); + snprintf(pathname, capacity, "%s/%.*s", store->sc_dirpath, (int) namelen, name); - if (access(pathname, R_OK) < 0) + if (access(pathname, R_OK) < 0) { + isns_free(pathname); return NULL; - return isns_dsasig_load_public_pem(NULL, pathname); + } + result = isns_dsasig_load_public_pem(NULL, pathname); + isns_free(pathname); + return result; } isns_keystore_t * @@ -515,7 +580,7 @@ return (isns_keystore_t *) store; } -#if OPADDRCONFIGENSSL_VERSION_NUMBER < 0x00906070L +#if OPENSSL_VERSION_NUMBER < 0x00906070L #undef i2d_DSA_PUBKEY int diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/policy.c new/open-isns-0.97/policy.c --- old/open-isns-0.96/policy.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/policy.c 2016-10-29 03:28:30.000000000 +0200 @@ -90,7 +90,7 @@ /* If the caller is the local root user, s/he can * do anything. */ - if (msg->im_creds && msg->im_creds->uid == 0) { + if (msg->im_creds && msg->im_creds->CMSGCRED_uid == 0) { policy = &isns_superhero_powers; goto found; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/security.c new/open-isns-0.97/security.c --- old/open-isns-0.96/security.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/security.c 2016-10-29 03:28:30.000000000 +0200 @@ -15,6 +15,10 @@ #ifdef WITH_SECURITY +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define EVP_PKEY_base_id(o) ((o)->type) +#endif + /* * Allocate a security peer */ @@ -37,7 +41,7 @@ if (pk) { const char *algo; - switch (pk->type) { + switch (EVP_PKEY_base_id(pk)) { case EVP_PKEY_DSA: algo = "DSA"; break; case EVP_PKEY_RSA: algo = "RSA"; break; default: algo = "unknown"; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/socket.c new/open-isns-0.97/socket.c --- old/open-isns-0.96/socket.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/socket.c 2016-10-29 03:28:30.000000000 +0200 @@ -342,7 +342,7 @@ static void isns_pdu_enqueue(isns_socket_t *sock, struct sockaddr_storage *addr, socklen_t alen, - buf_t *segment, struct ucred *creds) + buf_t *segment, struct_cmsgcred_t *creds) { isns_message_queue_t *q = &sock->is_partial; struct isns_partial_msg *msg; @@ -412,8 +412,7 @@ */ if (!isns_pdu_authenticate(sock->is_security, msg, segment)) goto drop; - } else - if (msg->imp_header.i_flags & ISNS_F_AUTHBLK_PRESENT) { + } else if (msg->imp_header.i_flags & ISNS_F_AUTHBLK_PRESENT) { /* Oops, unauthenticated fragment in an * authenticated message. */ isns_debug_message( @@ -594,8 +593,11 @@ isns_net_stream_accept(isns_socket_t *sock) { isns_socket_t *child; + int fd; +#ifdef SO_PASSCRED + int passcred = 0; socklen_t optlen; - int fd, passcred = 0; +#endif fd = accept(sock->is_desc, NULL, NULL); if (fd < 0) { @@ -604,12 +606,14 @@ return; } +#ifdef SO_PASSCRED optlen = sizeof(passcred); if (getsockopt(sock->is_desc, SOL_SOCKET, SO_PASSCRED, &passcred, &optlen) >= 0) { setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &passcred, sizeof(passcred)); } +#endif child = isns_net_alloc(fd); child->is_type = SOCK_STREAM; @@ -621,6 +625,9 @@ child->is_error = isns_net_stream_error; child->is_poll_mask = POLLIN|POLLHUP; child->is_security = sock->is_security; + /* We need to check the domain of the socket later. */ + memcpy(&child->is_src.addr, &sock->is_src.addr, sock->is_src.addrlen); + child->is_src.addrlen = sock->is_src.addrlen; if (isns_config.ic_network.idle_timeout) isns_net_set_timeout(child, @@ -693,10 +700,10 @@ isns_net_recvmsg(isns_socket_t *sock, void *buffer, size_t count, struct sockaddr *addr, socklen_t *alen, - struct ucred **cred) + struct_cmsgcred_t **cred) { - static struct ucred cred_buf; - unsigned int control[128]; + static struct_cmsgcred_t cred_buf; + unsigned int control[128 + sizeof(cred_buf)]; struct cmsghdr *cmsg; struct msghdr msg; struct iovec iov; @@ -708,8 +715,13 @@ iov.iov_len = count; memset(&msg, 0, sizeof(msg)); - msg.msg_name = addr; - msg.msg_namelen = *alen; + /* Some kernels don't provide peer names for AF_LOCAL sockets, + * we'll synthesize a peer name based on the file descriptor + * later. */ + if (sock->is_dst.addr.ss_family != AF_LOCAL && sock->is_src.addr.ss_family != AF_LOCAL) { + msg.msg_name = addr; + msg.msg_namelen = *alen; + } msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = control; @@ -723,7 +735,7 @@ cmsg = CMSG_FIRSTHDR(&msg); while (cmsg) { if (cmsg->cmsg_level == SOL_SOCKET - && cmsg->cmsg_type == SCM_CREDENTIALS) { + && cmsg->cmsg_type == SCM_CREDENTIALS_portable) { memcpy(&cred_buf, CMSG_DATA(cmsg), sizeof(cred_buf)); *cred = &cred_buf; break; @@ -732,7 +744,20 @@ cmsg = CMSG_NXTHDR(&msg, cmsg); } - *alen = msg.msg_namelen; + if (sock->is_dst.addr.ss_family != AF_LOCAL && sock->is_src.addr.ss_family != AF_LOCAL) { + *alen = msg.msg_namelen; + } else { + /* AF_LOCAL sockets don't have valid peer names on some + * kernels (e.g. Hurd), so synthesize one based on the + * file descriptor number. (It's only used for matching + * multiple PDUs based on their origin.) This is unique + * because this function is only ever called for stream + * sockets. */ + struct sockaddr_un *sun = (struct sockaddr_un *)addr; + sun->sun_family = AF_LOCAL; + memcpy(&sun->sun_path, &sock->is_desc, sizeof(int)); + *alen = offsetof(struct sockaddr_un, sun_path) + sizeof(int); + } return len; } @@ -741,7 +766,7 @@ { unsigned char buffer[ISNS_MAX_BUFFER]; struct sockaddr_storage addr; - struct ucred *creds = NULL; + struct_cmsgcred_t *creds = NULL; socklen_t alen = sizeof(addr); buf_t *bp; size_t count, total = 0; @@ -803,6 +828,41 @@ goto again; } +#ifndef SO_PASSCRED +/* Without SO_PASSCRED, we need to make sure that credentials are + * added to all sent messages. (Otherwise recvmsg will not receive + * any credentials. */ +ssize_t send_with_creds(int sockfd, const void *buf, size_t len, int flags) +{ + unsigned char control[CMSG_SPACE(sizeof(struct_cmsgcred_t))]; + struct cmsghdr *cmsg; + struct msghdr msg; + struct iovec iov; + + iov.iov_base = (void *)buf; + iov.iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + memset(&control, 0, sizeof(control)); + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct_cmsgcred_t)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS_portable; + /* The kernel will fill the actual data structure for us, so + * there's no need to bother with doing that ourselves. */ + + return sendmsg(sockfd, &msg, flags); +} +#endif + void isns_net_stream_xmit(isns_socket_t *sock) { @@ -822,7 +882,19 @@ return; count = buf_avail(bp); +#ifndef SO_PASSCRED + /* If SO_PASSCRED is not available, we need to ensure we add + * credentials to every sent message. Only do this for AF_LOCAL + * sockets though, as this won't work on AF_INET{,6}. Check + * both is_src and is_dst for AF_LOCAL, because one of them + * might be AF_UNSPEC. */ + if (sock->is_dst.addr.ss_family == AF_LOCAL || sock->is_src.addr.ss_family == AF_LOCAL) + len = send_with_creds(sock->is_desc, buf_head(bp), count, MSG_DONTWAIT); + else + len = send(sock->is_desc, buf_head(bp), count, MSG_DONTWAIT); +#else len = send(sock->is_desc, buf_head(bp), count, MSG_DONTWAIT); +#endif if (len < 0) { isns_net_stream_error(sock, errno); return; @@ -1432,6 +1504,7 @@ isns_socket_open(isns_socket_t *sock) { int af, fd, state = ISNS_SOCK_IDLE; + int no = 0; if (sock->is_desc >= 0) return 1; @@ -1462,26 +1535,39 @@ src_addr = (struct sockaddr *) &sock->is_src.addr; src_len = sock->is_src.addrlen; - /* For debugging only! */ - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { - isns_error("setsockopt(SO_REUSEADDR) failed: %m\n"); - goto failed; + /* GNU Hurd only supports SO_REUSEADDR for AF_INET, and + * it's useless for AF_LOCAL on any platform. (unlink + * is called before bind.) */ + if (af == AF_INET || af == AF_INET6) { + /* For debugging only! */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + isns_error("setsockopt(SO_REUSEADDR) failed: %m\n"); + goto failed; + } } switch (af) { case AF_LOCAL: unlink(((struct sockaddr_un *) src_addr)->sun_path); +#ifdef SO_PASSCRED if (sock->is_type == SOCK_STREAM && setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) { isns_error("setsockopt(SO_PASSCRED) failed: %m\n"); goto failed; } +#endif break; - case AF_INET: case AF_INET6: +#ifdef IPV6_V6ONLY + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&no, sizeof(no))) { + isns_warning("setsockopt(IPV6_V6ONLY, false) failed: %m"); + } +#endif + /* no break, fall through */ + case AF_INET: if (isns_addr_get_port(src_addr) == 0) { if (!__isns_socket_bind_random(fd, src_addr, src_len)) goto failed; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/socket.h new/open-isns-0.97/socket.h --- old/open-isns-0.96/socket.h 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/socket.h 2016-10-29 03:28:30.000000000 +0200 @@ -20,7 +20,7 @@ unsigned int imp_msg_size; buf_t * imp_chain; - struct ucred imp_credbuf; + struct_cmsgcred_t imp_credbuf; }; #define imp_users imp_base.im_users diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/open-isns-0.96/util.c new/open-isns-0.97/util.c --- old/open-isns-0.96/util.c 2016-06-19 19:25:05.000000000 +0200 +++ new/open-isns-0.97/util.c 2016-10-29 03:28:30.000000000 +0200 @@ -40,7 +40,7 @@ default: bad: - err(1, "parse_size: unknown unit in \"%s\"\n", arg); + err(1, "parse_size: unknown unit in \"%s\"", arg); } if (*s != '\0') @@ -78,7 +78,7 @@ ret = strtoul(arg, &s, 0); if (*s != '\0') - err(1, "parse_count: unexpected character in \"%s\"\n", arg); + err(1, "parse_count: unexpected character in \"%s\"", arg); return ret; } @@ -91,7 +91,7 @@ ret = strtol(arg, &s, 0); if (*s != '\0') - err(1, "parse_count: unexpected character in \"%s\"\n", arg); + err(1, "parse_count: unexpected character in \"%s\"", arg); return ret; } @@ -104,7 +104,7 @@ ret = strtoll(arg, &s, 0); if (*s != '\0') - err(1, "parse_count: unexpected character in \"%s\"\n", arg); + err(1, "parse_count: unexpected character in \"%s\"", arg); return ret; } @@ -117,7 +117,7 @@ ret = strtod(arg, &s); if (*s != '\0') - err(1, "parse_count: unexpected character in \"%s\"\n", arg); + err(1, "parse_count: unexpected character in \"%s\"", arg); return ret; }
