Skip to content

Commit

Permalink
public key pinning implementation and a parsing bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
kamarya committed May 16, 2022
1 parent de9ada4 commit baddc4a
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 28 deletions.
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
all:
$(CC) src/dnssec.c -Iinc -g -Wall -lcurl -std=gnu99 -o dnsd
$(CC) src/dnssec.c -Iinc -Wall -lcurl -std=gnu11 -o dnsd
install:
cp dnsd.conf /etc/dnsd.conf
mkdir -p /etc/dnsd
cp dnsd.conf /etc/dnsd/dnsd.conf
cp google.der /etc/dnsd/google.der
cp dnsd /usr/local/bin/
linux-service:
cp service/dnsd.service /lib/systemd/system/
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ DNSd is a daemon a.k.a. service for Unix-like systems. It provides a local DNS b
- Highly configurable through a simple config. file.
- A Self contained package that depends only on [libcurl](https://curl.haxx.se/libcurl/).
- Supported records are **A**,**AAAA**,**CNAME**,**NS** and **MX**.
- Public key pinning

# Build and Install
Build the software by running the following commands in the terminal.
Expand All @@ -38,8 +39,13 @@ For macOS systems install and launch the service as follows.
make macos-service
launchctl load -w /Library/LaunchDaemons/service.dnsd.plist
```
### Obtain Public Key
`openssl s_client -connect google.com:443 | openssl x509 -pubkey -noout`

### Verification
You can verify wether the service is accessible through ```host -va github.com localhost```.
You can verify wether the service is accessible through
- `host -va github.com localhost`
- `nslookup -port=5454 -query=mx github.com 127.0.0.1`
```
Trying "github.com"
Using domain server:
Expand Down
Binary file added google.der
Binary file not shown.
2 changes: 2 additions & 0 deletions inc/dnssec.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#define OPT_DEFAULT_URL "https://dns.google.com"
#define OPT_SERVICE_PORT "service_port"
#define OPT_SERVICE_IP "service_ip"
#define OPT_SERVICE_PUB_KEY "service_pub_key"
#define OPT_SERVICE_IP_LEN INET6_ADDRSTRLEN
#define OPT_ENABLE_TRUE "true"
#define OPT_ENABLE_FALSE "false"
Expand All @@ -94,6 +95,7 @@ struct func_options
char server_url[OPT_SERVER_URL_LEN];
char server_ip_list[OPT_SERVER_IP_LEN];
char service_ip[OPT_SERVICE_IP_LEN];
char service_pub_key[OPT_CONIG_FILE_LEN];
uint16_t server_timeout;
uint16_t service_port;
uint8_t enable_debug;
Expand Down
2 changes: 1 addition & 1 deletion service/dnsd.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=network.target
[Service]
Type=forking
PIDFile=/var/run/dnsd.pid
ExecStart=/usr/local/bin/dnsd -f /etc/dnsd.conf
ExecStart=/usr/local/bin/dnsd -f /etc/dnsd/dnsd.conf
KillMode=process
Restart=on-failure

Expand Down
2 changes: 1 addition & 1 deletion service/service.dnsd.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<array>
<string>/usr/local/bin/dnsd</string>
<string>-f</string>
<string>/etc/dnsd.conf</string>
<string>/etc/dnsd/dnsd.conf</string>
</array>
<key>RunAtLoad</key>
<true/>
Expand Down
49 changes: 26 additions & 23 deletions src/dnssec.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ static void __attribute__ ((unused)) start_daemon()
fprintf(stderr, "open(stderr)");
exit(EXIT_FAILURE);
}

}

#if DEBUG_AUDIT_ENABLE
Expand Down Expand Up @@ -182,11 +181,6 @@ int https_query (struct dns_query* query)

struct curl_slist* headers = NULL;

headers = curl_slist_append(headers, "Accept-Encoding : deflate, sdch, br");
headers = curl_slist_append(headers, "Accept : txt/html, application/xml;q=0.8");
headers = curl_slist_append(headers, "Accept-Language : en-US,en;q=0.8");
headers = curl_slist_append(headers, "Cache-Control : max-age=0");

curl = curl_easy_init();
if(curl && strlen(getTypeString(ntohs(query->qstn->qtype), FALSE)))
{
Expand All @@ -197,6 +191,7 @@ int https_query (struct dns_query* query)
// do not check the SSL certificate authenticity
//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

// failed to work with libcurl/7.65.3 and HTTP/2.0
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
Expand All @@ -208,6 +203,15 @@ int https_query (struct dns_query* query)
curl_easy_setopt(curl, CURLOPT_PROXY, options.https_proxy);
}

if (options.service_pub_key[0])
{
if (curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, options.service_pub_key) != CURLE_OK)
{
LOG_ERROR("failed to load the pinned public key");
return EXIT_FAILURE;
}
}

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, body_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)query);

Expand Down Expand Up @@ -376,6 +380,7 @@ int server()
char* answer = (char *)(buffer + sizeof(struct dns_question) + sizeof(struct dns_header) + dnlen + 1);
answer_length = json_to_answer(answer, header, max_len);
}
else LOG_ERROR("https_query() failed.");
}

if (!answer_length || answer_length == JSON_NO_ANSWER)
Expand Down Expand Up @@ -525,7 +530,7 @@ size_t json_to_answer(char* answer, struct dns_header_detail* header, size_t max
{

token = strstr(token, "type");
char* beg = strchr(token, ':') + 2;
char* beg = strchr(token, ':') + 1;
size_t len = strchr(beg, ',') - beg;

memset(ctype, 0x00, 10);
Expand Down Expand Up @@ -742,50 +747,44 @@ void hexdump (char *desc, void *addr, int len)
unsigned char buff[17];
unsigned char *pc = (unsigned char*)addr;

// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);

if (len == 0) {
if (len == 0)
{
printf(" ZERO LENGTH\n");
return;
}
if (len < 0) {
if (len < 0)
{
printf(" NEGATIVE LENGTH: %i\n",len);
return;
}

// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).

if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line.
for (i = 0; i < len; i++)
{
if ((i % 16) == 0)
{
if (i != 0)
printf (" %s\n", buff);

// Output the offset.
printf (" %04x ", i);
}

// Now the hex code for the specific character.
printf (" %02x", pc[i]);

// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0';
}

// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
while ((i % 16) != 0)
{
printf (" ");
i++;
}

// And print the final ASCII bit.
printf (" %s\n", buff);
}

Expand Down Expand Up @@ -870,6 +869,10 @@ int parse_options()
{
strncpy(options.service_ip, line + sizeof(OPT_SERVICE_IP), OPT_SERVICE_IP_LEN);
}
else if (strstr(line, OPT_SERVICE_PUB_KEY) != NULL)
{
strncpy(options.service_pub_key, line + sizeof(OPT_SERVICE_PUB_KEY), OPT_CONIG_FILE_LEN);
}
else if (strstr(line, OPT_ENABLE_EDNS) != NULL)
{
if (strcasestr(line, OPT_ENABLE_TRUE) != NULL) options.enable_edns = 1;
Expand Down

0 comments on commit baddc4a

Please sign in to comment.