summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/capabilities.c60
-rw-r--r--src/libstrongswan/utils/identification.c48
-rw-r--r--src/libstrongswan/utils/identification.h15
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_builtin.c3
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_builtin.h2
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_vstr.h2
-rw-r--r--src/libstrongswan/utils/utils.c107
-rw-r--r--src/libstrongswan/utils/utils/string.c2
8 files changed, 190 insertions, 49 deletions
diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c
index 923b7d4db..ce5f550b5 100644
--- a/src/libstrongswan/utils/capabilities.c
+++ b/src/libstrongswan/utils/capabilities.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
@@ -288,13 +288,25 @@ METHOD(capabilities_t, resolve_uid, bool,
#ifdef HAVE_GETPWNAM_R
struct passwd passwd;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- err = getpwnam_r(username, &passwd, buf, sizeof(buf), &pwp);
- if (pwp)
+ while (TRUE)
{
- this->uid = pwp->pw_uid;
+ buf = realloc(buf, buflen);
+ err = getpwnam_r(username, &passwd, buf, buflen, &pwp);
+ if (err == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (pwp)
+ {
+ this->uid = pwp->pw_uid;
+ }
+ break;
}
+ free(buf);
#else /* HAVE GETPWNAM_R */
this->mutex->lock(this->mutex);
pwp = getpwnam(username);
@@ -324,13 +336,25 @@ METHOD(capabilities_t, resolve_gid, bool,
#ifdef HAVE_GETGRNAM_R
struct group group;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- err = getgrnam_r(groupname, &group, buf, sizeof(buf), &grp);
- if (grp)
+ while (TRUE)
{
- this->gid = grp->gr_gid;
+ buf = realloc(buf, buflen);
+ err = getgrnam_r(groupname, &group, buf, buflen, &grp);
+ if (err == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (grp)
+ {
+ this->gid = grp->gr_gid;
+ }
+ break;
}
+ free(buf);
#else /* HAVE_GETGRNAM_R */
this->mutex->lock(this->mutex);
grp = getgrnam(groupname);
@@ -362,12 +386,24 @@ static bool init_supplementary_groups(private_capabilities_t *this)
#ifdef HAVE_GETPWUID_R
struct passwd pwd;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- if (getpwuid_r(this->uid, &pwd, buf, sizeof(buf), &pwp) == 0 && pwp)
+ while (TRUE)
{
- res = initgroups(pwp->pw_name, this->gid);
+ buf = realloc(buf, buflen);
+ if (getpwuid_r(this->uid, &pwd, buf, buflen, &pwp) == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (pwp)
+ {
+ res = initgroups(pwp->pw_name, this->gid);
+ }
+ break;
}
+ free(buf);
#else /* HAVE_GETPWUID_R */
this->mutex->lock(this->mutex);
pwp = getpwuid(this->uid);
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index b69adf399..da23d143c 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -47,10 +47,9 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_DER_ASN1_DN",
"ID_DER_ASN1_GN",
"ID_KEY_ID");
-ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_USER_ID, ID_KEY_ID,
- "ID_DER_ASN1_GN_URI",
- "ID_USER_ID");
-ENUM_END(id_type_names, ID_USER_ID);
+ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID,
+ "ID_DER_ASN1_GN_URI");
+ENUM_END(id_type_names, ID_DER_ASN1_GN_URI);
/**
* coding of X.501 distinguished name
@@ -478,7 +477,7 @@ static status_t atodn(char *src, chunk_t *dn)
name.len -= whitespace;
rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING
&& !asn1_is_printablestring(name))
- ? ASN1_T61STRING : x501rdns[i].type;
+ ? ASN1_UTF8STRING : x501rdns[i].type;
if (rdn_count < RDN_MAX)
{
@@ -579,6 +578,19 @@ METHOD(identification_t, contains_wildcards_memchr, bool,
return memchr(this->encoded.ptr, '*', this->encoded.len) != NULL;
}
+METHOD(identification_t, hash_binary, u_int,
+ private_identification_t *this, u_int inc)
+{
+ u_int hash;
+
+ hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
+ if (this->type != ID_ANY)
+ {
+ hash = chunk_hash_inc(this->encoded, hash);
+ }
+ return hash;
+}
+
METHOD(identification_t, equals_binary, bool,
private_identification_t *this, identification_t *other)
{
@@ -687,6 +699,24 @@ METHOD(identification_t, equals_dn, bool,
return compare_dn(this->encoded, other->get_encoding(other), NULL);
}
+METHOD(identification_t, hash_dn, u_int,
+ private_identification_t *this, u_int inc)
+{
+ enumerator_t *rdns;
+ chunk_t oid, data;
+ u_char type;
+ u_int hash;
+
+ hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
+ rdns = create_rdn_enumerator(this->encoded);
+ while (rdns->enumerate(rdns, &oid, &type, &data))
+ {
+ hash = chunk_hash_inc(data, chunk_hash_inc(oid, hash));
+ }
+ rdns->destroy(rdns);
+ return hash;
+}
+
METHOD(identification_t, equals_strcasecmp, bool,
private_identification_t *this, identification_t *other)
{
@@ -828,7 +858,6 @@ int identification_printf_hook(printf_hook_data_t *data,
case ID_FQDN:
case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI:
- case ID_USER_ID:
chunk_printable(this->encoded, &proper, '?');
snprintf(buf, sizeof(buf), "%.*s", (int)proper.len, proper.ptr);
chunk_free(&proper);
@@ -903,23 +932,26 @@ static private_identification_t *identification_create(id_type_t type)
switch (type)
{
case ID_ANY:
+ this->public.hash = _hash_binary;
this->public.matches = _matches_any;
this->public.equals = _equals_binary;
this->public.contains_wildcards = return_true;
break;
case ID_FQDN:
case ID_RFC822_ADDR:
- case ID_USER_ID:
+ this->public.hash = _hash_binary;
this->public.matches = _matches_string;
this->public.equals = _equals_strcasecmp;
this->public.contains_wildcards = _contains_wildcards_memchr;
break;
case ID_DER_ASN1_DN:
+ this->public.hash = _hash_dn;
this->public.equals = _equals_dn;
this->public.matches = _matches_dn;
this->public.contains_wildcards = _contains_wildcards_dn;
break;
default:
+ this->public.hash = _hash_binary;
this->public.equals = _equals_binary;
this->public.matches = _matches_binary;
this->public.contains_wildcards = return_false;
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index e6a9fe1c6..5f27ba112 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -129,11 +129,6 @@ enum id_type_t {
* Private ID type which represents a GeneralName of type URI
*/
ID_DER_ASN1_GN_URI = 201,
-
- /**
- * Private ID type which represents a user ID
- */
- ID_USER_ID = 202
};
/**
@@ -219,6 +214,14 @@ struct identification_t {
id_type_t (*get_type) (identification_t *this);
/**
+ * Create a hash value for this identification_t object.
+ *
+ * @param inc optional value for incremental hashing
+ * @return hash value
+ */
+ u_int (*hash) (identification_t *this, u_int inc);
+
+ /**
* Check if two identification_t objects are equal.
*
* @param other other identification_t object
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
index 466c673d9..af5494052 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
@@ -843,7 +843,8 @@ int builtin_vsnprintf(char *buffer, size_t n, const char *format, va_list ap)
/* String */
sarg = va_arg(ap, const char *);
sarg = sarg ? sarg : "(null)";
- slen = strlen(sarg);
+ slen = prec != -1 ? strnlen(sarg, prec)
+ : strlen(sarg);
goto is_string;
}
case 'm':
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
index 409b5bf3d..efbacff6f 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
@@ -15,7 +15,7 @@
/**
* @defgroup printf_hook_builtin printf_hook_builtin
- * @{ @ingroup utils
+ * @{ @ingroup printf_hook
*/
#ifndef PRINTF_HOOK_BUILTIN_H_
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h b/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
index 2f9ee5983..7c24b05e2 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
@@ -16,7 +16,7 @@
/**
* @defgroup printf_hook_vstr printf_hook_vstr
- * @{ @ingroup utils
+ * @{ @ingroup printf_hook
*/
#ifndef PRINTF_HOOK_VSTR_H_
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c
index 9b516accd..b4a4db802 100644
--- a/src/libstrongswan/utils/utils.c
+++ b/src/libstrongswan/utils/utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2014 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -16,15 +16,38 @@
#include "utils.h"
+#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
+#include <ctype.h>
#ifndef WIN32
# include <signal.h>
#endif
+#ifndef HAVE_CLOSEFROM
+#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <sys/syscall.h>
+/* This is from the kernel sources. We limit the length of directory names to
+ * 256 as we only use it to enumerate FDs. */
+struct linux_dirent64 {
+ u_int64_t d_ino;
+ int64_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+};
+#else /* !defined(__linux__) || !defined(HAVE_SYS_SYSCALL_H) */
+# include <dirent.h>
+#endif /* defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) */
+#endif
+
#include <library.h>
#include <collections/enumerator.h>
+#define FD_DIR "/proc/self/fd"
+
#ifdef WIN32
#include <threading/mutex.h>
@@ -110,43 +133,89 @@ void wait_sigint()
/**
* Described in header.
*/
-void closefrom(int lowfd)
+void closefrom(int low_fd)
{
- char fd_dir[PATH_MAX];
- int maxfd, fd, len;
+ int max_fd, dir_fd, fd;
/* try to close only open file descriptors on Linux... */
- len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
- if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
+#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+ /* By directly using a syscall we avoid any calls that might be unsafe after
+ * fork() (e.g. malloc()). */
+ char buffer[sizeof(struct linux_dirent64)];
+ struct linux_dirent64 *entry;
+ int offset, len;
+
+ dir_fd = open("/proc/self/fd", O_RDONLY);
+ if (dir_fd != -1)
{
- enumerator_t *enumerator = enumerator_create_directory(fd_dir);
- if (enumerator)
+ while ((len = syscall(SYS_getdents64, dir_fd, buffer,
+ sizeof(buffer))) > 0)
{
- char *rel;
- while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
+ for (offset = 0; offset < len; offset += entry->d_reclen)
{
- fd = atoi(rel);
- if (fd >= lowfd)
+ entry = (struct linux_dirent64*)(buffer + offset);
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+ fd = atoi(entry->d_name);
+ if (fd != dir_fd && fd >= low_fd)
{
close(fd);
}
}
- enumerator->destroy(enumerator);
- return;
}
+ close(dir_fd);
+ return;
+ }
+#else /* !defined(__linux__) || !defined(HAVE_SYS_SYSCALL_H) */
+ /* This is potentially unsafe when called after fork() in multi-threaded
+ * applications. In particular opendir() will require an allocation.
+ * Depends on how the malloc() implementation handles such situations. */
+ DIR *dir;
+ struct dirent *entry;
+
+#ifndef HAVE_DIRFD
+ /* if we don't have dirfd() lets close the lowest FD and hope it gets reused
+ * by opendir() */
+ close(low_fd);
+ dir_fd = low_fd++;
+#endif
+
+ dir = opendir(FD_DIR);
+ if (dir)
+ {
+#ifdef HAVE_DIRFD
+ dir_fd = dirfd(dir);
+#endif
+ while ((entry = readdir(dir)))
+ {
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+ fd = atoi(entry->d_name);
+ if (fd != dir_fd && fd >= low_fd)
+ {
+ close(fd);
+ }
+ }
+ closedir(dir);
+ return;
}
+#endif /* defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) */
/* ...fall back to closing all fds otherwise */
#ifdef WIN32
- maxfd = _getmaxstdio();
+ max_fd = _getmaxstdio();
#else
- maxfd = (int)sysconf(_SC_OPEN_MAX);
+ max_fd = (int)sysconf(_SC_OPEN_MAX);
#endif
- if (maxfd < 0)
+ if (max_fd < 0)
{
- maxfd = 256;
+ max_fd = 256;
}
- for (fd = lowfd; fd < maxfd; fd++)
+ for (fd = low_fd; fd < max_fd; fd++)
{
close(fd);
}
diff --git a/src/libstrongswan/utils/utils/string.c b/src/libstrongswan/utils/utils/string.c
index 14087e765..56910ed79 100644
--- a/src/libstrongswan/utils/utils/string.c
+++ b/src/libstrongswan/utils/utils/string.c
@@ -44,7 +44,7 @@ char* translate(char *str, const char *from, const char *to)
char* strreplace(const char *str, const char *search, const char *replace)
{
size_t len, slen, rlen, count = 0;
- char *res, *pos, *found, *dst;
+ char *res, *pos, *found = NULL, *dst;
if (!str || !*str || !search || !*search || !replace)
{