summaryrefslogtreecommitdiff
path: root/c_src
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2016-03-27 19:27:30 +0200
committerLinus Nordberg <linus@nordu.net>2016-03-27 19:44:25 +0200
commit56d70baa79ae5907b11445364bbea9b31ee4cd20 (patch)
treeef0403255a04de75736da82385d282a0198c52c2 /c_src
parent9f723f6f1d79c1be460ece10555945346045b175 (diff)
WIP
Diffstat (limited to 'c_src')
-rw-r--r--c_src/Makefile17
-rw-r--r--c_src/dnssec.c138
-rw-r--r--c_src/erlport.c119
-rw-r--r--c_src/erlport.h18
-rw-r--r--c_src/net_read_write.c93
-rw-r--r--c_src/net_read_write.h10
6 files changed, 395 insertions, 0 deletions
diff --git a/c_src/Makefile b/c_src/Makefile
new file mode 100644
index 0000000..ae9c73e
--- /dev/null
+++ b/c_src/Makefile
@@ -0,0 +1,17 @@
+CC = gcc
+#CFLAGS = -Wall -Werror -std=gnu99
+CFLAGS = -Wall -Werror -std=gnu99 -DTEST
+LDFLAGS =
+
+PORTS = dnssecport
+
+common_OBJS = erlport.o net_read_write.o
+dnssecport_OBJS = dnssec.o dnssec_test.o $(common_OBJS)
+
+all: $(PORTS)
+
+clean:
+ rm -f $(common_OBJS) $(dnssecport_OBJS) $(PORTS)
+
+dnssecport: $(dnssecport_OBJS)
+ $(CC) -o $@ $^ $(LDFLAGS) -ldl -lgetdns
diff --git a/c_src/dnssec.c b/c_src/dnssec.c
new file mode 100644
index 0000000..693d645
--- /dev/null
+++ b/c_src/dnssec.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, NORDUnet A/S.
+ * See LICENSE for licensing information.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <getopt.h>
+#include <getdns/getdns.h>
+#include "erlport.h"
+#include "dnssec_test.h"
+
+static char *testmode = NULL;
+
+/* getdns/src/convert.c */
+getdns_return_t getdns_wire2rr_dict(const uint8_t *wire, size_t wire_len,
+ getdns_dict **rr_dict);
+
+#if !defined(TEST)
+static getdns_return_t
+validate(const unsigned char *records,
+ size_t records_len,
+ getdns_list *trust_anchors)
+{
+ getdns_return_t r = GETDNS_DNSSEC_INDETERMINATE;
+ getdns_list *to_validate = getdns_list_create();
+ getdns_list *support_records = getdns_list_create();
+ getdns_dict *records_dict = NULL;
+
+ if (to_validate == NULL || support_records == NULL)
+ {
+ r = GETDNS_RETURN_MEMORY_ERROR;
+ goto out;
+ }
+
+ /* TODO: figure out if we get _all_ RRs in records here bc i have
+ the feeling that we're not supposed to mix RR types in the same
+ dict; maybe this will help some:
+ https://getdnsapi.net/pipermail/users/2015-May/000032.html
+ */
+ r = getdns_wire2rr_dict(records, records_len, &records_dict);
+ if (r)
+ goto out;
+
+ /*
+ to_validate: one dict with the DS and one with a RRSIG for that DS
+ support_records: DS and DNSKEY dicts with accompanying RRSIG's
+ trust_anchors: DNSKEY (or DS)
+ */
+ r = getdns_list_set_dict(to_validate, i, records_dict);
+ if (r)
+ goto out;
+
+ r = getdns_validate_dnssec(to_validate,
+ support_records,
+ trust_anchors);
+
+out:
+ if (to_validate)
+ getdns_list_destroy(to_validate);
+ if (support_records)
+ getdns_list_destroy(support_records);
+
+ return r;
+}
+#endif /* !TEST */
+
+static void
+loop(getdns_list *trust_anchors)
+{
+ getdns_return_t r = GETDNS_RETURN_GENERIC_ERROR;
+ unsigned char buf[65536];
+ ssize_t len;
+
+ while ((len = read_command(buf, sizeof(buf), 4)) > 0)
+ {
+ unsigned char *reply = NULL;
+
+#if !defined(TEST)
+ r = validate(buf, len, trust_anchors);
+#else
+ r = test_validate(buf, len, trust_anchors, testmode);
+#endif
+
+ switch (r)
+ {
+ case GETDNS_RETURN_GOOD:
+ reply = (unsigned char *) "valid";
+ break;
+ default:
+ fprintf(stderr, "error %d\n", r); /* DEBUG */
+ reply = (unsigned char *) "err";
+ }
+
+ write_reply(reply, strlen((const char *) reply), 4);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ getdns_list *trust_anchors = NULL;
+ time_t trust_anchor_date;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"testmode", required_argument, NULL, 't'},
+ {0, 0, 0, 0}};
+
+ c = getopt_long(argc, argv, "", long_options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+#if defined(TEST)
+ case 't':
+ testmode = optarg;
+ break;
+#endif
+ default:
+ fprintf(stderr, "dnssecport: bad option: %s", argv[optind]);
+ return -1;
+ }
+ }
+
+ if (optind < argc) /* Using getdns trust anchor. */
+ {
+ trust_anchors = getdns_root_trust_anchor(&trust_anchor_date);
+ }
+
+ loop(trust_anchors);
+
+ return 0;
+}
diff --git a/c_src/erlport.c b/c_src/erlport.c
new file mode 100644
index 0000000..372f98d
--- /dev/null
+++ b/c_src/erlport.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014-2015, NORDUnet A/S.
+ * See LICENSE for licensing information.
+ */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "net_read_write.h"
+#include "erlport.h"
+
+static ssize_t
+read_length(size_t length_size)
+{
+ unsigned char buf[4];
+
+ if (length_size != 2 && length_size != 4) {
+ return -1;
+ }
+
+ if (length_size > sizeof(buf)) {
+ return -1;
+ }
+
+ ssize_t ret;
+
+ ret = net_read(0, (char *)buf, length_size);
+
+ if (ret != (ssize_t) length_size) {
+ return -1;
+ }
+
+ if (length_size == 2) {
+ return (ssize_t)(((unsigned long)buf[0] << 8) | (unsigned long)buf[1]);
+ } else {
+ return (ssize_t)(((unsigned long)buf[0] << 24) |
+ ((unsigned long)buf[1] << 16) |
+ ((unsigned long)buf[2] << 8) |
+ (unsigned long)buf[3]);
+ }
+}
+
+ssize_t
+read_command(unsigned char *buf, size_t maxlen, size_t length_size)
+{
+ ssize_t len;
+
+ len = read_length(length_size);
+
+ if (len < 0) {
+ return -1;
+ }
+
+ if (len > (ssize_t) maxlen) {
+ return -1;
+ }
+ return net_read(0, (char *)buf, (size_t)len);
+}
+
+static int
+write_length(size_t len, size_t length_size)
+{
+ unsigned char buf[4];
+
+ if (length_size != 2 && length_size != 4) {
+ return -1;
+ }
+
+ if (length_size == 2) {
+ buf[0] = (len >> 8) & 0xff;
+ buf[1] = len & 0xff;
+ } else {
+ buf[0] = (len >> 24) & 0xff;
+ buf[1] = (len >> 16) & 0xff;
+ buf[2] = (len >> 8) & 0xff;
+ buf[3] = len & 0xff;
+ }
+
+ ssize_t ret;
+
+ ret = net_write(1, (char *)buf, length_size);
+
+ if (ret < 0) {
+ return -1;
+ }
+
+ if (ret != (ssize_t) length_size) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+write_reply(unsigned char *msg, size_t len, size_t length_size)
+{
+ ssize_t ret;
+
+ ret = write_length(len, length_size);
+ if (ret < 0) {
+ return -1;
+ }
+ ret = net_write(1, (char *)msg, len);
+ if (ret < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+write_status(char *msg)
+{
+ return write_reply((unsigned char *)msg, strlen(msg), 2);
+}
diff --git a/c_src/erlport.h b/c_src/erlport.h
new file mode 100644
index 0000000..58b2591
--- /dev/null
+++ b/c_src/erlport.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2014-2015, NORDUnet A/S.
+ * See LICENSE for licensing information.
+ */
+
+#ifndef ERLPORT_H
+#define ERLPORT_H
+
+ssize_t
+read_command(unsigned char *buf, size_t maxlen, size_t length_size);
+
+int
+write_reply(unsigned char *msg, size_t len, size_t length_size);
+
+int
+write_status(char *msg);
+
+#endif
diff --git a/c_src/net_read_write.c b/c_src/net_read_write.c
new file mode 100644
index 0000000..f8f14f0
--- /dev/null
+++ b/c_src/net_read_write.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "net_read_write.h"
+
+/*
+ * Like read but never return partial data.
+ */
+
+ssize_t
+net_read (int fd, void *buf, size_t nbytes)
+{
+ char *cbuf = (char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+ count = read (fd, cbuf, rem);
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ } else if (count == 0) {
+ return count;
+ }
+ cbuf += (size_t) count;
+ rem -= (size_t) count;
+ }
+ return (ssize_t)nbytes;
+}
+
+/*
+ * Like write but never return partial data.
+ */
+
+ssize_t
+net_write (int fd, const void *buf, size_t nbytes)
+{
+ const char *cbuf = (const char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+ count = write (fd, cbuf, rem);
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ }
+ cbuf += (size_t)count;
+ rem -= (size_t)count;
+ }
+ return (ssize_t)nbytes;
+}
diff --git a/c_src/net_read_write.h b/c_src/net_read_write.h
new file mode 100644
index 0000000..80b92b3
--- /dev/null
+++ b/c_src/net_read_write.h
@@ -0,0 +1,10 @@
+#ifndef NET_READ_WRITE_H
+#define NET_READ_WRITE_H
+
+ssize_t
+net_read (int, void *, size_t);
+
+ssize_t
+net_write (int, const void *, size_t);
+
+#endif