Use ws_fstat64() to determine the size of an open file.

fseek() to the end, followed by ftell(), is a bit of an odd way to get
the file size.  Use ws_fstat64() instead.

Check that the file is a regular file, while we're at it.  This means we
don't have to check before opening.

Bug: 11268
Change-Id: I31ee20dd5568d10541375cf97b286abfc1384d1c
Reviewed-on: https://code.wireshark.org/review/9230
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2015-06-29 18:04:59 -07:00
parent 1e511d830e
commit 63a78d45bc
3 changed files with 37 additions and 35 deletions

View File

@ -3536,7 +3536,7 @@ ssl_load_key(FILE* fp)
*/
gnutls_x509_privkey_t priv_key;
gnutls_datum_t key;
long size;
ws_statb64 statbuf;
gint ret;
guint bytes;
@ -3545,24 +3545,33 @@ ssl_load_key(FILE* fp)
/* init private key data*/
gnutls_x509_privkey_init(&priv_key);
/* compute file size and load all file contents into a datum buffer*/
if (fseek(fp, 0, SEEK_END) < 0) {
ssl_debug_printf("ssl_load_key: can't fseek file\n");
if (ws_fstat64(fileno(fp), &statbuf) == -1) {
ssl_debug_printf("ssl_load_key: can't ws_fstat64 file\n");
g_free(private_key);
return NULL;
}
if ((size = ftell(fp)) < 0) {
ssl_debug_printf("ssl_load_key: can't ftell file\n");
if (S_ISDIR(statbuf.st_mode)) {
ssl_debug_printf("ssl_load_key: file is a directory\n");
g_free(private_key);
errno = EISDIR;
return NULL;
}
if (fseek(fp, 0, SEEK_SET) < 0) {
ssl_debug_printf("ssl_load_key: can't re-fseek file\n");
if (S_ISFIFO(statbuf.st_mode)) {
ssl_debug_printf("ssl_load_key: file is a named pipe\n");
g_free(private_key);
errno = EINVAL;
return NULL;
}
key.data = (unsigned char *)g_malloc(size);
key.size = (int)size;
if (!S_ISREG(statbuf.st_mode)) {
ssl_debug_printf("ssl_load_key: file is not a regular file\n");
g_free(private_key);
errno = EINVAL;
return NULL;
}
/* XXX - check for a too-big size */
/* load all file contents into a datum buffer*/
key.data = (unsigned char *)g_malloc((size_t)statbuf.st_size);
key.size = (int)statbuf.st_size;
bytes = (guint) fread(key.data, 1, key.size, fp);
if (bytes < key.size) {
ssl_debug_printf("ssl_load_key: can't read from file %d bytes, got %d\n",
@ -4407,12 +4416,6 @@ ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, GTree*
address_type addr_type[2] = { AT_IPv4, AT_IPv6 };
gchar* address_string;
/* ftell() open open directory is undefined, catch it earlier. */
if (test_for_directory(uats->keyfile) == EISDIR) {
report_open_failure(uats->keyfile, EISDIR, FALSE);
return;
}
/* try to load keys file first */
fp = ws_fopen(uats->keyfile, "rb");
if (!fp) {

View File

@ -40,6 +40,24 @@ extern "C" {
#include <sys/stat.h>
#endif
/*
* Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
* define them either.)
*
* Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
*/
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#ifndef S_IFIFO
#define S_IFIFO _S_IFIFO
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#ifdef _WIN32

View File

@ -194,25 +194,6 @@ get_dirname(char *path)
* to be a directory.
*/
/*
* Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
* define them either.)
*
* Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
*/
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#ifndef S_IFIFO
#define S_IFIFO _S_IFIFO
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
int
test_for_directory(const char *path)
{