diff options
author | Moritz Jodeit <moritz@cvs.openbsd.org> | 2005-05-28 17:42:51 +0000 |
---|---|---|
committer | Moritz Jodeit <moritz@cvs.openbsd.org> | 2005-05-28 17:42:51 +0000 |
commit | d4e8f7d27f6b9c6cb67a3ab79c29d355c919baf7 (patch) | |
tree | d555c03a2b3b267948ab0bd89d7566d15cf17ccf /sbin | |
parent | aad5afe1cb3ef150317b503b65ed62d342e6ad60 (diff) |
introduce new readdir implementation for the monitor.
testing and ok hshoexer@
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/isakmpd/monitor.c | 179 | ||||
-rw-r--r-- | sbin/isakmpd/monitor.h | 13 | ||||
-rw-r--r-- | sbin/isakmpd/x509.c | 66 |
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; |