#include <time.h>
#include <unistd.h>
+#include <isc/endian.h>
#include <isc/util.h>
#include <dns/librpz.h>
char *cstr;
bool uses_expired;
trpz_clist_t *pclist;
- ssize_t *base_zones;
- size_t nbase_zones;
} trpz_client_t;
typedef struct {
trpz_result_t *all_nodes;
size_t num_zones, num_nodes;
ssize_t last_zone;
+ ssize_t *base_zones;
+ size_t nbase_zones;
} trpz_rsp_t;
librpz_log_level_t g_log_level = LIBRPZ_LOG_TRACE2;
static void
clear_all_updates(trpz_rsp_t *trsp);
-static int
+static bool
domain_ntop(const u_char *src, char *dst, size_t dstsiz);
-static int
+static bool
domain_pton2(const char *src, u_char *dst, size_t dstsiz, size_t *dstlen,
bool lower);
void
trpz_set_log(librpz_log_fnc_t *new_log, const char *prog_nm);
void
-trpz_vlog(librpz_log_level_t level, void *ctx, const char *p, va_list args);
+trpz_vlog(librpz_log_level_t level, void *ctx, const char *p, va_list args)
+ LIBRPZ_PF(3, 0);
void
-trpz_log(librpz_log_level_t level, void *ctx, const char *p, ...);
+trpz_log(librpz_log_level_t level, void *ctx, const char *p, ...)
+ LIBRPZ_PF(3, 4);
librpz_log_level_t
trpz_log_level_val(librpz_log_level_t level);
void
-trpz_vpemsg(librpz_emsg_t *emsg, const char *p, va_list args);
+trpz_vpemsg(librpz_emsg_t *emsg, const char *p, va_list args) LIBRPZ_PF(2, 0);
void
-trpz_pemsg(librpz_emsg_t *emsg, const char *fmt, ...);
+trpz_pemsg(librpz_emsg_t *emsg, const char *fmt, ...) LIBRPZ_PF(2, 3);
librpz_clist_t *
trpz_clist_create(librpz_emsg_t *emsg, librpz_mutex_t *lock,
librpz_mutex_t *unlock, librpz_mutex_t *mutex_destroy,
* zones.
*/
static bool
-has_base_zone(trpz_client_t *cli, ssize_t zone) {
+has_base_zone(trpz_rsp_t *trsp, ssize_t zone) {
size_t n;
- if (cli == NULL || cli->base_zones == NULL || cli->nbase_zones == 0) {
+ if (trsp == NULL || trsp->base_zones == NULL || trsp->nbase_zones == 0)
+ {
return (false);
}
- for (n = 0; n < cli->nbase_zones; n++) {
- if (cli->base_zones[n] == BASE_ZONE_ANY ||
- cli->base_zones[n] == zone)
+ for (n = 0; n < trsp->nbase_zones; n++) {
+ if (trsp->base_zones[n] == BASE_ZONE_ANY ||
+ trsp->base_zones[n] == zone)
{
return (true);
}
static bool
pack_soa_record(unsigned char *rdatap, size_t rbufsz, size_t *rdlenp,
const rpz_soa_t *psoa) {
- uint32_t *uptr = NULL;
size_t needed = (sizeof(uint32_t) * 5) + strlen(psoa->mname) + 2 +
strlen(psoa->rname) + 2;
size_t mlen = 0, rlen = 0, used = 0;
used = rlen + mlen;
- uptr = (uint32_t *)(rdatap + rlen + mlen);
- *uptr++ = htonl(psoa->serial);
- *uptr++ = htonl(psoa->refresh);
- *uptr++ = htonl(psoa->retry);
- *uptr++ = htonl(psoa->expire);
- *uptr++ = htonl(psoa->minimum);
-
- used += (sizeof(uint32_t) * 5);
-
- if (rdlenp) {
+ rdatap += rlen + mlen;
+ ISC_U32TO8_BE(rdatap, psoa->serial);
+ rdatap += 4;
+ ISC_U32TO8_BE(rdatap, psoa->refresh);
+ rdatap += 4;
+ ISC_U32TO8_BE(rdatap, psoa->retry);
+ rdatap += 4;
+ ISC_U32TO8_BE(rdatap, psoa->expire);
+ rdatap += 4;
+ ISC_U32TO8_BE(rdatap, psoa->minimum);
+ rdatap += 4;
+ used += (4 * 5);
+
+ if (rdlenp != NULL) {
*rdlenp = used;
}
return (true);
}
+static void
+do_log(librpz_log_level_t level, void *ctx, const char *fmt, va_list args)
+ LIBRPZ_PF(3, 0);
static void
do_log(librpz_log_level_t level, void *ctx, const char *fmt, va_list args) {
if (level > g_log_level) {
static void
scan_data_file_for_errors(void *lctx) {
char *updfile = NULL, *fname = NULL, *last = NULL;
+ char *tmp = NULL;
updfile = getenv("DNSRPS_TEST_UPDATE_FILE");
if (updfile == NULL) {
return;
}
- fname = strtok_r(updfile, ":", &last);
+ tmp = strdup(updfile);
+ if (tmp == NULL) {
+ return;
+ }
+
+ fname = strtok_r(tmp, ":", &last);
while (fname) {
char *errp = NULL;
ret = sanity_check_data_file(fname, &errp);
if ((ret < 0) && errp) {
- trpz_log(LIBRPZ_LOG_ERROR, lctx, errp);
+ trpz_log(LIBRPZ_LOG_ERROR, lctx, "%s", errp);
free(errp);
}
fname = strtok_r(NULL, ":", &last);
}
+ free(tmp);
return;
}
void
trpz_client_detach(librpz_client_t **clientp) {
if (clientp != NULL && *clientp != NULL) {
- librpz_client_t *client = *clientp;
- *clientp = NULL;
+ trpz_client_t *client = (trpz_client_t *)(*clientp);
+ if (client->cstr != NULL) {
+ free(client->cstr);
+ }
free(client);
}
static int
apply_all_updates(trpz_rsp_t *trsp) {
char *updfile = NULL, *fname = NULL, *last = NULL;
+ char *tmp = NULL;
updfile = getenv("DNSRPS_TEST_UPDATE_FILE");
if (updfile == NULL) {
return (0);
}
+ tmp = strdup(updfile);
+ if (tmp == NULL) {
+ return (-1);
+ }
+
fname = strtok_r(updfile, ":", &last);
while (fname != NULL) {
char *errp = NULL;
&trsp->num_nodes, &trsp->all_zones,
&trsp->num_zones, &errp);
- if (errp) {
+ if (errp != NULL) {
fprintf(stderr, "Error loading updates: %s\n", errp);
free(errp);
}
if (ret < 0) {
+ free(tmp);
return (-1);
}
fname = strtok_r(NULL, ":", &last);
}
+ free(tmp);
return (0);
}
size_t n;
for (n = 0; n < trsp->num_nodes; n++) {
+ if (trsp->all_nodes[n].canonical != NULL) {
+ free(trsp->all_nodes[n].canonical);
+ }
+ if (trsp->all_nodes[n].dname != NULL) {
+ free(trsp->all_nodes[n].dname);
+ }
if (trsp->all_nodes[n].rrs) {
size_t m;
result->stack_idx = 1;
result->last_zone = -1;
- *rspp = (librpz_rsp_t *)result;
+ assert(*rspp == NULL);
clear_all_updates(result);
- cli->base_zones = get_cstr_zones(cli->cstr, result,
- &(cli->nbase_zones));
+ result->base_zones = get_cstr_zones(cli->cstr, result,
+ &(result->nbase_zones));
- if (cli->base_zones == NULL) {
+ if (result->base_zones == NULL) {
trpz_pemsg(emsg, "no valid policy zone specified");
- free(*rspp);
- *rspp = NULL;
+ clear_all_updates(result);
+ free(result);
return (false);
}
if (apply_all_updates(result) < 0) {
trpz_pemsg(emsg, "internal error loading test data 1");
+ clear_all_updates(result);
+ free(result->base_zones);
+ free(result);
return (false);
}
+ *rspp = (librpz_rsp_t *)result;
+
return (true);
}
void
trpz_rsp_detach(librpz_rsp_t **rspp) {
- if (rspp && *rspp) {
+ if (rspp != NULL && *rspp != NULL) {
trpz_rsp_t *trsp = (trpz_rsp_t *)*rspp;
-
- clear_all_updates(trsp);
-
- free(*rspp);
*rspp = NULL;
+ clear_all_updates(trsp);
+ if (trsp->base_zones != NULL) {
+ free(trsp->base_zones);
+ }
+ free(trsp);
}
return;
rres->rdlength = htons(rdlen);
- if (rrp) {
- *rrp = rres;
- }
-
- if (origin) {
+ if (origin != NULL) {
uint8_t *buf = NULL;
int nbytes;
free(buf);
}
+ if (rrp != NULL) {
+ *rrp = rres;
+ } else {
+ free(rdbuf);
+ }
+
return (true);
}
trsp->all_zones[trsp->all_nodes[n].result.dznum]
.not_recursive_only ||
recursed) &&
- has_base_zone(trsp->client,
+ has_base_zone(trsp,
trsp->all_nodes[n].result.dznum) &&
!trsp->all_zones[trsp->all_nodes[n].result.dznum]
.forgotten)
{
if (recursed &&
has_base_zone(
- trsp->client,
+ trsp,
trsp->all_nodes[n].result.dznum) &&
!trsp->all_zones[trsp->all_nodes[n]
.result.dznum]
unsigned int nmask = 32;
if (family == AF_INET6) {
- if (!inet_ntop(AF_INET6, addr, abuf, sizeof(abuf))) {
+ if (inet_ntop(AF_INET6, addr, abuf, sizeof(abuf)) == 0) {
return (-1);
}
return (-1);
}
} else if (sscanf(addrstr, "%d.%d.%d.%d", &ipstr[1], &ipstr[2],
- &ipstr[3], &ipstr[4]) != 4)
+ &ipstr[3], &ipstr[4]) != 4)
{
perror("bad address format");
return (-1);
}
if (ipstr[1] > 255 || ipstr[2] > 255 || ipstr[3] > 255 ||
- ipstr[4] > 255) {
+ ipstr[4] > 255 || ipstr[1] < 0 || ipstr[2] < 0 ||
+ ipstr[3] < 0 || ipstr[4] < 0)
+ {
perror("bad address format");
return (-1);
}
memmove(&a2, addr, sizeof(uint32_t));
m = get_mask(nmask);
- if (pmask) {
+ if (pmask != NULL) {
*pmask = nmask;
}
}
if (strcmp(addrstr, abuf) == 0) {
- if (pmask) {
+ if (pmask != NULL) {
*pmask = nmask;
}
trsp->all_zones[trsp->all_nodes[n].result.dznum]
.not_recursive_only ||
recursed) &&
- has_base_zone(trsp->client,
+ has_base_zone(trsp,
trsp->all_nodes[n].result.dznum) &&
!trsp->all_zones[trsp->all_nodes[n].result.dznum]
.forgotten)
} else if ((nfidx < 0) && !recursed &&
has_base_zone(
- trsp->client,
+ trsp,
trsp->all_nodes[n].result.dznum) &&
!trsp->all_zones[trsp->all_nodes[n]
.result.dznum]
dlen = strlen(domain_nm);
- if (dlen > 0 && domain_nm[dlen - 1] == '.') {
+ if (dlen > 0U && domain_nm[dlen - 1] == '.') {
dlen--;
}
for (n = 0; n < trsp->num_zones; n++) {
if (dlen != strlen(trsp->all_zones[n].name)) {
continue;
- } else if (!has_base_zone(trsp->client, n)) {
+ } else if (!has_base_zone(trsp, n)) {
continue;
}
return (false);
}
-static int
+static bool
domain_ntop(const u_char *src, char *dst, size_t dstsiz) {
const unsigned char *sptr = src;
char *dptr = dst, *dend = dst + dstsiz;
if (dst == NULL || dstsiz == 0) {
- return (0);
+ return (false);
}
memset(dst, 0, dstsiz);
while (*sptr) {
if (((dptr + *sptr) > dend)) {
- return (0);
+ return (false);
}
if (sptr != src) {
sptr++;
}
- return (1);
+ return (true);
}
-static int
+static bool
domain_pton2(const char *src, u_char *dst, size_t dstsiz, size_t *dstlen,
bool lower) {
unsigned char *dptr = dst;
tmps = strdup(src);
if (tmps == NULL) {
perror("strdup");
- return (0);
+ return (false);
}
tptr = tmps;
- if (dstlen) {
+ if (dstlen != NULL) {
*dstlen = 0;
}
tok = strsep(&tptr, ".");
if (((dptr + strlen(tok) + 1) > dend)) {
- return (0);
+ free(tmps);
+ return (false);
}
*dptr++ = strlen(tok);
memmove(dptr, tok, strlen(tok));
dptr += strlen(tok);
- if (dstlen) {
+ if (dstlen != NULL) {
(*dstlen) += (1 + strlen(tok));
}
}
if (dptr >= dend) {
- return (0);
+ free(tmps);
+ return (false);
}
*dptr = 0;
- if (dstlen) {
+ if (dstlen != NULL) {
(*dstlen)++;
}
free(tmps);
- return (1);
+ return (true);
}
/* XXX: needs IPv6 support. */
}
if (strncmp(tmpexp, "*.", 2) == 0) {
- size_t nrd;
+ int nrd;
uint32_t n = snprintf(
tmpexp3,
sizeof(tmpexp3),
}
nrd = wdns_str_to_name(
tmpexp3, &nrdata, 1);
+ if (nrd < 0) {
+ trpz_pemsg(
+ emsg,
+ "Error packing "
+ "domain");
+ return (false);
+ }
to_copy = nrd;
copy_src = nrdata;
}
*rrp = calloc(1, needed);
if (*rrp == NULL) {
trpz_pemsg(emsg, "calloc: %s", strerror(errno));
+ if (nrdata != NULL) {
+ free(nrdata);
+ }
return (false);
}
(*rrp)->ttl = htonl(this_rr->ttl);
(*rrp)->rdlength = htons(to_copy);
memmove((*rrp)->rdata, copy_src, to_copy);
+ if (nrdata != NULL) {
+ free(nrdata);
+ }
}
result->next_rr = this_rr->rrn;
unsigned int prefix = 0, values[16] = { 0 }, hex_values[16] = { 0 };
bool is_ipv6 = false;
- if (!astr || !pfamily || !pbuf) {
+ if (astr == NULL || pfamily == NULL || pbuf == NULL) {
return (-1);
}
*/
if (*pfamily == AF_INET) {
if (prefix > 32) {
- if (errp) {
+ if (errp != NULL) {
*errp = str_printf(
"invalid rpz IP address \"%s\"; "
"invalid prefix length of %u",
size_t n;
if (prefix > 128) {
- if (errp) {
+ if (errp != NULL) {
*errp = str_printf(
"invalid rpz IP address \"%s\"; "
"invalid prefix length of %u",
size_t bytes_remaining = src_len;
uint8_t oclen;
- if (!src) {
+ if (src == NULL) {
return (0);
}
rptr->ttl == nrec.ttl && rptr->rdlength == nrec.rdlength &&
!memcmp(rptr->rdata, nrec.rdata, nrec.rdlength))
{
+ free(nrec.rdata);
return (n + 1);
}
}
reverse_labels(const char *str, char *pbuf) {
const char *sptr = str, *end = NULL;
- if (!sptr || !*sptr) {
+ if (sptr == NULL || *sptr == 0) {
return;
}
char *tok = NULL, *sptr = NULL;
unsigned long result = 0;
- if (!str || !*str) {
+ if (str == NULL || *str == 0) {
return (0);
}
free_nodes(trpz_result_t **presults, size_t *pnresults) {
size_t n, tot;
- if ((!presults || !*presults) && pnresults) {
- *pnresults = 0;
- }
-
- if (!presults || !*presults) {
+ if (presults == NULL || *presults == NULL) {
+ if (pnresults != NULL) {
+ *pnresults = 0;
+ }
return;
}
trpz_result_t *res = &((*presults)[n - 1]);
size_t m;
- if (res->canonical) {
+ if (res->canonical != NULL) {
free(res->canonical);
}
- if (res->dname) {
+ if (res->dname != NULL) {
free(res->dname);
}
for (m = 0; m < res->nrrs; m++) {
- if (res->rrs[m].rdata) {
+ if (res->rrs[m].rdata != NULL) {
free(res->rrs[m].rdata);
}
}
- if (res->rrs) {
+ if (res->rrs != NULL) {
free(res->rrs);
}
}
FILE *f = NULL;
int result = -1;
- if (errp) {
+ if (errp != NULL) {
*errp = NULL;
}
} else if (strcasecmp(line, "static") &&
strcasecmp(line, "update"))
{
- if (errp) {
+ if (errp != NULL) {
*errp = str_printf("Found unknown instruction "
"directive: \"%s\"\n",
line);
strcasecmp(rrbuf, "TXT") && strcasecmp(rrbuf, "DNAME") &&
strcasecmp(rrbuf, "AAAA"))
{
- if (errp) {
+ if (errp != NULL) {
*errp = str_printf("Target \"%s\" is not "
"currently supported!\n",
rrbuf);
if (slen == 1 && *p == '.') {
*pbuf = malloc(1);
+ if (*pbuf == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
*pbuf[0] = 0;
return (1);
}
res = 0;
*pbuf = malloc(WDNS_MAXLEN_NAME);
+ if (*pbuf == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
data = *pbuf;
label_len = 0;
c = *p++;
label_len++;
+ /* Will the wire name become too long? */
+ if (res >= WDNS_MAXLEN_NAME) {
+ goto out;
+ }
+
if (slen == 0) {
/* end of input */
- if (res == WDNS_MAXLEN_NAME) {
- res = -1;
- goto out;
- }
*oclen = --label_len;
*data++ = '\0';
res++;
break;
}
- if (res >= WDNS_MAXLEN_NAME) {
- res = -1;
- }
-
if (c >= 'A' && c <= 'Z') {
/* an upper case letter; downcase it */
if (downcase) {
} else if (c == '\\' && !isdigit(*p)) {
/* an escaped character */
if (slen <= 0) {
- res = -1;
goto out;
}
*data++ = *p;
out:
free(*pbuf);
+ *pbuf = NULL;
return (-1);
}