summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHakan Olsson <ho@cvs.openbsd.org>2003-05-18 19:37:48 +0000
committerHakan Olsson <ho@cvs.openbsd.org>2003-05-18 19:37:48 +0000
commitc7dbb2513f201e339a478971b6b83aad177e05e9 (patch)
treee00b77ea29ed11af23d89b74ddb453ee32cdaf7b
parent83f54bd6f28f561dfb8e52c42c2d6fd9859cca77 (diff)
More isakmpd privsep work. X509 private keys are now kept in the privileged
process only. Various cleanup and bugfixes. markus@ ok
-rw-r--r--sbin/isakmpd/conf.c4
-rw-r--r--sbin/isakmpd/ike_auth.c141
-rw-r--r--sbin/isakmpd/isakmpd.c6
-rw-r--r--sbin/isakmpd/log.c6
-rw-r--r--sbin/isakmpd/monitor.c541
-rw-r--r--sbin/isakmpd/monitor.h30
-rw-r--r--sbin/isakmpd/monitor_fdpass.c5
-rw-r--r--sbin/isakmpd/pf_key_v2.c4
-rw-r--r--sbin/isakmpd/policy.c4
9 files changed, 574 insertions, 167 deletions
diff --git a/sbin/isakmpd/conf.c b/sbin/isakmpd/conf.c
index 41c56087050..865c0d56cb0 100644
--- a/sbin/isakmpd/conf.c
+++ b/sbin/isakmpd/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.52 2003/05/15 00:28:53 ho Exp $ */
+/* $OpenBSD: conf.c,v 1.53 2003/05/18 19:37:46 ho Exp $ */
/* $EOM: conf.c,v 1.48 2000/12/04 02:04:29 angelos Exp $ */
/*
@@ -611,7 +611,7 @@ conf_reinit (void)
fd, new_conf_addr, (unsigned long)sz);
goto fail;
}
- monitor_close (fd);
+ close (fd);
trans = conf_begin ();
diff --git a/sbin/isakmpd/ike_auth.c b/sbin/isakmpd/ike_auth.c
index f1ffbaa823e..d7f24977828 100644
--- a/sbin/isakmpd/ike_auth.c
+++ b/sbin/isakmpd/ike_auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ike_auth.c,v 1.73 2003/05/15 03:20:28 ho Exp $ */
+/* $OpenBSD: ike_auth.c,v 1.74 2003/05/18 19:37:46 ho Exp $ */
/* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */
/*
@@ -151,10 +151,6 @@ ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen)
BIO *keyh;
RSA *rsakey;
size_t fsize;
-#if defined (USE_PRIVSEP)
- int fd;
- char *fdata;
-#endif
#endif
#endif
@@ -296,51 +292,6 @@ ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen)
if (check_file_secrecy (keyfile, &fsize))
return 0;
-#if defined (USE_PRIVSEP)
- /* XXX Try to find a better solution. */
- keyh = BIO_new (BIO_s_mem ());
- if (keyh == NULL)
- {
- log_print ("ike_auth_get_key: "
- "BIO_new (BIO_s_mem ()) failed");
- return 0;
- }
- fd = monitor_open (keyfile, O_RDONLY, 0);
- if (fd < 0)
- {
- log_print ("ike_auth_get_key: open(\"%s\") failed", keyfile);
- BIO_free (keyh);
- return 0;
- }
- fdata = (char *)malloc (fsize);
- if (!fdata)
- {
- log_error ("ike_auth_get_get: malloc (%d) failed", fsize);
- monitor_close (fd);
- BIO_free (keyh);
- return 0;
- }
- if (read (fd, fdata, fsize) != fsize)
- {
- log_error ("ike_auth_get_key: short read");
- monitor_close (fd);
- BIO_free (keyh);
- memset (fdata, 0, fsize);
- free (fdata);
- return 0;
- }
- monitor_close (fd);
- if (BIO_write (keyh, fdata, fsize) == -1)
- {
- log_print ("ike_auth_get_key: BIO_read () failed");
- BIO_free (keyh);
- memset (fdata, 0, fsize);
- free (fdata);
- return 0;
- }
- memset (fdata, 0, fsize);
- free (fdata);
-#else
keyh = BIO_new (BIO_s_file ());
if (keyh == NULL)
{
@@ -356,7 +307,6 @@ ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen)
BIO_free (keyh);
return 0;
}
-#endif /* USE_PRIVSEP */
#if SSLEAY_VERSION_NUMBER >= 0x00904100L
rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL);
@@ -964,7 +914,6 @@ rsa_sig_encode_hash (struct message *msg)
u_int8_t *id;
size_t id_len;
int idtype;
- int sent_keytype;
void *sent_key;
id = initiator ? exchange->id_i : exchange->id_r;
@@ -1075,38 +1024,6 @@ rsa_sig_encode_hash (struct message *msg)
skipcert:
- switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ])
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- util_ntoa ((char **)&buf2,
- id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] == IPSEC_ID_IPV4_ADDR
- ? AF_INET : AF_INET6,
- id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- if (!buf2)
- return 0;
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- buf2 = calloc (id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- sizeof (char));
- if (!buf2)
- {
- log_print ("rsa_sig_encode_hash: malloc (%lu) failed",
- (unsigned long)id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1);
- return 0;
- }
- memcpy (buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
-
- /* XXX Support more ID types? */
- default:
- buf2 = 0;
- break;
- }
-
/* Again, we may have these from the kernel */
buf = (u_int8_t *)conf_get_str (exchange->name, "PKAuthentication");
if (buf)
@@ -1119,7 +1036,6 @@ rsa_sig_encode_hash (struct message *msg)
return 0;
}
- sent_keytype = ISAKMP_KEY_RSA;
sent_key = key_internalize (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, data,
datalen);
if (!sent_key)
@@ -1128,11 +1044,54 @@ rsa_sig_encode_hash (struct message *msg)
"SA acquisition subsystem");
return 0;
}
+#if defined (USE_PRIVSEP)
+ {
+ /* With USE_PRIVSEP, the sent_key should be a key number. */
+ void *key = sent_key;
+ sent_key = monitor_RSA_upload_key (key);
+ }
+#endif
}
else /* Try through the regular means. */
{
+ switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ])
+ {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa ((char **)&buf2,
+ id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] == IPSEC_ID_IPV4_ADDR
+ ? AF_INET : AF_INET6,
+ id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ if (!buf2)
+ return 0;
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ buf2 = calloc (id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
+ sizeof (char));
+ if (!buf2)
+ {
+ log_print ("rsa_sig_encode_hash: malloc (%lu) failed",
+ (unsigned long)id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1);
+ return 0;
+ }
+ memcpy (buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
+ break;
+
+ /* XXX Support more ID types? */
+ default:
+ buf2 = 0;
+ return 0;
+ }
+
+#if defined (USE_PRIVSEP)
+ sent_key = monitor_RSA_get_private_key (exchange->name, (char *)buf2);
+#else
sent_key = ike_auth_get_key (IKE_AUTH_RSA_SIG, exchange->name,
(char *)buf2, 0);
+#endif
free (buf2);
/* Did we find a key? */
@@ -1141,16 +1100,16 @@ rsa_sig_encode_hash (struct message *msg)
log_print ("rsa_sig_encode_hash: could not get private key");
return -1;
}
-
- sent_keytype = ISAKMP_KEY_RSA;
}
+#if !defined (USE_PRIVSEP)
/* Enable RSA blinding. */
if (RSA_blinding_on (sent_key, NULL) != 1)
{
log_error ("rsa_sig_encode_hash: RSA_blinding_on () failed.");
return -1;
}
+#endif
/* XXX hashsize is not necessarily prf->blocksize. */
buf = malloc (hashsize);
@@ -1170,6 +1129,7 @@ rsa_sig_encode_hash (struct message *msg)
snprintf (header, 80, "rsa_sig_encode_hash: HASH_%c", initiator ? 'I' : 'R');
LOG_DBG_BUF ((LOG_MISC, 80, header, buf, hashsize));
+#if !defined (USE_PRIVSEP)
data = malloc (RSA_size (sent_key));
if (!data)
{
@@ -1180,10 +1140,17 @@ rsa_sig_encode_hash (struct message *msg)
datalen = RSA_private_encrypt (hashsize, buf, data, sent_key,
RSA_PKCS1_PADDING);
+#else
+ datalen = monitor_RSA_private_encrypt (hashsize, buf, &data, sent_key,
+ RSA_PKCS1_PADDING);
+#endif /* USE_PRIVSEP */
if (datalen == -1)
{
log_print ("rsa_sig_encode_hash: RSA_private_encrypt () failed");
+ if (data)
+ free (data);
free (buf);
+ monitor_RSA_free (sent_key);
return -1;
}
diff --git a/sbin/isakmpd/isakmpd.c b/sbin/isakmpd/isakmpd.c
index e70d6a90618..0022701e016 100644
--- a/sbin/isakmpd/isakmpd.c
+++ b/sbin/isakmpd/isakmpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isakmpd.c,v 1.51 2003/05/15 00:28:53 ho Exp $ */
+/* $OpenBSD: isakmpd.c,v 1.52 2003/05/18 19:37:46 ho Exp $ */
/* $EOM: isakmpd.c,v 1.54 2000/10/05 09:28:22 niklas Exp $ */
/*
@@ -253,7 +253,7 @@ report (void)
log_to (rfp);
ui_report ("r");
log_to (old);
- monitor_fclose (rfp);
+ fclose (rfp);
sigusr1ed = 0;
}
@@ -348,7 +348,7 @@ write_pid_file (void)
{
/* XXX Error checking! */
fprintf (fp, "%ld\n", (long) getpid ());
- monitor_fclose (fp);
+ fclose (fp);
}
else
log_fatal ("main: fopen (\"%s\", \"w\") failed", pid_file);
diff --git a/sbin/isakmpd/log.c b/sbin/isakmpd/log.c
index 7c2c54f423c..3707abeb0fc 100644
--- a/sbin/isakmpd/log.c
+++ b/sbin/isakmpd/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.31 2003/05/15 00:28:53 ho Exp $ */
+/* $OpenBSD: log.c,v 1.32 2003/05/18 19:37:46 ho Exp $ */
/* $EOM: log.c,v 1.30 2000/09/29 08:19:23 niklas Exp $ */
/*
@@ -186,7 +186,7 @@ _log_print (int error, int syslog_level, const char *fmt, va_list ap,
if (fileno (log_output) != -1
&& fileno (stdout) == fileno (log_output))
fclose (stdout);
- fclose (log_output); /* XXX monitor_fclose ? */
+ fclose (log_output);
/* Fallback to syslog. */
log_to (0);
@@ -437,7 +437,7 @@ log_packet_stop (void)
/* Stop capture. */
if (packet_log)
{
- monitor_fclose (packet_log);
+ fclose (packet_log);
log_print ("log_packet_stop: stopped capture");
}
packet_log = 0;
diff --git a/sbin/isakmpd/monitor.c b/sbin/isakmpd/monitor.c
index fb6645047be..a36a49c0a27 100644
--- a/sbin/isakmpd/monitor.c
+++ b/sbin/isakmpd/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.3 2003/05/15 02:04:45 ho Exp $ */
+/* $OpenBSD: monitor.c,v 1.4 2003/05/18 19:37:46 ho Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -40,8 +40,19 @@
#include <string.h>
#include <unistd.h>
+#if defined (USE_POLICY)
+#include <regex.h>
+#include <keynote.h>
+#endif
+
+#include "conf.h"
#include "log.h"
#include "monitor.h"
+#include "policy.h"
+#include "util.h"
+#if defined (USE_X509)
+#include "x509.h"
+#endif
struct monitor_state
{
@@ -65,7 +76,17 @@ void m_priv_getsocket (int);
void m_priv_setsockopt (int);
void m_priv_bind (int);
void m_priv_mkfifo (int);
-void m_priv_close (int);
+
+#if defined (USE_X509)
+void m_priv_rsa_getkey (int);
+void m_priv_rsa_freekey (int);
+void m_priv_rsa_uploadkey (int);
+void m_priv_rsa_encrypt (int);
+
+int32_t m_priv_local_addkey (RSA *);
+RSA *m_priv_local_getkey (int32_t);
+void m_priv_local_deletekey (int32_t);
+#endif /* USE_X509 */
/*
* Public functions, unprivileged.
@@ -91,7 +112,7 @@ monitor_init (void)
m_state.s = p[m_state.pid ? 1 : 0];
strlcpy (m_state.root, pw->pw_dir, sizeof m_state.root);
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_init: pid %d my fd %d", m_state.pid,
+ LOG_DBG ((LOG_SYSDEP, 30, "monitor_init: pid %d my fd %d", m_state.pid,
m_state.s));
/* The child process should drop privileges now. */
@@ -124,11 +145,11 @@ monitor_open (const char *path, int flags, mode_t mode)
int fd, mode32 = (int32_t) mode;
char realpath[MAXPATHLEN];
- /* Only the child process is supposed to run this. */
if (m_state.pid)
- log_fatal ("[priv] bad call to monitor_open");
-
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_open: enter"));
+ {
+ /* Called from the parent, i.e already privileged. */
+ return open (path, flags, mode);
+ }
if (path[0] == '/')
strlcpy (realpath, path, sizeof realpath);
@@ -156,7 +177,6 @@ monitor_open (const char *path, int flags, mode_t mode)
log_error ("monitor_open: open(\"%s\") failed", path);
return -1;
}
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_open: got fd %d", fd));
return fd;
@@ -171,8 +191,6 @@ monitor_fopen (const char *path, const char *mode)
FILE *fp;
int fd, flags = 0, umask = 0;
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_fopen: enter"));
-
/* Only the child process is supposed to run this. */
if (m_state.pid)
log_fatal ("[priv] bad call to monitor_fopen");
@@ -213,8 +231,6 @@ monitor_stat (const char *path, struct stat *sb)
{
int fd, r, saved_errno;
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_stat: enter"));
-
fd = monitor_open (path, O_RDONLY, 0);
if (fd < 0)
{
@@ -224,7 +240,7 @@ monitor_stat (const char *path, struct stat *sb)
r = fstat (fd, sb);
saved_errno = errno;
- monitor_close (fd);
+ close (fd);
errno = saved_errno;
return r;
}
@@ -234,8 +250,6 @@ monitor_socket (int domain, int type, int protocol)
{
int s;
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_socket: enter"));
-
if (m_write_int32 (m_state.s, MONITOR_GET_SOCKET))
goto errout;
@@ -252,7 +266,6 @@ monitor_socket (int domain, int type, int protocol)
/* Read result. */
s = mm_receive_fd (m_state.s);
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_socket: return fd %d", s));
return s;
errout:
@@ -266,11 +279,9 @@ monitor_setsockopt (int s, int level, int optname, const void *optval,
{
int ret;
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_setsockopt: enter"));
-
if (m_write_int32 (m_state.s, MONITOR_SETSOCKOPT))
goto errout;
- mm_send_fd (m_state.s, s);
+ mm_send_fd (m_state.s, s); /* XXX? */
if (m_write_int32 (m_state.s, (int32_t)level))
goto errout;
@@ -296,8 +307,6 @@ monitor_bind (int s, const struct sockaddr *name, socklen_t namelen)
{
int ret;
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_bind: enter"));
-
if (m_write_int32 (m_state.s, MONITOR_BIND))
goto errout;
mm_send_fd (m_state.s, s);
@@ -327,8 +336,6 @@ monitor_mkfifo (const char *path, mode_t mode)
if (m_state.pid)
log_fatal ("[priv] bad call to monitor_mkfifo");
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_mkfifo: enter"));
-
if (path[0] == '/')
strlcpy (realpath, path, sizeof realpath);
else
@@ -354,38 +361,134 @@ monitor_mkfifo (const char *path, mode_t mode)
return -1;
}
-int
-monitor_close (int s)
+#if defined (USE_X509)
+/* Called by rsa_sig_encode_hash, the code that gets a key from ACQUIRE. */
+char *
+monitor_RSA_upload_key (char *k_raw)
{
- if (m_write_int32 (m_state.s, MONITOR_CLOSE))
+ RSA *rsa = (RSA *)k_raw;
+ int32_t v;
+
+ if (m_write_int32 (m_state.s, MONITOR_RSA_UPLOADKEY))
goto errout;
- mm_send_fd (m_state.s, s);
+ /* XXX - incomplete */
+ if (m_write_raw (m_state.s, k_raw, 0))
+ goto errout;
+
+ RSA_free (rsa);
- return close (s);
+ if (m_read_int32 (m_state.s, &v))
+ goto errout;
+
+ return (char *)v;
errout:
- log_print ("monitor_close: write error");
- return close (s);
+ log_print ("monitor_RSA_upload_key: read/write error");
+ return 0;
+}
+
+char *
+monitor_RSA_get_private_key (char *id, char *local_id)
+{
+ char *confval;
+ int32_t v;
+
+ if (m_write_int32 (m_state.s, MONITOR_RSA_GETKEY))
+ goto errout;
+
+ /*
+ * The privileged process will call ike_auth_get_key, so we need to
+ * to collect some current configuration data for it.
+ */
+ confval = conf_get_str ("KeyNote", "Credential-directory");
+ if (!confval)
+ m_write_int32 (m_state.s, 0);
+ else
+ m_write_raw (m_state.s, confval, strlen (confval) + 1);
+
+ confval = conf_get_str ("X509-certificates", "Private-key");
+ if (!confval)
+ m_write_int32 (m_state.s, 0);
+ else
+ m_write_raw (m_state.s, confval, strlen (confval) + 1);
+
+ /* Next, the required arguments. */
+ if (m_write_raw (m_state.s, id, strlen (id) + 1))
+ goto errout;
+ if (m_write_raw (m_state.s, local_id, strlen (local_id) + 1))
+ goto errout;
+
+ /* Now, read the results. */
+ if (m_read_int32 (m_state.s, &v))
+ goto errout;
+
+ return (char *)v;
+
+ errout:
+ log_print ("monitor_RSA_upload_key: read/write error");
+ return 0;
}
int
-monitor_fclose (FILE *fp)
+monitor_RSA_private_encrypt (int hashsize, unsigned char *hash,
+ unsigned char **sigdata, void *rkey, int padtype)
{
- int fd = fileno (fp);
+ int32_t v;
+ char *data = 0;
+ int datalen;
+
+ *sigdata = 0;
+
+ if (m_write_int32 (m_state.s, MONITOR_RSA_ENCRYPT))
+ goto errout;
+
+ if (m_write_int32 (m_state.s, (int32_t)hashsize))
+ goto errout;
+
+ if (m_write_raw (m_state.s, hash, hashsize))
+ goto errout;
+
+ if (m_write_int32 (m_state.s, (int32_t)rkey))
+ goto errout;
+
+ if (m_write_int32 (m_state.s, (int32_t)padtype))
+ goto errout;
+
+ /* Read results. */
+ if (m_read_int32 (m_state.s, &v))
+ goto errout;
+ datalen = (int)v;
+
+ if (datalen == -1)
+ goto errout;
- if (m_write_int32 (m_state.s, MONITOR_CLOSE))
+ data = (char *)malloc (datalen);
+ if (!data)
goto errout;
- mm_send_fd (m_state.s, fd);
+ if (m_read_raw (m_state.s, data, datalen))
+ goto errout;
- return fclose (fp);
+ *sigdata = data;
+ return datalen;
errout:
- log_print ("monitor_fclose: write error");
- return fclose (fp);
+ if (data)
+ free (data);
+ return -1;
}
+void
+monitor_RSA_free (void *key)
+{
+ if (m_write_int32 (m_state.s, MONITOR_RSA_FREEKEY) == 0)
+ m_write_int32 (m_state.s, (int32_t)key);
+
+ return;
+}
+#endif /* USE_X509 */
+
/*
* Start of code running with privileges (the monitor process).
*/
@@ -437,9 +540,7 @@ monitor_loop (int debugging)
FD_ZERO (fds);
FD_SET (m_state.s, fds);
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_loop: waiting for select()"));
n = select (maxfd, fds, NULL, NULL, NULL);
- LOG_DBG ((LOG_SYSDEP, 95, "monitor_loop: select returned %d", n));
if (n == -1)
{
if (errno != EINTR)
@@ -477,14 +578,29 @@ monitor_loop (int debugging)
m_priv_mkfifo (m_state.s);
break;
- case MONITOR_CLOSE:
- m_priv_close (m_state.s);
- break;
-
case MONITOR_SHUTDOWN:
shutdown++;
break;
+#if defined (USE_X509)
+ case MONITOR_RSA_UPLOADKEY:
+ /* XXX Not implemented yet. */
+ /* m_priv_rsa_uploadkey (m_state.s); */
+ break;
+
+ case MONITOR_RSA_GETKEY:
+ m_priv_rsa_getkey (m_state.s);
+ break;
+
+ case MONITOR_RSA_ENCRYPT:
+ m_priv_rsa_encrypt (m_state.s);
+ break;
+
+ case MONITOR_RSA_FREEKEY:
+ m_priv_rsa_freekey (m_state.s);
+ break;
+#endif
+
default:
log_print ("monitor_loop: got unknown code %d", msgcode);
}
@@ -512,8 +628,6 @@ m_priv_getfd (int s)
* u_int32_t mode
*/
- LOG_DBG ((LOG_SYSDEP, 95, "m_priv_getfd: enter"));
-
if (m_read_raw (s, path, MAXPATHLEN))
goto errout;
@@ -528,7 +642,12 @@ m_priv_getfd (int s)
/* XXX Sanity checks */
v = (int32_t)open (path, flags, mode);
- mm_send_fd (s, v);
+ if (mm_send_fd (s, v))
+ {
+ close (v);
+ goto errout;
+ }
+ close (v);
return;
errout:
@@ -543,8 +662,6 @@ m_priv_getsocket (int s)
int domain, type, protocol;
int32_t v;
- LOG_DBG ((LOG_SYSDEP, 95, "m_priv_getsocket: enter"));
-
if (m_read_int32 (s, &v))
goto errout;
domain = (int)v;
@@ -558,7 +675,12 @@ m_priv_getsocket (int s)
protocol = (int)v;
v = (int32_t)socket (domain, type, protocol);
- mm_send_fd (s, v);
+ if (mm_send_fd (s, v))
+ {
+ close (v);
+ goto errout;
+ }
+ close (v);
return;
errout:
@@ -594,6 +716,7 @@ m_priv_setsockopt (int s)
goto errout;
v = (int32_t) setsockopt (sock, level, optname, optval, optlen);
+ close (sock);
if (m_write_int32 (s, v))
goto errout;
@@ -616,8 +739,6 @@ m_priv_bind (int s)
socklen_t namelen;
int32_t v;
- LOG_DBG ((LOG_SYSDEP, 95, "m_priv_bind: enter"));
-
sock = mm_receive_fd (s);
if (m_read_int32 (s, &v))
@@ -632,6 +753,11 @@ m_priv_bind (int s)
goto errout;
v = (int32_t)bind (sock, name, namelen);
+ if (v < 0)
+ log_error ("m_priv_bind: bind(%d,%p,%d) returned %d",
+ sock, name, namelen, v);
+
+ close (sock);
if (m_write_int32 (s, v))
goto errout;
@@ -653,8 +779,6 @@ m_priv_mkfifo (int s)
mode_t mode;
int32_t v;
- LOG_DBG ((LOG_SYSDEP, 95, "m_priv_mkfifo: enter"));
-
if (m_read_raw (s, name, MAXPATHLEN))
goto errout;
@@ -679,20 +803,242 @@ m_priv_mkfifo (int s)
return;
}
-/* Privileged: called by monitor_loop. */
+#if defined (USE_X509)
void
-m_priv_close (int s)
+m_priv_rsa_getkey (int s)
{
- int sock, r;
+ char cred_dir[MAXPATHLEN], pkey_path[MAXPATHLEN], pbuf[MAXPATHLEN];
+ char id[MAXPATHLEN],local_id[MAXPATHLEN]; /* XXX MAXPATHLEN? */
+ size_t fsize;
+ int32_t keyno;
+ RSA *rsakey = 0;
+ BIO *keyh;
+
+ cred_dir[0] = pkey_path[0] = id[0] = local_id[0] = 0;
+ if (m_read_raw (s, pbuf, sizeof pbuf))
+ goto errout;
+ if (pbuf[0] == '/')
+ strlcpy (cred_dir, pbuf, sizeof cred_dir);
+ else
+ snprintf (cred_dir, sizeof cred_dir, "%s/%s", m_state.root, pbuf);
- sock = mm_receive_fd (s);
- r = close (sock);
+ if (m_read_raw (s, pbuf, sizeof pbuf))
+ goto errout;
+ if (pbuf[0] == '/')
+ strlcpy (pkey_path, pbuf, sizeof pkey_path);
+ else
+ snprintf (pkey_path, sizeof pkey_path, "%s/%s", m_state.root, pbuf);
+
+ if (m_read_raw (s, id, sizeof id))
+ goto errout;
+ if (m_read_raw (s, local_id, sizeof local_id))
+ goto errout;
- LOG_DBG ((LOG_SYSDEP, 95, "m_priv_close: closing fd %d, ret %d", sock, r));
+ /* This is basically a copy of ike_auth_get_key (). */
+#if defined (USE_KEYNOTE)
+ if (local_id[0] && cred_dir[0])
+ {
+ struct stat sb;
+ struct keynote_deckey dc;
+ char *privkeyfile, *buf2, *buf;
+ int fd, pkflen;
+ size_t size;
+
+ pkflen = strlen (cred_dir) + strlen (local_id) +
+ sizeof PRIVATE_KEY_FILE + sizeof "//" - 1;
+ privkeyfile = calloc (pkflen, sizeof (char));
+ if (!privkeyfile)
+ {
+ log_print ("m_priv_rsa_getkey: failed to allocate %d bytes", pkflen);
+ goto errout;
+ }
+ snprintf (privkeyfile, pkflen, "%s/%s/%s", cred_dir, local_id,
+ PRIVATE_KEY_FILE);
+
+ if (stat (privkeyfile, &sb) < 0)
+ {
+ free (privkeyfile);
+ goto ignorekeynote;
+ }
+ size = (size_t)sb.st_size;
+
+ fd = open (privkeyfile, O_RDONLY, 0);
+ if (fd < 0)
+ {
+ log_print ("m_priv_rsa_getkey: failed opening \"%s\"", privkeyfile);
+ free (privkeyfile);
+ goto errout;
+ }
+
+ buf = calloc (size + 1, sizeof (char));
+ if (!buf)
+ {
+ log_print ("m_priv_rsa_getkey: failed allocating %lu bytes",
+ (unsigned long)size + 1);
+ free (privkeyfile);
+ goto errout;
+ }
+
+ if (read (fd, buf, size) != size)
+ {
+ free (buf);
+ log_print ("m_priv_rsa_getkey: "
+ "failed reading %lu bytes from \"%s\"",
+ (unsigned long)size, privkeyfile);
+ free (privkeyfile);
+ goto errout;
+ }
+
+ close (fd);
+
+ /* Parse private key string */
+ buf2 = kn_get_string (buf);
+ free (buf);
+
+ if (kn_decode_key (&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1)
+ {
+ free (buf2);
+ log_print ("m_priv_rsa_getkey: failed decoding key in \"%s\"",
+ privkeyfile);
+ free (privkeyfile);
+ goto errout;
+ }
+
+ free (buf2);
+
+ if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA)
+ {
+ log_print ("m_priv_rsa_getkey: wrong algorithm type %d in \"%s\"",
+ dc.dec_algorithm, privkeyfile);
+ free (privkeyfile);
+ kn_free_key (&dc);
+ goto errout;
+ }
+
+ free (privkeyfile);
+ rsakey = dc.dec_key;
+ }
+ ignorekeynote:
+#endif /* USE_KEYNOTE */
+
+ /* XXX I do not really like to call this from here. */
+ if (check_file_secrecy (pkey_path, &fsize))
+ goto errout;
+
+ keyh = BIO_new (BIO_s_file ());
+ if (keyh == NULL)
+ {
+ log_print ("m_priv_rsa_getkey: "
+ "BIO_new (BIO_s_file ()) failed");
+ goto errout;
+ }
+ if (BIO_read_filename (keyh, pkey_path) == -1)
+ {
+ log_print ("m_priv_rsa_getkey: "
+ "BIO_read_filename (keyh, \"%s\") failed",
+ pkey_path);
+ BIO_free (keyh);
+ goto errout;
+ }
+
+#if SSLEAY_VERSION_NUMBER >= 0x00904100L
+ rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL);
+#else
+ rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL);
+#endif
+ BIO_free (keyh);
+ if (!rsakey)
+ {
+ log_print ("m_priv_rsa_getkey: PEM_read_bio_RSAPrivateKey failed");
+ goto errout;
+ }
+
+ /* Enable RSA blinding. */
+ if (RSA_blinding_on (rsakey, NULL) != 1)
+ {
+ log_error ("m_priv_rsa_getkey: RSA_blinding_on () failed");
+ goto errout;
+ }
+
+ keyno = m_priv_local_addkey (rsakey);
+ m_write_int32 (s, keyno);
+ return;
+
+ errout:
+ m_write_int32 (s, -1);
+ if (rsakey)
+ RSA_free (rsakey);
return;
}
+void
+m_priv_rsa_encrypt (int s)
+{
+ int32_t hashsize, padtype, datalen;
+ char *hash = 0, *data = 0;
+ RSA *key;
+ int32_t v;
+
+ if (m_read_int32 (s, &hashsize))
+ goto errout;
+
+ hash = (char *)malloc (hashsize);
+ if (!hash)
+ goto errout;
+
+ if (m_read_raw (s, hash, hashsize))
+ goto errout;
+
+ if (m_read_int32 (s, &v))
+ goto errout;
+
+ if (m_read_int32 (s, &padtype))
+ goto errout;
+
+ key = m_priv_local_getkey (v);
+ if (!key)
+ goto errout;
+
+ data = (char *)malloc (RSA_size (key));
+ if (!data)
+ goto errout;
+
+ datalen = RSA_private_encrypt (hashsize, hash, data, key, padtype);
+ if (datalen == -1)
+ {
+ log_print ("m_priv_rsa_encrypt: RSA_private_encrypt () failed");
+ goto errout;
+ }
+
+ if (m_write_int32 (s, datalen))
+ goto errout;
+
+ if (m_write_raw (s, data, datalen))
+ goto errout;
+
+ free (hash);
+ free (data);
+ return;
+
+ errout:
+ m_write_int32 (s, -1);
+ if (data)
+ free (data);
+ if (hash)
+ free (hash);
+ return;
+}
+
+void
+m_priv_rsa_freekey (int s)
+{
+ int32_t keyno;
+ if (m_read_int32 (s, &keyno) == 0)
+ m_priv_local_deletekey (keyno);
+}
+#endif /* USE_X509 */
+
/*
* Help functions, used by both privileged and unprivileged code
*/
@@ -746,9 +1092,82 @@ m_flush (int s)
u_int8_t tmp;
int one = 1;
- LOG_DBG ((LOG_SYSDEP, 95, "m_flush: fd %d enter", s));
ioctl (s, FIONBIO, &one); /* Non-blocking */
while (read (s, &tmp, 1) > 0) ;
ioctl (s, FIONBIO, 0); /* Blocking */
- LOG_DBG ((LOG_SYSDEP, 95, "m_flush: fd %d done", s));
}
+
+#if defined (USE_X509)
+/* Privileged process RSA key storage help functions. */
+struct m_key_storage
+{
+ RSA *key;
+ int32_t keyno;
+ struct m_key_storage *next;
+} *keylist = 0;
+
+int32_t
+m_priv_local_addkey (RSA *key)
+{
+ struct m_key_storage *n, *k;
+
+ n = (struct m_key_storage *)calloc (1, sizeof (struct m_key_storage));
+ if (!n)
+ return 0;
+
+ if (!keylist)
+ {
+ keylist = n;
+ n->keyno = 1;
+ }
+ else
+ {
+ for (k = keylist; k->next; k = k->next) ;
+ k->next = n;
+ n->keyno = k->keyno + 1; /* XXX 2^31 keys? */
+ }
+
+ n->key = key;
+ return n->keyno;
+}
+
+RSA *
+m_priv_local_getkey (int32_t keyno)
+{
+ struct m_key_storage *k;
+
+ for (k = keylist; k; k = k->next)
+ if (k->keyno == keyno)
+ return k->key;
+ return 0;
+}
+
+void
+m_priv_local_deletekey (int32_t keyno)
+{
+ struct m_key_storage *k;
+
+ if (keylist->keyno == keyno)
+ {
+ k = keylist;
+ keylist = keylist->next;
+ }
+ else
+ for (k = keylist; k->next; k = k->next)
+ if (k->next->keyno == keyno)
+ {
+ struct m_key_storage *s = k->next;
+ k->next = k->next->next;
+ k = s;
+ break;
+ }
+
+ if (k)
+ {
+ RSA_free (k->key);
+ free (k);
+ }
+
+ return;
+}
+#endif /* USE_X509 */
diff --git a/sbin/isakmpd/monitor.h b/sbin/isakmpd/monitor.h
index 358b3ba54b0..d91b0614842 100644
--- a/sbin/isakmpd/monitor.h
+++ b/sbin/isakmpd/monitor.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.2 2003/05/17 17:39:26 ho Exp $ */
+/* $OpenBSD: monitor.h,v 1.3 2003/05/18 19:37:46 ho Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -38,8 +38,13 @@ enum monitor_reqtypes
MONITOR_SETSOCKOPT,
MONITOR_BIND,
MONITOR_MKFIFO,
- MONITOR_CLOSE,
MONITOR_SHUTDOWN,
+#if defined (USE_X509)
+ MONITOR_RSA_UPLOADKEY,
+ MONITOR_RSA_GETKEY,
+ MONITOR_RSA_ENCRYPT,
+ MONITOR_RSA_FREEKEY,
+#endif
};
pid_t monitor_init (void);
@@ -56,9 +61,17 @@ int monitor_socket (int, int, int);
int monitor_setsockopt (int, int, int, const void *, socklen_t);
int monitor_bind (int, const struct sockaddr *, socklen_t);
int monitor_mkfifo (const char *, mode_t);
-int monitor_close (int);
-int monitor_fclose (FILE *);
-#else
+
+#if defined (USE_X509)
+char *monitor_RSA_upload_key (char *);
+char *monitor_RSA_get_private_key (char *, char *);
+int monitor_RSA_private_encrypt (int, unsigned char *, unsigned char **,
+ void *, int);
+void monitor_RSA_free (void *);
+#endif
+
+#else /* !USE_PRIVSEP */
+
#define monitor_fopen fopen
#define monitor_open open
#define monitor_stat stat
@@ -66,6 +79,9 @@ int monitor_fclose (FILE *);
#define monitor_setsockopt setsockopt
#define monitor_bind bind
#define monitor_mkfifo mkfifo
-#define monitor_close close
-#define monitor_fclose fclose
+
+#if defined (USE_X509)
+#define monitor_RSA_free RSA_free
#endif
+
+#endif /* USE_PRIVSEP */
diff --git a/sbin/isakmpd/monitor_fdpass.c b/sbin/isakmpd/monitor_fdpass.c
index 6a5cfff228f..e7f7f96bfba 100644
--- a/sbin/isakmpd/monitor_fdpass.c
+++ b/sbin/isakmpd/monitor_fdpass.c
@@ -41,6 +41,8 @@ mm_send_fd (int socket, int fd)
char ch = '\0';
ssize_t n;
+ LOG_DBG ((LOG_SYSDEP, 90, "mm_send_fd: send %d", fd));
+
memset(&msg, 0, sizeof msg);
msg.msg_control = (caddr_t)tmp;
msg.msg_controllen = CMSG_LEN (sizeof (int));
@@ -107,5 +109,8 @@ mm_receive_fd (int socket)
return -1;
}
fd = (*(int *)CMSG_DATA (cmsg));
+
+ LOG_DBG ((LOG_SYSDEP, 90, "mm_receive_fd: recv %d", fd));
+
return fd;
}
diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c
index 46c10126b04..412d601150f 100644
--- a/sbin/isakmpd/pf_key_v2.c
+++ b/sbin/isakmpd/pf_key_v2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_key_v2.c,v 1.130 2003/05/18 18:16:34 ho Exp $ */
+/* $OpenBSD: pf_key_v2.c,v 1.131 2003/05/18 19:37:46 ho Exp $ */
/* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */
/*
@@ -623,7 +623,7 @@ pf_key_v2_open (void)
cleanup:
if (pf_key_v2_socket != -1)
{
- monitor_close (pf_key_v2_socket);
+ close (pf_key_v2_socket);
pf_key_v2_socket = -1;
}
if (ret)
diff --git a/sbin/isakmpd/policy.c b/sbin/isakmpd/policy.c
index 12b1e5581fa..50d2261f30e 100644
--- a/sbin/isakmpd/policy.c
+++ b/sbin/isakmpd/policy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: policy.c,v 1.61 2003/05/15 00:28:53 ho Exp $ */
+/* $OpenBSD: policy.c,v 1.62 2003/05/18 19:37:47 ho Exp $ */
/* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
/*
@@ -1829,7 +1829,7 @@ policy_init (void)
}
/* We're done with this. */
- monitor_close (fd);
+ close (fd);
/* Parse buffer, break up into individual policies. */
asserts = kn_read_asserts (ptr, sz, &i);