is only useful when doing load balancing within failover.
[ISC-Bugs #26108]
+- Fix a set of issues that were discovered via a code inspection
+ tool. Thanks to Jiri Popelka and Tomas Hozza Red Hat for the logs
+ and patches.
+ [ISC-Bugs #23833]
+
Changes since 4.2.3
! Add a check for a null pointer before calling the regexec function.
memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr));
DHCPv6DestAddr.sin6_family = AF_INET6;
DHCPv6DestAddr.sin6_port = remote_port;
- inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
- &DHCPv6DestAddr.sin6_addr);
+ if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
+ &DHCPv6DestAddr.sin6_addr) <= 0) {
+ log_fatal("Bad address %s", All_DHCP_Relay_Agents_and_Servers);
+ }
code = D6O_CLIENTID;
if (!option_code_hash_lookup(&clientid_option,
* not sure based on what additional keys now).
*/
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
- if (!evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
+ if ((oc == NULL) ||
+ !evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
lease->options, NULL, &global_scope,
oc, MDL) ||
lease->server_id.len == 0) {
Memory allocation... */
/*
- * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
#endif
}
- (*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
- if (!(*ptr) -> refcnt)
+ (*ptr)->refcnt--;
+ rc_register (file, line, ptr, *ptr, (*ptr)->refcnt, 1, RC_MISC);
+ if ((*ptr)->refcnt == 0) {
dfree ((*ptr), file, line);
- if ((*ptr) -> refcnt < 0) {
+ } else if ((*ptr)->refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
dump_rc_history (*ptr);
/* In this function h should be a (struct subnet *) */
isc_result_t status;
- int updatep = 0;
if (h -> type != dhcp_type_subnet)
return DHCP_R_INVALIDARG;
if (status == ISC_R_SUCCESS)
return status;
}
- if (updatep)
- return ISC_R_SUCCESS;
+
return ISC_R_NOTFOUND;
}
/* In this function h should be a (struct shared_network *) */
isc_result_t status;
- int updatep = 0;
if (h -> type != dhcp_type_shared_network)
return DHCP_R_INVALIDARG;
if (status == ISC_R_SUCCESS)
return status;
}
- if (updatep)
- return ISC_R_SUCCESS;
+
return ISC_R_NOTFOUND;
}
Support Services in Vancouver, B.C. */
/*
- * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
memcpy(&hw->hbuf[1], sa->sa_data, 6);
break;
case ARPHRD_FDDI:
- hw->hlen = 17;
+ hw->hlen = 7;
hw->hbuf[0] = HTYPE_FDDI;
- memcpy(&hw->hbuf[1], sa->sa_data, 16);
+ memcpy(&hw->hbuf[1], sa->sa_data, 6);
break;
default:
log_fatal("Unsupported device type %ld for \"%s\"",
option_cache_reference(&op->next, nop, MDL);
option_cache_dereference(&nop, MDL);
} else {
- save_option_buffer(universe, options, bp,
- bp->data + offset, len,
- code, 1);
+ if (save_option_buffer(universe, options, bp,
+ bp->data + offset, len,
+ code, 1) == 0) {
+ log_error("parse_option_buffer: "
+ "save_option_buffer failed");
+ buffer_dereference(&bp, MDL);
+ return 0;
+ }
}
}
option_dereference(&option, MDL);
* Load all options into a buffer, and then split them out into the three
* separate fields in the dhcp packet (options, file, and sname) where
* options can be stored.
+ *
+ * returns 0 on error, length of packet on success
*/
int
cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
if (inpacket &&
(op = lookup_option(&dhcp_universe, inpacket->options,
- DHO_DHCP_MAX_MESSAGE_SIZE))) {
- evaluate_option_cache(&ds, inpacket,
- lease, client_state, in_options,
- cfg_options, scope, op, MDL);
+ DHO_DHCP_MAX_MESSAGE_SIZE)) &&
+ (evaluate_option_cache(&ds, inpacket, lease,
+ client_state, in_options,
+ cfg_options, scope, op, MDL) != 0)) {
if (ds.len >= sizeof (u_int16_t)) {
i = getUShort(ds.data);
if(!mms || (i < mms))
* in the packet if there is space. Note that the option
* may only be included if the client supplied one.
*/
- if ((priority_len < PRIORITY_COUNT) &&
+ if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) &&
(lookup_option(&fqdn_universe, inpacket->options,
FQDN_ENCODED) != NULL))
priority_list[priority_len++] = DHO_FQDN;
* DHCPINFORM or DHCPLEASEQUERY responses (if the client
* didn't request it).
*/
- if ((priority_len < PRIORITY_COUNT) &&
+ if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) &&
((inpacket->packet_type == DHCPDISCOVER) ||
(inpacket->packet_type == DHCPREQUEST)))
priority_list[priority_len++] = DHO_SUBNET_MASK;
cfg_options,
vendor_cfg_option -> code);
if (tmp)
- evaluate_option_cache (&name, packet, lease,
- client_state,
- in_options,
- cfg_options,
- scope, tmp, MDL);
+ /* No need to check the return as we check name.len below */
+ (void) evaluate_option_cache (&name, packet, lease,
+ client_state,
+ in_options,
+ cfg_options,
+ scope, tmp, MDL);
} else if (vuname) {
name.data = (unsigned char *)s;
name.len = strlen (s);
/* Find the value of the option... */
od.len = 0;
if (oc) {
- evaluate_option_cache (&od, packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, MDL);
+ /* No need to check the return as we check od.len below */
+ (void) evaluate_option_cache (&od, packet,
+ lease, client_state, in_options,
+ cfg_options, scope, oc, MDL);
/* If we have encapsulation for this option, and an oc
* lookup succeeded, but the evaluation failed, it is
struct option_cache *oc = (struct option_cache *)(ocp -> car);
if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
continue;
- evaluate_option_cache (&results [oc -> option -> code],
- packet, lease, client_state, in_options,
- cfg_options, scope, oc, MDL);
+ /* No need to check the return code, we check the length later */
+ (void) evaluate_option_cache (&results[oc->option->code],
+ packet, lease, client_state,
+ in_options, cfg_options, scope,
+ oc, MDL);
}
/* We add a byte for the flags field.
* We add two bytes for the two RCODE fields.
oc = (struct option_cache *)(ocp->car);
if (oc->option->code > FQDN_SUBOPTION_COUNT)
log_fatal("Impossible condition at %s:%d.", MDL);
-
- evaluate_option_cache(&results[oc->option->code], packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, MDL);
+ /* No need to check the return code, we check the length later */
+ (void) evaluate_option_cache(&results[oc->option->code], packet,
+ lease, client_state, in_options,
+ cfg_options, scope, oc, MDL);
}
/* We add a byte for the flags field at the start of the option.
the token specified in separator. If max is zero, any number of
numbers will be parsed; otherwise, exactly max numbers are
expected. Base and size tell us how to internalize the numbers
- once they've been tokenized. */
+ once they've been tokenized.
+
+ buf - A pointer to space to return the parsed value, if it is null
+ then the function will allocate space for the return.
+
+ max - The maximum number of items to store. If zero there is no
+ maximum. When buf is null and the function needs to allocate space
+ it will do an allocation of max size at the beginning if max is non
+ zero. If max is zero then the allocation will be done later, after
+ the function has determined the size necessary for the incoming
+ string.
+
+ returns NULL on errors or a pointer to the value string on success.
+ The pointer will either be buf if it was non-NULL or newly allocated
+ space if buf was NULL
+ */
+
unsigned char *parse_numeric_aggregate (cfile, buf,
max, separator, base, size)
bufp = (unsigned char *)dmalloc (*max * size / 8, MDL);
if (!bufp)
log_fatal ("no space for numeric aggregate");
- s = 0;
- } else
- s = bufp;
+ }
+ s = bufp;
do {
if (count) {
parse_warn (cfile, "too few numbers.");
if (token != SEMI)
skip_to_semi (cfile);
+ /* free bufp if it was allocated */
+ if ((bufp != NULL) && (bufp != buf))
+ dfree(bufp, MDL);
return (unsigned char *)0;
}
token = next_token (&val, (unsigned *)0, cfile);
(base != 16 || token != NUMBER_OR_NAME)) {
parse_warn (cfile, "expecting numeric value.");
skip_to_semi (cfile);
- return (unsigned char *)0;
+ /* free bufp if it was allocated */
+ if ((bufp != NULL) && (bufp != buf))
+ dfree(bufp, MDL);
+ /* free any linked numbers we may have allocated */
+ while (c) {
+ pair cdr = c->cdr;
+ dfree(c->car, MDL);
+ dfree(c, MDL);
+ c = cdr;
+ }
+ return (NULL);
}
/* If we can, convert the number now; otherwise, build
a linked list of all the numbers. */
/* If we had to cons up a list, convert it now. */
if (c) {
+ /*
+ * No need to cleanup bufp, to get here we didn't allocate
+ * bufp above
+ */
bufp = (unsigned char *)dmalloc (count * size / 8, MDL);
if (!bufp)
log_fatal ("no space for numeric aggregate.");
parse_warn (cfile, "can't allocate buffer for base64 data.");
data -> len = 0;
data -> data = (unsigned char *)0;
- return 0;
+ goto out;
}
j = k = 0;
return 0;
}
*fmt = g;
+ /* FALL THROUGH */
+ /* to get string value for the option */
case 'X':
token = peek_token (&val, (unsigned *)0, cfile);
if (token == NUMBER_OR_NAME || token == NUMBER) {
"encapsulation format");
goto parse_exit;
}
+ /* FALL THROUGH */
+ /* to get string value for the option */
case 'X':
len = parse_X (cfile, &hunkbuf [hunkix],
sizeof hunkbuf - hunkix);
bp = (struct buffer *)0;
if (!buffer_allocate (&bp, hunkix + nul_term, MDL))
log_fatal ("no memory to store option declaration.");
- if (!bp -> data)
- log_fatal ("out of memory allocating option data.");
memcpy (bp -> data, hunkbuf, hunkix + nul_term);
if (!option_cache_allocate (oc, MDL))
buf [rv] = 0;
return rv;
}
+ break;
case expr_gethostname:
if (len > 13) {
const char *prefix,
const char *suffix, const char *buf)
{
- int len = strlen (buf) + strlen (prefix);
+ int len = 0;
+ if (prefix != NULL)
+ len = strlen (prefix);
+ if (buf != NULL)
+ len += strlen (buf);
+
if (col + len > 79) {
if (indent + len < 79) {
indent_spaces (file, indent);
fputs (prefix, file);
col += strlen (prefix);
}
- fputs (buf, file);
- col += len;
+ if ((buf != NULL) && (*buf != 0)) {
+ fputs (buf, file);
+ col += strlen(buf);
+ }
if (suffix && *suffix) {
if (col + strlen (suffix) > 79) {
indent_spaces (file, indent);
return 0;
}
-/* Return data hanging off of an option cache structure, or if there
- isn't any, evaluate the expression hanging off of it and return the
- result of that evaluation. There should never be both an expression
- and a valid data_string. */
+/*
+ * Return data hanging off of an option cache structure, or if there
+ * isn't any, evaluate the expression hanging off of it and return the
+ * result of that evaluation. There should never be both an expression
+ * and a valid data_string.
+ *
+ * returns 0 if there wasn't an expression or it couldn't be evaluated
+ * returns non-zero if there was an expression or string that was evaluated
+ * When it returns zero the arguements, in particualr resutl, should not
+ * be modified
+ */
int evaluate_option_cache (result, packet, lease, client_state,
in_options, cfg_options, scope, oc, file, line)
col = write_expression (file, expr -> data.suffix.len,
col, scol, 0);
col = token_print_indent (file, col, indent, "", "", ")");
+ break;
case expr_lcase:
col = token_print_indent(file, col, indent, "", "", "lcase");
const char *file;
int line;
{
- struct fundef *bp = *ptr;
+ struct fundef *bp;
struct string_list *sp, *next;
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (!bp) {
+ if ((ptr == NULL) || (*ptr == NULL)) {
log_error ("%s(%d): null pointer", file, line);
#if defined (POINTER_DEBUG)
abort ();
#endif
}
+ bp = *ptr;
bp -> refcnt--;
rc_register (file, line, ptr, bp, bp -> refcnt, 1, RC_MISC);
if (bp -> refcnt < 0) {
if (binding -> value -> value.data.terminated) {
data_string_copy (value, &binding -> value -> value.data, MDL);
} else {
- buffer_allocate (&value -> buffer,
- binding -> value -> value.data.len,
- MDL);
- if (!value -> buffer)
+ if (buffer_allocate (&value->buffer,
+ binding->value->value.data.len,
+ MDL) == 0) {
return 0;
+ }
memcpy (value -> buffer -> data,
binding -> value -> value.data.data,
EREPORT(("dst_read_private_key(): Null key name passed in\n"));
return (NULL);
} else
- strcpy(keyname, in_keyname);
+ strncpy(keyname, in_keyname, PATH_MAX);
/* before I read in the public key, check if it is allowed to sign */
if ((pubkey = dst_s_read_public_key(keyname, in_id, in_alg)) == NULL)
if ((nn = fwrite(encoded_block, 1, len, fp)) != len) {
EREPORT(("dst_write_private_key(): Write failure on %s %d != %d errno=%d\n",
file, out_len, nn, errno));
+ fclose(fp);
return (-5);
}
fclose(fp);
int alg ;
int start = DST_KEY_START;
- if (rdata == NULL || len <= DST_KEY_ALG) /* no data */
+ if (in_name == NULL || rdata == NULL || len <= DST_KEY_ALG) /* no data */
return (NULL);
alg = (u_int8_t) rdata[DST_KEY_ALG];
if (!dst_check_algorithm(alg)) { /* make sure alg is available */
if ((key_st = dst_s_get_key_struct(in_name, alg, 0, 0, 0)) == NULL)
return (NULL);
- if (in_name == NULL)
- return (NULL);
key_st->dk_flags = dst_s_get_int16(rdata);
key_st->dk_proto = (u_int16_t) rdata[DST_KEY_PROT];
if (key_st->dk_flags & DST_EXTEND_FLAG) {
dkey->dk_func->from_dns_key != NULL) {
if (dkey->dk_func->from_dns_key(dkey, key_buf, key_len) < 0) {
EREPORT(("dst_buffer_to_key(): dst_buffer_to_hmac failed\n"));
- return (dst_free_key(dkey));
+ (void) (dst_free_key(dkey));
+ return (NULL);
}
return (dkey);
}
+ (void) (dst_free_key(dkey));
return (NULL);
}
else {
EREPORT(("dst_free_key(): Unknown key alg %d\n",
f_key->dk_alg));
- free(f_key->dk_KEY_struct); /* SHOULD NOT happen */
}
if (f_key->dk_KEY_struct) {
- free(f_key->dk_KEY_struct);
- f_key->dk_KEY_struct = NULL;
+ SAFE_FREE(f_key->dk_KEY_struct);
}
if (f_key->dk_key_name)
SAFE_FREE(f_key->dk_key_name);
/*
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
* Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
{
const u_char *bp = bin_data;
char *op = out_buf;
+ int res = 0;
unsigned lenh = 0, len64 = 0;
unsigned local_in_len = bin_len;
unsigned local_out_len = out_len;
local_out_len -= lenh;
op += lenh;
}
- len64 = b64_ntop(bp, local_in_len, op, local_out_len - 2);
- if (len64 < 0)
+ res = b64_ntop(bp, local_in_len, op, local_out_len - 2);
+ if (res < 0)
return (-1);
+ len64 = (unsigned) res;
op += len64++;
*(op++) = '\n'; /* put CR in the output */
*op = '\0'; /* make sure output is 0 terminated */
unsigned blen;
char *bp;
u_char bstr[RAW_KEY_SIZE];
+ int res = 0;
if (buf == NULL || *buf == NULL) { /* error checks */
EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n"));
if (bp != NULL)
*bp = '\0';
- blen = b64_pton(*buf, bstr, sizeof(bstr));
- if (blen <= 0) {
+ res = b64_pton(*buf, bstr, sizeof(bstr));
+ if (res <= 0) {
EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
return (0);
}
- else if (loclen < blen) {
+ blen = (unsigned) res;
+ if (loclen < blen) {
EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
return (0);
}
unsigned plen = sizeof(pathname);
if (*dst_path != '\0') {
- strcpy(pathname, dst_path);
+ strncpy(pathname, dst_path, PATH_MAX);
plen -= strlen(pathname);
}
else
/*
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
* Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
int sign_len = 0;
MD5_CTX *ctx = NULL;
+ if (d_key == NULL || d_key->dk_KEY_struct == NULL)
+ return (-1);
+ key = (HMAC_Key *) d_key->dk_KEY_struct;
+
if (mode & SIG_MODE_INIT)
ctx = (MD5_CTX *) malloc(sizeof(*ctx));
else if (context)
if (ctx == NULL)
return (-1);
- if (d_key == NULL || d_key->dk_KEY_struct == NULL)
- return (-1);
- key = (HMAC_Key *) d_key->dk_KEY_struct;
-
if (mode & SIG_MODE_INIT) {
MD5Init(ctx);
MD5Update(ctx, key->hk_ipad, HMAC_LEN);
HMAC_Key *key;
MD5_CTX *ctx = NULL;
+ if (d_key == NULL || d_key->dk_KEY_struct == NULL)
+ return (-1);
+ key = (HMAC_Key *) d_key->dk_KEY_struct;
+
if (mode & SIG_MODE_INIT)
ctx = (MD5_CTX *) malloc(sizeof(*ctx));
else if (context)
if (ctx == NULL)
return (-1);
- if (d_key == NULL || d_key->dk_KEY_struct == NULL)
- return (-1);
-
- key = (HMAC_Key *) d_key->dk_KEY_struct;
if (mode & SIG_MODE_INIT) {
MD5Init(ctx);
MD5Update(ctx, key->hk_ipad, HMAC_LEN);
HMAC_Key *hkey = NULL;
MD5_CTX ctx;
unsigned local_keylen = keylen;
+ u_char tk[MD5_LEN];
- if (dkey == NULL || key == NULL || keylen < 0)
+ /* Do we need to check if keylen == 0? The original
+ * code didn't, so we don't currently */
+ if (dkey == NULL || key == NULL)
return (-1);
if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
/* if key is longer than HMAC_LEN bytes reset it to key=MD5(key) */
if (keylen > HMAC_LEN) {
- u_char tk[MD5_LEN];
+ memset(tk, 0, sizeof(tk));
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)key, keylen);
MD5Final(tk, &ctx);
const unsigned buff_len)
{
char *bp;
- int i;
+ int i, res;
unsigned len, b_len, key_len;
u_char key[HMAC_LEN];
HMAC_Key *hkey;
bp += strlen("Key: ");
b_len = buff_len - (bp - buff);
- len = b64_ntop(key, key_len, bp, b_len);
- if (len < 0)
+ res = b64_ntop(key, key_len, bp, b_len);
+ if (res < 0)
return (-1);
+ len = (unsigned) res;
bp += len;
*(bp++) = '\n';
*bp = '\0';
struct timeval tv;
u_char buf[1024];
+ name = files[f_cnt++];
if (f_round == 0 || files[f_cnt] == NULL || work->file_digest == NULL)
if (gettimeofday(&tv, NULL)) /* only do this if needed */
return (0);
if (f_round == 0) /* first time called set to one hour ago */
f_round = (tv.tv_sec - MAX_OLD);
- name = files[f_cnt++];
if (files[f_cnt] == NULL) { /* end of list of files */
if(f_cnt <= 1) /* list is too short */
return (0);
new->step = step;
new->block = block;
new->key = new_key;
- if (dst_sign_data(SIG_MODE_INIT, new_key, &new->ctx, NULL, 0, NULL, 0))
+ if (dst_sign_data(SIG_MODE_INIT, new_key, &new->ctx, NULL, 0, NULL, 0)) {
+ SAFE_FREE(new);
return (NULL);
+ }
return (new);
}
DST_HASH_SIZE *
DST_NUM_HASHES);
my_work->file_digest = NULL;
- if (my_work->output == NULL)
+ if (my_work->output == NULL) {
+ SAFE_FREE(my_work);
return (n);
+ }
memset(my_work->output, 0x0, my_work->needed);
/* allocate upto 4 different HMAC hash functions out of order */
#if DST_NUM_HASHES >= 3
my_work->hash[3] = get_hmac_key(5, DST_RANDOM_BLOCK_SIZE / 4);
#endif
my_work->hash[0] = get_hmac_key(1, DST_RANDOM_BLOCK_SIZE);
- if (my_work->hash[0] == NULL) /* if failure bail out */
+ if (my_work->hash[0] == NULL) { /* if failure bail out */
+ for (i = 1; i < DST_NUM_HASHES; i++) {
+ if (my_work->hash[i] != NULL) {
+ dst_free_key(my_work->hash[i]->key);
+ SAFE_FREE(my_work->hash[i]);
+ }
+ }
+ SAFE_FREE(my_work->output);
+ SAFE_FREE(my_work);
return (n);
+ }
s = own_random(my_work);
/* if more generated than needed store it for future use */
if (s >= my_work->needed) {
n += my_work->needed;
/* saving unused data for next time */
unused = s - my_work->needed;
+ if (unused > sizeof(old_unused)) {
+ unused = sizeof(old_unused);
+ }
memcpy(old_unused, &my_work->output[my_work->needed],
unused);
} else {
/* delete the allocated work area */
for (i = 0; i < DST_NUM_HASHES; i++) {
- dst_free_key(my_work->hash[i]->key);
- SAFE_FREE(my_work->hash[i]);
+ if (my_work->hash[i] != NULL) {
+ dst_free_key(my_work->hash[i]->key);
+ SAFE_FREE(my_work->hash[i]);
+ }
}
SAFE_FREE(my_work->output);
SAFE_FREE(my_work);
prand_hash *hash;
unsigned out = 0;
unsigned i;
- int n;
+ int n, res;
if (output == NULL || size <= 0)
return (-2);
for (n = 0; n < DST_NUMBER_OF_COUNTERS; n++)
i = (int) counter[n]++;
- i = dst_sign_data(SIG_MODE_ALL, my_key, NULL,
+ res = dst_sign_data(SIG_MODE_ALL, my_key, NULL,
(u_char *) counter, hb_size,
semi_old, sizeof(semi_old));
+ if (res < 0) {
+ return res;
+ }
+ i = (unsigned) res;
if (i != hb_size)
EREPORT(("HMAC SIGNATURE FAILURE %d\n", i));
cnt++;
Buffer access functions for the object management protocol... */
/*
- * Copyright (c) 2004,2005,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
int sig_flags = SIG_MODE_UPDATE;
omapi_connection_object_t *c;
- /* Make sure len is valid. */
- if (len < 0)
- return DHCP_R_INVALIDARG;
+ /* no need to verify len as it's unsigned */
if (!h || h -> type != omapi_type_connection)
return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
Subroutines for dealing with connections. */
/*
- * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
/* Find the matching connect object, if there is one. */
omapi_array_foreach_begin (omapi_connections,
omapi_connection_object_t, lp) {
- for (i = 0; (lp -> connect_list &&
- i < lp -> connect_list -> count); i++) {
+ for (i = 0; (lp->connect_list &&
+ i < lp->connect_list->count); i++) {
if (!memcmp (&remote.sin_addr,
- &lp -> connect_list -> addresses [i].address,
+ &lp->connect_list->addresses[i].address,
sizeof remote.sin_addr) &&
(ntohs (remote.sin_port) ==
- lp -> connect_list -> addresses [i].port))
- lp -> state = omapi_connection_connected;
- lp -> remote_addr = remote;
- lp -> remote_addr.sin_family = AF_INET;
- omapi_addr_list_dereference (&lp -> connect_list, MDL);
- lp -> index = connect_index;
- status = omapi_signal_in ((omapi_object_t *)lp,
- "connect");
- omapi_connection_dereference (&lp, MDL);
- return;
+ lp->connect_list->addresses[i].port)) {
+ lp->state = omapi_connection_connected;
+ lp->remote_addr = remote;
+ lp->remote_addr.sin_family = AF_INET;
+ omapi_addr_list_dereference(&lp->connect_list, MDL);
+ lp->index = connect_index;
+ status = omapi_signal_in((omapi_object_t *)lp,
+ "connect");
+ omapi_connection_dereference (&lp, MDL);
+ return;
+ }
}
} omapi_array_foreach_end (omapi_connections,
omapi_connection_object_t, lp);
static isc_result_t omapi_connection_connect_internal (omapi_object_t *h)
{
- int error;
+ int error = 0;
omapi_connection_object_t *c;
socklen_t sl;
isc_result_t status;
obj = (omapi_listener_object_t *)0;
status = omapi_listener_allocate (&obj, MDL);
if (status != ISC_R_SUCCESS)
- return status;
+ /*
+ * we could simply return here but by going to
+ * error_exit we keep the code check tools happy
+ * without removing the NULL check on obj at
+ * the exit, which we could skip curently but
+ * might want in the future.
+ */
+ goto error_exit;
obj->socket = -1;
/* Connect this object to the inner object. */
omapi_protocol_object_t *p;
omapi_object_t *c;
omapi_message_object_t *m;
- omapi_value_t *signature;
+ omapi_value_t *signature = NULL;
u_int16_t nlen;
u_int32_t vlen;
u_int32_t th;
case omapi_protocol_signature_wait:
if (p -> message -> id_object) {
/* Compute the signature of the message. */
- signature = (omapi_value_t *)0;
status = omapi_get_value_str (c, (omapi_object_t *)0,
"input-signature",
&signature);
p -> message -> authlen);
if (status != ISC_R_SUCCESS) {
- omapi_value_dereference (&signature, MDL);
+ if (signature != NULL) {
+ omapi_value_dereference (&signature, MDL);
+ }
omapi_disconnect (c, 1);
return ISC_R_NOMEMORY;
}
p->verify_result = DHCP_R_INVALIDKEY;
}
- omapi_value_dereference (&signature, MDL);
+ if (signature != NULL) {
+ omapi_value_dereference (&signature, MDL);
+ }
/* Process the message. */
message_done:
p = (omapi_protocol_object_t *)h;
if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
- if (value -> type != omapi_datatype_object)
+ if (!value || value -> type != omapi_datatype_object)
return DHCP_R_INVALIDARG;
- if (!value || !value -> u.object) {
+ if (!value -> u.object) {
p -> default_auth = (omapi_remote_auth_t *)0;
} else {
for (r = p -> remote_auth_list; r; r = r -> next)
l -> verify_auth = verify_auth;
l -> insecure = 0;
- return omapi_listener_configure_security (h -> outer, verify_addr);
+ if (h -> outer != NULL) {
+ return omapi_listener_configure_security (h -> outer, verify_addr);
+ } else {
+ return DHCP_R_INVALIDARG;
+ }
}
Subroutines providing general support for objects. */
/*
- * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED)
return status;
}
+
+ /*
+ * For now ignore the return value. I'm not sure if we want to
+ * generate an error if we can't set the handle value. If we
+ * do add a check we probably should allow unchanged and notfound
+ */
if (handle)
- omapi_set_int_value (obj, id, "remote-handle", (int)handle);
+ (void) omapi_set_int_value (obj, id, "remote-handle", (int)handle);
status = omapi_signal (obj, "updated");
if (status != ISC_R_NOTFOUND)
return status;
transactions... */
/*
+ * Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
/* We have to swap out the data, because it may be read back on a
machine of different endianness. */
+ memset(&tmp, 0, sizeof(tmp));
tmp.type_index = htonl (ttype -> index);
tmp.when = htonl (time ((time_t *)0)); /* XXX */
tmp.length = htonl (length);
}
result = trace_get_next_packet (&ttype, tpkt, buf, len, &max);
+ /* done with tpkt, free it */
+ dfree (tpkt, MDL);
if (result != ISC_R_SUCCESS) {
- dfree (tpkt, MDL);
- if (*buf)
+ if (*buf) {
dfree (*buf, MDL);
+ *buf = NULL;
+ }
return result;
}
/* Make sure the filename is right. */
if (strcmp (filename, *buf)) {
log_error ("Read file %s when expecting %s", *buf, filename);
+ dfree (*buf, MDL);
+ *buf = NULL;
+
status = fsetpos (traceinfile, &curpos);
if (status < 0) {
log_error ("fsetpos in tracefile failed: %m");
- dfree (tpkt, MDL);
- dfree (*buf, MDL);
return DHCP_R_PROTOCOLERROR;
}
return ISC_R_UNEXPECTEDTOKEN;
}
- dfree (tpkt, MDL);
return ISC_R_SUCCESS;
}
#endif /* TRACING */
DHCP/BOOTP Relay Agent. */
/*
- * Copyright(c) 2004-2011 by Internet Systems Consortium, Inc.("ISC")
+ * Copyright(c) 2004-2012 by Internet Systems Consortium, Inc.("ISC")
* Copyright(c) 1997-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
local_family_set = 1;
local_family = AF_INET;
#endif
+ if (++i == argc) {
+ usage();
+ }
+ if (strlen(argv[i]) >= sizeof(tmp->name)) {
+ log_fatal("%s: interface name too long "
+ "(is %ld)",
+ argv[i], (long)strlen(argv[i]));
+ }
status = interface_allocate(&tmp, MDL);
- if (status != ISC_R_SUCCESS)
+ if (status != ISC_R_SUCCESS) {
log_fatal("%s: interface_allocate: %s",
argv[i],
isc_result_totext(status));
- if (++i == argc) {
- usage();
}
strcpy(tmp->name, argv[i]);
interface_snorf(tmp, INTERFACE_REQUESTED);
for (i = 0 ; i < out->address_count ; i++ ) {
if (out->addresses[i].s_addr ==
- packet->giaddr.s_addr)
+ packet->giaddr.s_addr) {
i = -1;
break;
+ }
}
if (i == -1)
Handling for client classes. */
/*
- * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1998-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
}
memset (nc -> billed_leases, 0,
(nc -> lease_limit *
- sizeof nc -> billed_leases));
+ sizeof (struct lease *)));
}
data_string_copy (&nc -> hash_string, &data,
MDL);
if (hba_len != 32) {
parse_warn (cfile,
"HBA must be exactly 32 bytes.");
- dfree (hba, MDL);
break;
}
make_hba:
log_fatal ("no memory for billing");
memset (class -> billed_leases, 0,
(class -> lease_limit *
- sizeof class -> billed_leases));
+ sizeof (struct lease *)));
}
data_string_copy (&class -> hash_string, &data, MDL);
if (!pc -> hash &&
log_fatal ("no memory for billed leases.");
memset (class -> billed_leases, 0,
(class -> lease_limit *
- sizeof class -> billed_leases));
+ sizeof (struct lease *)));
have_billing_classes = 1;
parse_semi (cfile);
} else {
if (status != ISC_R_SUCCESS)
log_fatal ("Can't allocate shared subnet: %s",
isc_result_totext (status));
- clone_group (&share -> group, group, MDL);
+ if (clone_group (&share -> group, group, MDL) == 0) {
+ log_fatal ("Can't clone group for shared net");
+ }
shared_network_reference (&share -> group -> shared_network,
share, MDL);
val, isc_result_totext(status));
group_reference(&t->group, g, MDL);
t->name = name;
+ /* no need to include deletedp as it's handled above */
t->flags = ((staticp ? GROUP_OBJECT_STATIC : 0) |
- (dynamicp ? GROUP_OBJECT_DYNAMIC : 0) |
- (deletedp ? GROUP_OBJECT_DELETED : 0));
+ (dynamicp ? GROUP_OBJECT_DYNAMIC : 0));
supersede_group(t, 0);
}
if (t != NULL)
errno = 0;
fprintf(db_file, "%sset %s = \"%s\";",
prepend, bnd->name, s);
+ dfree(s, MDL);
if (errno)
return ISC_R_FAILURE;
-
- dfree(s, MDL);
} else {
return ISC_R_FAILURE;
}
{
char ddns_address[MAX_ADDRESS_STRING_LEN];
sprintf(ddns_address, "unknown");
- if (ddns_cb) {
+ if (ddns_cb == NULL) {
+ log_info("%s(%d): No control block for lease update",
+ file, line);
+ return (ISC_R_FAILURE);
+ }
+ else {
strncpy(ddns_address, piaddr(ddns_cb->address),
MAX_ADDRESS_STRING_LEN);
}
ret_val = 0;
memset(server_id, 0, sizeof(*server_id));
+ memset(&client_id, 0, sizeof(client_id));
/*
* Make a string that we can print out to give more
if (status != ISC_R_SUCCESS) {
goto cleanup;
}
- if (reply->lease != NULL) {
- iasubopt_dereference(&reply->lease, MDL);
- }
+ /*
+ * reply->lease can't be null as we use it above
+ * add check if that changes
+ */
+ iasubopt_dereference(&reply->lease, MDL);
}
cleanup:
isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
failover_message_t *msg)
{
- struct lease *lt, *lease;
+ struct lease *lt = NULL, *lease = NULL;
struct iaddr ia;
int reason = FTR_MISC_REJECT;
const char *message;
ia.len = sizeof msg -> assigned_addr;
memcpy (ia.iabuf, &msg -> assigned_addr, ia.len);
- lease = (struct lease *)0;
- lt = (struct lease *)0;
if (!find_lease_by_ip_addr (&lease, ia, MDL)) {
message = "unknown IP address";
reason = FTR_ILLEGAL_IP_ADDR;
return (0);
}
memset ((*newclass)->billed_leases, 0,
- ((*newclass)->lease_limit * sizeof (*newclass)->billed_leases));
+ ((*newclass)->lease_limit * sizeof (struct lease *)));
}
data_string_copy (&(*newclass)->hash_string, data, MDL);
/* See if there's a statement that sets the client identifier.
This is a kludge - the client identifier really shouldn't be
set with an executable statement. */
- esp = (struct executable_statement *)0;
- if (executable_statement_foreach (hd -> group -> statements,
+ esp = NULL;
+ if (executable_statement_foreach (hd->group->statements,
find_uid_statement, &esp, 0)) {
- evaluate_option_cache (&hd -> client_identifier,
- (struct packet *)0,
- (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0, &global_scope,
- esp -> data.option, MDL);
+ (void) evaluate_option_cache (&hd->client_identifier,
+ NULL, NULL, NULL, NULL, NULL,
+ &global_scope,
+ esp->data.option, MDL);
}
/* If we got a client identifier, hash this entry by
void make_binding_state_transition (struct lease *lease)
{
+
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *peer;
- if (lease && lease -> pool && lease -> pool -> failover_peer)
+ if (lease -> pool && lease -> pool -> failover_peer)
peer = lease -> pool -> failover_peer;
else
peer = (dhcp_failover_state_t *)0;
case FTS_RELEASED:
case FTS_ABANDONED:
case FTS_RESET:
- lease -> next_binding_state = FTS_FREE;
+ lease->next_binding_state = FTS_FREE;
#if defined(FAILOVER_PROTOCOL)
/* If we are not in partner_down, leases don't go from
EXPIRED to FREE on a timeout - only on an update.
If we're in partner_down, they expire at mclt past
the time we entered partner_down. */
- if (lease -> pool -> failover_peer &&
- lease -> pool -> failover_peer -> me.state == partner_down)
- lease -> tsfp =
- (lease -> pool -> failover_peer -> me.stos +
- lease -> pool -> failover_peer -> mclt);
+ if ((lease->pool != NULL) &&
+ (lease->pool->failover_peer != NULL) &&
+ (lease->pool->failover_peer->me.state == partner_down))
+ lease->tsfp =
+ (lease->pool->failover_peer->me.stos +
+ lease->pool->failover_peer->mclt);
#endif /* FAILOVER_PROTOCOL */
break;
{
/* h should point to (struct pool *) */
isc_result_t status;
- int updatep = 0;
if (h -> type != dhcp_type_pool)
return DHCP_R_INVALIDARG;
if (status == ISC_R_SUCCESS)
return status;
}
- if (updatep)
- return ISC_R_SUCCESS;
+
return ISC_R_NOTFOUND;
}