aboutsummaryrefslogtreecommitdiffstats
path: root/src/pluto/dnskey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/dnskey.c')
-rw-r--r--src/pluto/dnskey.c107
1 files changed, 75 insertions, 32 deletions
diff --git a/src/pluto/dnskey.c b/src/pluto/dnskey.c
index bd190530c..ed901ade5 100644
--- a/src/pluto/dnskey.c
+++ b/src/pluto/dnskey.c
@@ -29,6 +29,9 @@
#include <freeswan.h>
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
+
#include "constants.h"
#include "adns.h" /* needs <resolv.h> */
#include "defs.h"
@@ -83,7 +86,9 @@ init_adns(void)
{
strcpy(adns_path_space, helper_bin_dir);
if (n > 0 && adns_path_space[n -1] != '/')
+ {
adns_path_space[n++] = '/';
+ }
}
}
else
@@ -95,25 +100,33 @@ init_adns(void)
n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
if (n < 0)
+ {
exit_log_errno((e
, "readlink(\"/proc/self/exe\") failed in init_adns()"));
-
+ }
}
if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
+ {
exit_log("path to %s is too long", adns_name);
+ }
while (n > 0 && adns_path_space[n - 1] != '/')
+ {
n--;
-
+ }
strcpy(adns_path_space + n, adns_name);
adns_path = adns_path_space;
}
if (access(adns_path, X_OK) < 0)
+ {
exit_log_errno((e, "%s missing or not executable", adns_path));
+ }
if (pipe(qfds) != 0 || pipe(afds) != 0)
+ {
exit_log_errno((e, "pipe(2) failed in init_adns()"));
+ }
adns_pid = fork();
switch (adns_pid)
@@ -128,7 +141,9 @@ init_adns(void)
* Take care to handle case where pipes already use these fds.
*/
if (afds[1] == 0)
+ {
afds[1] = dup(afds[1]); /* avoid being overwritten */
+ }
if (qfds[0] != 0)
{
dup2(qfds[0], 0);
@@ -140,16 +155,18 @@ init_adns(void)
close(qfds[1]);
}
if (afds[0] > 1)
+ {
close(afds[0]);
+ }
if (afds[1] > 1)
+ {
close(afds[1]);
-
+ }
DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
execlp(adns_path, adns_name, NULL);
exit_log_errno((e, "execlp of %s failed", adns_path));
}
-
default:
/* parent */
close(qfds[0]);
@@ -183,8 +200,10 @@ stop_adns(void)
else if (WIFEXITED(status))
{
if (WEXITSTATUS(status) != 0)
+ {
plog("ADNS process exited with status %d"
, (int) WEXITSTATUS(status));
+ }
}
else if (WIFSIGNALED(status))
{
@@ -227,8 +246,9 @@ decode_iii(u_char **pp, struct id *gw_id)
u_char under = *e;
if (p == e)
+ {
return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
-
+ }
*e = '\0';
if (*p == '@')
{
@@ -236,8 +256,10 @@ decode_iii(u_char **pp, struct id *gw_id)
err_t ugh = atoid(p, gw_id, FALSE);
if (ugh != NULL)
+ {
return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
, ugh);
+ }
}
else
{
@@ -248,12 +270,14 @@ decode_iii(u_char **pp, struct id *gw_id)
, &ip);
if (ugh != NULL)
+ {
return builddiag("malformed IP address in TXT " our_TXT_attr_string ": %s"
, ugh);
-
+ }
if (isanyaddr(&ip))
+ {
return "gateway address must not be 0.0.0.0 or 0::0";
-
+ }
iptoid(&ip, gw_id);
}
@@ -278,14 +302,18 @@ process_txt_rr_body(u_char *str
/* is this for us? */
if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
+ {
return NULL; /* neither interesting nor bad */
+ }
p += sizeof(our_TXT_attr) - 1; /* ignore our attribute name */
p += strspn(p, " \t"); /* ignore leading whitespace */
/* decode '(' nnn ')' */
if (*p != '(')
+ {
return "X-IPsec-Server missing '('";
+ }
{
char *e;
@@ -293,25 +321,30 @@ process_txt_rr_body(u_char *str
p++;
pref = strtoul(p, &e, 0);
if ((u_char *)e == p)
+ {
return "malformed X-IPsec-Server priority";
-
+ }
p = e + strspn(e, " \t");
if (*p != ')')
+ {
return "X-IPsec-Server priority missing ')'";
-
+ }
p++;
p += strspn(p, " \t");
if (pref > 0xFFFF)
+ {
return "X-IPsec-Server priority larger than 0xFFFF";
+ }
}
/* time for '=' */
if (*p != '=')
+ {
return "X-IPsec-Server priority missing '='";
-
+ }
p++;
p += strspn(p, " \t");
@@ -384,29 +417,34 @@ process_txt_rr_body(u_char *str
/* Decode base 64 encoding of key.
* Similar code is in process_lwdnsq_key.
*/
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- struct RSA_public_key r;
-
- err_t ugh = ttodatav(p, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-
- if (ugh != NULL)
+ u_char buf[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
+ size_t sz;
+ err_t ugh;
+ chunk_t rfc3110_chunk;
+ public_key_t *key;
+
+ ugh = ttodatav(p, 0, 64, buf, sizeof(buf), &sz,
+ diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
+ if (ugh)
+ {
return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- ugh = unpack_RSA_public_key(&r, &kbc);
- if (ugh != NULL)
- return builddiag("invalid key data: %s", ugh);
+ }
+ if (sz > sizeof(buf))
+ {
+ return builddiag("key data larger than %lu bytes",
+ (unsigned long) sizeof(buf));
+ }
+ rfc3110_chunk = chunk_create(buf, sz);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_RFC_3110, rfc3110_chunk,
+ BUILD_END);
+ if (key == NULL)
+ {
+ return builddiag("invalid key data");
+ }
/* now find a key entry to put it in */
- gi.key = public_key_from_rsa(&r);
-
- free_RSA_public_content(&r);
+ gi.key = public_key_from_rsa(key);
unreference_key(&cr->last_info);
cr->last_info = reference_key(gi.key);
@@ -426,13 +464,18 @@ process_txt_rr_body(u_char *str
{
char cidb[BUF_LEN];
char gwidb[BUF_LEN];
+ identification_t *keyid;
+ public_key_t *pub_key;
idtoa(client_id, cidb, sizeof(cidb));
idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
+ pub_key = gi.key->public_key;
+ keyid = pub_key->get_id(pub_key, ID_PUBKEY_SHA1);
+
if (gi.gw_key_present)
{
- DBG_log("gateway for %s is %s with key %s"
- , cidb, gwidb, gi.key->u.rsa.keyid);
+ DBG_log("gateway for %s is %s with key %Y"
+ , cidb, gwidb, keyid);
}
else
{