summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMoritz Jodeit <moritz@cvs.openbsd.org>2005-05-28 17:42:51 +0000
committerMoritz Jodeit <moritz@cvs.openbsd.org>2005-05-28 17:42:51 +0000
commitd4e8f7d27f6b9c6cb67a3ab79c29d355c919baf7 (patch)
treed555c03a2b3b267948ab0bd89d7566d15cf17ccf /sbin
parentaad5afe1cb3ef150317b503b65ed62d342e6ad60 (diff)
introduce new readdir implementation for the monitor.
testing and ok hshoexer@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/isakmpd/monitor.c179
-rw-r--r--sbin/isakmpd/monitor.h13
-rw-r--r--sbin/isakmpd/x509.c66
3 files changed, 116 insertions, 142 deletions
diff --git a/sbin/isakmpd/monitor.c b/sbin/isakmpd/monitor.c
index 370ba94cd62..113836d4219 100644
--- a/sbin/isakmpd/monitor.c
+++ b/sbin/isakmpd/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.56 2005/05/28 17:07:53 moritz Exp $ */
+/* $OpenBSD: monitor.c,v 1.57 2005/05/28 17:42:49 moritz Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -70,6 +70,7 @@ static void must_write(const void *, size_t);
static void m_priv_getfd(void);
static void m_priv_setsockopt(void);
+static void m_priv_req_readdir(void);
static void m_priv_bind(void);
static void m_priv_ui_init(void);
static void m_priv_pfkey_open(void);
@@ -358,96 +359,41 @@ errout:
return -1;
}
-struct monitor_dirents *
-monitor_opendir(const char *path)
+int
+monitor_req_readdir(const char *filename)
{
- char *buf, *cp;
- size_t bufsize;
- int fd, nbytes, entries;
- long base;
- struct stat sb;
- struct dirent *dp;
- struct monitor_dirents *direntries;
-
- fd = monitor_open(path, 0, O_RDONLY);
- if (fd < 0) {
- log_error("monitor_opendir: opendir(\"%s\") failed", path);
- return NULL;
- }
- /* Now build a list with all dirents from fd. */
- if (fstat(fd, &sb) < 0) {
- (void)close(fd);
- return NULL;
- }
- if (!S_ISDIR(sb.st_mode)) {
- (void)close(fd);
- errno = EACCES;
- return NULL;
- }
- bufsize = sb.st_size;
- if (bufsize < sb.st_blksize)
- bufsize = sb.st_blksize;
-
- buf = calloc(bufsize, sizeof(char));
- if (buf == NULL) {
- (void)close(fd);
- errno = EACCES;
- return NULL;
- }
- nbytes = getdirentries(fd, buf, bufsize, &base);
- if (nbytes <= 0) {
- (void)close(fd);
- free(buf);
- errno = EACCES;
- return NULL;
- }
- (void)close(fd);
+ int cmd, err;
+ size_t len;
- for (entries = 0, cp = buf; cp < buf + nbytes;) {
- dp = (struct dirent *)cp;
- cp += dp->d_reclen;
- entries++;
- }
+ cmd = MONITOR_REQ_READDIR;
+ must_write(&cmd, sizeof cmd);
- direntries = calloc(1, sizeof(struct monitor_dirents));
- if (direntries == NULL) {
- free(buf);
- errno = EACCES;
- return NULL;
- }
- direntries->dirents = calloc(entries + 1, sizeof(struct dirent *));
- if (direntries->dirents == NULL) {
- free(buf);
- free(direntries);
- errno = EACCES;
- return NULL;
- }
- direntries->current = 0;
+ len = strlen(filename);
+ must_write(&len, sizeof len);
+ must_write(filename, len);
- for (entries = 0, cp = buf; cp < buf + nbytes;) {
- dp = (struct dirent *)cp;
- direntries->dirents[entries++] = dp;
- cp += dp->d_reclen;
- }
- direntries->dirents[entries] = NULL;
+ must_read(&err, sizeof err);
+ if (err == -1)
+ must_read(&errno, sizeof errno);
- return direntries;
+ return (err);
}
-struct dirent *
-monitor_readdir(struct monitor_dirents *direntries)
+int
+monitor_readdir(char *file, size_t size)
{
- if (direntries->dirents[direntries->current] != NULL)
- return direntries->dirents[direntries->current++];
+ int fd;
+ size_t len;
- return NULL;
-}
-
-void
-monitor_closedir(struct monitor_dirents *direntries)
-{
- free(direntries->dirents);
- free(direntries);
+ must_read(&len, sizeof len);
+ if (len == 0)
+ return -1;
+ if (len >= size)
+ log_fatal("monitor_readdir: received bad length from monitor");
+ must_read(file, len);
+ file[len] = '\0';
+ fd = mm_receive_fd(m_state.s);
+ return fd;
}
void
@@ -565,6 +511,12 @@ monitor_loop(int debug)
m_priv_bind();
break;
+ case MONITOR_REQ_READDIR:
+ LOG_DBG((LOG_MISC, 80,
+ "monitor_loop: MONITOR_REQ_READDIR"));
+ m_priv_req_readdir();
+ break;
+
case MONITOR_INIT_DONE:
LOG_DBG((LOG_MISC, 80,
"monitor_loop: MONITOR_INIT_DONE"));
@@ -945,6 +897,69 @@ m_priv_check_bind(const struct sockaddr *sa, socklen_t salen)
return 0;
}
+static void
+m_priv_req_readdir()
+{
+ size_t len;
+ char path[MAXPATHLEN];
+ DIR *dp;
+ struct dirent *file;
+ int off, size, fd, ret, serrno;
+
+ must_read(&len, sizeof len);
+ if (len == 0 || len >= sizeof path)
+ log_fatal("m_priv_req_readdir: invalid pathname length");
+ must_read(path, len);
+ path[len] = '\0';
+ if (strlen(path) != len)
+ log_fatal("m_priv_req_readdir: invalid pathname");
+
+ off = strlen(path);
+ size = sizeof path - off;
+
+ /* XXX sanitize path */
+
+ if ((dp = opendir(path)) == NULL) {
+ serrno = errno;
+ ret = -1;
+ must_write(&ret, sizeof ret);
+ must_write(&serrno, sizeof serrno);
+ return;
+ }
+
+ /* report opendir() success */
+ ret = 0;
+ must_write(&ret, sizeof ret);
+
+ while ((file = readdir(dp)) != NULL) {
+ strlcpy(path + off, file->d_name, size);
+
+ if (file->d_type != DT_UNKNOWN && file->d_type != DT_REG &&
+ file->d_type != DT_LNK)
+ continue;
+
+ fd = open(path, O_RDONLY, 0);
+ if (fd == -1) {
+ log_error("m_priv_req_readdir: open "
+ "(\"%s\", O_RDONLY, 0) failed", path);
+ continue;
+ }
+
+ len = strlen(path);
+ must_write(&len, sizeof len);
+ must_write(path, len);
+
+ mm_send_fd(m_state.s, fd);
+ close(fd);
+ }
+ closedir(dp);
+
+ len = 0;
+ must_write(&len, sizeof len);
+
+ return;
+}
+
/* Increase state into less permissive mode */
static void
m_priv_increase_state(int state)
diff --git a/sbin/isakmpd/monitor.h b/sbin/isakmpd/monitor.h
index 5f8835bd055..01f9d13a04f 100644
--- a/sbin/isakmpd/monitor.h
+++ b/sbin/isakmpd/monitor.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.14 2005/05/27 07:08:21 moritz Exp $ */
+/* $OpenBSD: monitor.h,v 1.15 2005/05/28 17:42:50 moritz Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -43,6 +43,7 @@ enum monitor_reqtypes {
MONITOR_GET_FD,
MONITOR_SETSOCKOPT,
MONITOR_BIND,
+ MONITOR_REQ_READDIR,
MONITOR_MKFIFO,
MONITOR_INIT_DONE,
MONITOR_SHUTDOWN
@@ -54,11 +55,6 @@ enum priv_state {
STATE_QUIT /* shutting down */
};
-struct monitor_dirents {
- int current;
- struct dirent **dirents;
-};
-
pid_t monitor_init(int);
void monitor_loop(int);
@@ -70,9 +66,8 @@ int monitor_open(const char *, int, mode_t);
int monitor_stat(const char *, struct stat *);
int monitor_setsockopt(int, int, int, const void *, socklen_t);
int monitor_bind(int, const struct sockaddr *, socklen_t);
-struct monitor_dirents *monitor_opendir(const char *);
-struct dirent *monitor_readdir(struct monitor_dirents *);
-void monitor_closedir(struct monitor_dirents *);
+int monitor_req_readdir(const char *);
+int monitor_readdir(char *, size_t);
void monitor_init_done(void);
void monitor_ui_init(void);
diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c
index d799989732a..d9d0f0e0183 100644
--- a/sbin/isakmpd/x509.c
+++ b/sbin/isakmpd/x509.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.c,v 1.102 2005/05/26 00:58:52 cloder Exp $ */
+/* $OpenBSD: x509.c,v 1.103 2005/05/28 17:42:50 moritz Exp $ */
/* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */
/*
@@ -583,13 +583,12 @@ x509_hash_enter(X509 *cert)
int
x509_read_from_dir(X509_STORE *ctx, char *name, int hash)
{
- struct dirent *file;
- struct monitor_dirents *dir;
FILE *certfp;
X509 *cert;
struct stat sb;
char fullname[PATH_MAX];
- int fd, off, size;
+ char file[PATH_MAX];
+ int fd;
if (strlen(name) >= sizeof fullname - 1) {
log_print("x509_read_from_dir: directory name too long");
@@ -598,34 +597,17 @@ x509_read_from_dir(X509_STORE *ctx, char *name, int hash)
LOG_DBG((LOG_CRYPTO, 40, "x509_read_from_dir: reading certs from %s",
name));
- dir = monitor_opendir(name);
- if (!dir) {
+ if (monitor_req_readdir(name) == -1) {
LOG_DBG((LOG_CRYPTO, 10,
"x509_read_from_dir: opendir (\"%s\") failed: %s",
name, strerror(errno)));
return 0;
}
- strlcpy(fullname, name, sizeof fullname);
- off = strlen(fullname);
- size = sizeof fullname - off;
-
- while ((file = monitor_readdir(dir)) != NULL) {
- strlcpy(fullname + off, file->d_name, size);
-
- if (file->d_type != DT_UNKNOWN) {
- if (file->d_type != DT_REG && file->d_type != DT_LNK)
- continue;
- }
+ while ((fd = monitor_readdir(file, sizeof file)) != -1) {
LOG_DBG((LOG_CRYPTO, 60,
"x509_read_from_dir: reading certificate %s",
- file->d_name));
-
- if ((fd = monitor_open(fullname, O_RDONLY, 0)) == -1) {
- log_error("x509_read_from_dir: monitor_open"
- "(\"%s\", O_RDONLY, 0) failed", fullname);
- continue;
- }
+ file));
if (fstat(fd, &sb) == -1) {
log_error("x509_read_from_dir: fstat failed");
@@ -653,7 +635,7 @@ x509_read_from_dir(X509_STORE *ctx, char *name, int hash)
if (cert == NULL) {
log_print("x509_read_from_dir: PEM_read_X509 "
- "failed for %s", file->d_name);
+ "failed for %s", file);
continue;
}
if (!X509_STORE_add_cert(ctx, cert)) {
@@ -665,17 +647,15 @@ x509_read_from_dir(X509_STORE *ctx, char *name, int hash)
*/
LOG_DBG((LOG_CRYPTO, 50,
"x509_read_from_dir: X509_STORE_add_cert failed "
- "for %s", file->d_name));
+ "for %s", file));
}
if (hash)
if (!x509_hash_enter(cert))
log_print("x509_read_from_dir: "
"x509_hash_enter (%s) failed",
- file->d_name);
+ file);
}
- monitor_closedir(dir);
-
return 1;
}
@@ -684,12 +664,11 @@ int
x509_read_crls_from_dir(X509_STORE *ctx, char *name)
{
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- struct dirent *file;
- struct monitor_dirents *dir;
FILE *crlfp;
X509_CRL *crl;
struct stat sb;
char fullname[PATH_MAX];
+ char file[PATH_MAX];
int fd, off, size;
if (strlen(name) >= sizeof fullname - 1) {
@@ -699,8 +678,7 @@ x509_read_crls_from_dir(X509_STORE *ctx, char *name)
LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs "
"from %s", name));
- dir = monitor_opendir(name);
- if (!dir) {
+ if (monitor_req_readdir(name) == -1) {
LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir "
"(\"%s\") failed: %s", name, strerror(errno)));
return 0;
@@ -709,22 +687,9 @@ x509_read_crls_from_dir(X509_STORE *ctx, char *name)
off = strlen(fullname);
size = sizeof fullname - off;
- while ((file = monitor_readdir(dir)) != NULL) {
- strlcpy(fullname + off, file->d_name, size);
-
- if (file->d_type != DT_UNKNOWN) {
- if (file->d_type != DT_REG && file->d_type != DT_LNK)
- continue;
- }
-
+ while ((fd = monitor_readdir(file, sizeof file)) != -1) {
LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading "
- "CRL %s", file->d_name));
-
- if ((fd = monitor_open(fullname, O_RDONLY, 0)) == -1) {
- log_error("x509_read_crls_from_dir: monitor_open"
- "(\"%s\", O_RDONLY, 0) failed", fullname);
- continue;
- }
+ "CRL %s", file));
if (fstat(fd, &sb) == -1) {
log_error("x509_read_crls_from_dir: fstat failed");
@@ -750,12 +715,12 @@ x509_read_crls_from_dir(X509_STORE *ctx, char *name)
if (crl == NULL) {
log_print("x509_read_crls_from_dir: "
"PEM_read_X509_CRL failed for %s",
- file->d_name);
+ file);
continue;
}
if (!X509_STORE_add_crl(ctx, crl)) {
LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: "
- "X509_STORE_add_crl failed for %s", file->d_name));
+ "X509_STORE_add_crl failed for %s", file));
continue;
}
/*
@@ -769,7 +734,6 @@ x509_read_crls_from_dir(X509_STORE *ctx, char *name)
X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
}
- monitor_closedir(dir);
#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
return 1;