On February 3, 2010 at 15:23, Valdis(_dot_)Kletnieks(_at_)vt(_dot_)edu wrote:
Given that the vast majority of nmh users are probably on laptops or
single-user desktop boxes rather than large central servers with untrusted
other users on them, and your code *is* an improvement, I think the best
thing to do is drop in your patches, leave a TO_DO comment block in there
about what's still needed, and we revisit it if it ever becomes an issue.
Okay.
I did make some more mods to m_mktemp.c to make things a bit more
secure and to support specifying the temporary directory via
envvars. See comments in code for more details.
/*
* m_mktemp.c -- Construct a temporary file.
*
* $Id: m_mktemp.c,v 1.4 2002/07/02 22:09:14 kenh Exp $
*
* This code is Copyright (c) 2010, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
*/
#include <errno.h>
#include <h/mh.h>
static char *get_temp_dir();
/* Create a temporary file. If pfx_in is null, the temporary file
* will be created in the temporary directory (more on that later).
* If pfx_in is not null, then the temporary file location will be
* defined by the value pfx_in.
*
* The file created will be at the pathname specified appended with
* 6 random (we hope :) characters.
*
* The return value will be the pathname to the file created.
*
* CAUTION: The return pointer references static data. If
* you need to modify, or save, the return string, make a copy of it
* first.
*
* When pfx_in is null, the temporary directory is determined as
* follows, in order:
*
* MHTMPDIR envvar
* TMPDIR envvar
* TMP envvar
* User's mail directory.
*
* NOTE: One will probably use m_mktemp2() instead of this function.
* For example, if you want to create a temp file in the defined
* temporary directory, but with a custom basename prefix, do
* something like the following:
*
* char *tmp_pathname = m_mktemp2(NULL, "mypre", ...);
*/
char *
m_mktemp (
const char *pfx_in, /* Pathname prefix for temporary file. */
int *fd_ret, /* (return,optional) File descriptor to temp file. */
FILE **fp_ret /* (return,optional) FILE pointer to temp file. */
)
{
static char tmpfil[BUFSIZ];
int fd = -1;
int keep_open = 0;
mode_t oldmode = umask(077);
if (pfx_in == NULL) {
snprintf(tmpfil, sizeof(tmpfil), "%s/nmhXXXXXX", get_temp_dir());
} else {
snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx_in);
}
fd = mkstemp(tmpfil);
if (fd < 0) {
umask(oldmode);
return NULL;
}
if (fd_ret != NULL) {
*fd_ret = fd;
keep_open = 1;
}
if (fp_ret != NULL) {
FILE *fp = fdopen(fd, "w+");
if (fp == NULL) {
int olderr = errno;
unlink(tmpfil);
close(fd);
errno = olderr;
umask(oldmode);
return NULL;
}
*fp_ret = fp;
keep_open = 1;
}
if (!keep_open) {
close(fd);
}
umask(oldmode);
return tmpfil;
}
/* This version allows one to specify the directory the temp file should
* by created based on a given pathname. Although m_mktemp() technically
* supports this, this version is when the directory is defined by
* a separate variable from the prefix, eliminating the caller from having
* to do string manipulation to generate the desired. pathname prefix.
*
* The pfx_in parameter specifies a basename prefix for the file. If dir_in
* is NULL, then the defined temporary directory (see comments to m_mktemp()
* above) is used to create the temp file.
*/
char *
m_mktemp2 (
const char *dir_in, /* Directory to place temp file. */
const char *pfx_in, /* Basename prefix for temp file. */
int *fd_ret, /* (return,optional) File descriptor to temp file. */
FILE **fp_ret /* (return,optional) FILE pointer to temp file. */
)
{
static char buffer[BUFSIZ];
char *cp;
if (dir_in == NULL) {
if (pfx_in == NULL) {
return m_mktemp(NULL, fd_ret, fp_ret);
}
snprintf(buffer, sizeof(buffer), "%s/%s", get_temp_dir(), pfx_in);
return m_mktemp(buffer, fd_ret, fp_ret);
}
if ((cp = r1bindex ((char *)dir_in, '/')) == dir_in) {
/* No directory component */
return m_mktemp(pfx_in, fd_ret, fp_ret);
}
int n = (int)(cp-dir_in-1); /* Length of dir component */
snprintf(buffer, sizeof(buffer), "%.*s%s", n, dir_in, pfx_in);
return m_mktemp(buffer, fd_ret, fp_ret);
}
static char *
get_temp_dir()
{
// Ignore envvars if we are setuid
if ((getuid()==geteuid()) && (getgid()==getegid())) {
char *tmpdir = NULL;
tmpdir = getenv("MHTMPDIR");
if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
tmpdir = getenv("TMPDIR");
if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
tmpdir = getenv("TMP");
if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
}
return m_maildir("");
}
_______________________________________________
Nmh-workers mailing list
Nmh-workers(_at_)nongnu(_dot_)org
http://lists.nongnu.org/mailman/listinfo/nmh-workers