summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--ace/Hash_Map_Manager_T.h1
-rw-r--r--ace/Map_Manager.h1
-rw-r--r--ace/OS_NS_stdlib.cpp152
-rw-r--r--ace/OS_NS_stdlib.h7
-rw-r--r--ace/OS_NS_stdlib.inl17
-rw-r--r--ace/RB_Tree.h1
7 files changed, 168 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 29ada312752..8d6e68b3f36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+Fri Oct 1 23:30:06 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * ace/OS_NS_stdlib.h (mkstemp, mkstemp_emulation):
+ * ace/OS_NS_stdlib.inl (mkstemp):
+ * ace/OS_NS_stdlib.cpp (mkstemp_emulation):
+
+ Added new mkstemp(3) implementation for the case where
+ ACE_LACKS_MKSTEMP is defined. It attempts to retain all of the
+ security features that vendor supplied mkstemp() implementation
+ provide, such as preventing symbolic link attacks. A race
+ condition, however, may exist when attempting to use this
+ implementation to create a temporary file on a network
+ filesystem.
+
+ ACE_OS::mkstemp() is now available when ACE_LACKS_MKSTEMP is
+ defined.
+
+ From Ganesh Pai <GPai at sonusnet dot com>
+ * ace/Hash_Map_Manager_T.h:
+ * ace/Map_Manager.h:
+ * ace/RB_Tree.h:
+
+ Added new "lock_type" type trait. Allows one to more easily
+ determine the type of the underlying map/table lock.
+
Fri Oct 1 11:54:17 MST 2004 Trevor Fields <fields_t@ociweb.com>
* bin/MakeProjectCreator/config/messaging.mpb:
@@ -532,15 +557,10 @@ Fri Sep 24 22:35:25 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
New ICMP and "ping" support, and accompanying test.
-<<<<<<< ChangeLog
* ace/Makefile.am (libACE_Sockets_la_SOURCES):
* ace/ace.mpc:
* tests/Makefile.am:
* tests/tests.mpc:
-=======
- * ace/ace.mpc:
- * tests/tests.mpc:
->>>>>>> 4.7677
Added new ICMP and "ping" source files to the appropriate
source lists.
diff --git a/ace/Hash_Map_Manager_T.h b/ace/Hash_Map_Manager_T.h
index f71b71fd3b1..eefd5862f89 100644
--- a/ace/Hash_Map_Manager_T.h
+++ b/ace/Hash_Map_Manager_T.h
@@ -120,6 +120,7 @@ public:
KEY;
typedef INT_ID
VALUE;
+ typedef ACE_LOCK lock_type;
typedef ACE_Hash_Map_Entry<EXT_ID, INT_ID>
ENTRY;
diff --git a/ace/Map_Manager.h b/ace/Map_Manager.h
index 79af0088240..1cf39698914 100644
--- a/ace/Map_Manager.h
+++ b/ace/Map_Manager.h
@@ -133,6 +133,7 @@ public:
// = Traits.
typedef EXT_ID KEY;
typedef INT_ID VALUE;
+ typedef ACE_LOCK lock_type;
typedef ACE_Map_Entry<EXT_ID, INT_ID> ENTRY;
typedef ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK> ITERATOR;
typedef ACE_Map_Const_Iterator<EXT_ID, INT_ID, ACE_LOCK> CONST_ITERATOR;
diff --git a/ace/OS_NS_stdlib.cpp b/ace/OS_NS_stdlib.cpp
index 70bb0e13bd5..5cda64ad7df 100644
--- a/ace/OS_NS_stdlib.cpp
+++ b/ace/OS_NS_stdlib.cpp
@@ -1,9 +1,10 @@
-// -*- C++ -*-
// $Id$
#include "ace/OS_NS_stdlib.h"
-ACE_RCSID(ace, OS_NS_stdlib, "$Id$")
+ACE_RCSID (ace,
+ OS_NS_stdlib,
+ "$Id$")
#if !defined (ACE_HAS_INLINED_OSCALLS)
# include "ace/OS_NS_stdlib.inl"
@@ -13,10 +14,19 @@ ACE_RCSID(ace, OS_NS_stdlib, "$Id$")
#include "ace/OS_NS_unistd.h"
-#if defined (ACE_LACKS_MKTEMP) || defined (ACE_LACKS_REALPATH)
+#if defined (ACE_LACKS_MKTEMP) \
+ || defined (ACE_LACKS_MKSTEMP) \
+ || defined (ACE_LACKS_REALPATH)
# include "ace/OS_NS_stdio.h"
# include "ace/OS_NS_sys_stat.h"
-#endif /* ACE_LACKS_MKTEMP || ACE_LACKS_REALPATH */
+#endif /* ACE_LACKS_MKTEMP || ACE_LACKS_MKSTEMP || ACE_LACKS_REALPATH */
+
+#if defined (ACE_LACKS_MKSTEMP)
+# include "ace/OS_fcntl.h"
+# include "ace/OS_NS_sys_time.h"
+
+# include <limits>
+#endif /* ACE_LACKS_MKSTEMP */
ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0;
@@ -265,7 +275,7 @@ ACE_OS::realpath (const char *file_name,
char *resolved_name)
{
ACE_OS_TRACE ("ACE_OS::realpath");
-
+
if (file_name == 0)
{
// Single Unix Specification V3:
@@ -332,7 +342,7 @@ ACE_OS::realpath (const char *file_name,
// Skip multiple separators
while (*file_name == '/')
- ++file_name;
+ ++file_name;
char* start = dest;
@@ -366,7 +376,7 @@ ACE_OS::realpath (const char *file_name,
while (*--dest != '/')
;
}
-# if !defined (ACE_LACKS_SYMLINKS)
+# if !defined (ACE_LACKS_SYMLINKS)
else
{
ACE_stat st;
@@ -383,12 +393,12 @@ ACE_OS::realpath (const char *file_name,
if (S_ISLNK (st.st_mode))
{
if (++nlinks > MAXSYMLINKS)
- {
- errno = ELOOP;
- if (resolved_name == 0)
- ACE_OS::free (rpath);
- return 0;
- }
+ {
+ errno = ELOOP;
+ if (resolved_name == 0)
+ ACE_OS::free (rpath);
+ return 0;
+ }
char link_buf[PATH_MAX];
@@ -397,31 +407,32 @@ ACE_OS::realpath (const char *file_name,
// Check if there is room to expand link?
if (link_len + tail_len > PATH_MAX)
- {
- errno = ENAMETOOLONG;
- if (resolved_name == 0)
- ACE_OS::free (rpath);
- return 0;
- }
+ {
+ errno = ENAMETOOLONG;
+ if (resolved_name == 0)
+ ACE_OS::free (rpath);
+ return 0;
+ }
// Move tail and prefix it with expanded link
ACE_OS::memmove (expand_buf + link_len, file_name, tail_len);
ACE_OS::memcpy (expand_buf, link_buf, link_len);
if (*link_buf == '/') // Absolute link?
- {
- dest = rpath;
- }
+ {
+ dest = rpath;
+ }
else // Relative link, remove expanded link component
- {
- --dest;
- while (*--dest != '/')
- ;
- }
+ {
+ --dest;
+ while (*--dest != '/')
+ ;
+ }
file_name = expand_buf; // Source path is now in expand_buf
}
+ }
}
-# endif /* ACE_LACKS_SYMLINKS */
+# endif /* ACE_LACKS_SYMLINKS */
}
*dest = '\0';
@@ -578,3 +589,88 @@ ACE_OS::strtoul_emulation (const char *nptr,
}
#endif /* ACE_LACKS_STRTOUL */
+
+#if defined (ACE_LACKS_MKSTEMP)
+ACE_HANDLE
+ACE_OS::mkstemp_emulation (ACE_TCHAR * s)
+{
+ if (s == 0)
+ {
+ errno = EINVAL;
+ return ACE_INVALID_HANDLE;
+ }
+
+ // The "XXXXXX" template to be filled in.
+ ACE_TCHAR * const t = ACE_OS::strstr (s, ACE_TEXT ("XXXXXX"));
+
+ if (t == 0)
+ {
+ errno = EINVAL;
+ return ACE_INVALID_HANDLE;
+ }
+
+ static unsigned int const NUM_RETRIES = 50;
+ static unsigned int const NUM_CHARS = 6; // Do not change!
+
+ ACE_RANDR_TYPE const seed =
+ static_cast<ACE_RANDR_TYPE> (ACE_OS::gettimeofday ().msec ());
+
+ static ACE_TCHAR const MAX_VAL =
+ std::numeric_limits<ACE_TCHAR>::max ();
+
+ // Use high-order bits rather than low-order ones (e.g. rand() %
+ // MAX_VAL). See Numerical Recipes in C: The Art of Scientific
+ // Computing (William H. Press, Brian P. Flannery, Saul
+ // A. Teukolsky, William T. Vetterling; New York: Cambridge
+ // University Press, 1992 (2nd ed., p. 277).
+ //
+ // e.g.: MAX_VAL * rand() / (RAND_MAX + 1.0)
+
+ // Factor out the constant coefficient.
+ static float const coefficient =
+ static_cast<float> (MAX_VAL) / (RAND_MAX + 1.0);
+
+ // @@ These nested loops may be ineffecient. Improvements are
+ // welcome.
+ for (unsigned int i = 0; i < NUM_RETRIES; ++i)
+ {
+ for (unsigned int n = 0; n < NUM_CHARS; ++n)
+ {
+ ACE_TCHAR r;
+
+ // This do/while() loop allows this alphanumeric character
+ // selection to work for EBCDIC, as well.
+ do
+ {
+ r =
+ static_cast<ACE_TCHAR> (coefficient * ACE_OS::rand_r (&seed));
+ }
+ while (!ACE_OS::ace_isalnum (r));
+
+ t[n] = r;
+ }
+
+ static int const perms =
+#if defined (ACE_WIN32)
+ 0; /* Do not share while open. */
+#else
+ 0600; /* S_IRUSR | S_IWUSR */
+#endif /* ACE_WIN32 */
+
+ // Create the file with the O_EXCL bit set to ensure that we're
+ // not subject to a symbolic link attack.
+ //
+ // Note that O_EXCL is subject to a race condition over NFS
+ // filesystems.
+ ACE_HANDLE const handle = ACE_OS::open (s,
+ O_RDWR | O_CREAT | O_EXCL,
+ perms);
+
+ if (handle != ACE_INVALID_HANDLE)
+ return handle;
+ }
+
+ errno = EEXIST; // Couldn't create a unique temporary file.
+ return ACE_INVALID_HANDLE;
+}
+#endif /* ACE_LACKS_MKSTEMP */
diff --git a/ace/OS_NS_stdlib.h b/ace/OS_NS_stdlib.h
index 987dc4ddfe8..38fcd9e9187 100644
--- a/ace/OS_NS_stdlib.h
+++ b/ace/OS_NS_stdlib.h
@@ -144,7 +144,6 @@ namespace ACE_OS {
extern ACE_Export
void *malloc (size_t);
-#if !defined (ACE_LACKS_MKSTEMP)
ACE_NAMESPACE_INLINE_FUNCTION
ACE_HANDLE mkstemp (char *s);
@@ -152,7 +151,11 @@ namespace ACE_OS {
ACE_NAMESPACE_INLINE_FUNCTION
ACE_HANDLE mkstemp (wchar_t *s);
# endif /* ACE_HAS_WCHAR */
-#endif /* !ACE_LACKS_MKSTEMP */
+
+#if defined (ACE_LACKS_MKSTEMP)
+ extern ACE_Export
+ ACE_HANDLE mkstemp_emulation (ACE_TCHAR * s);
+#endif /* ACE_LACKS_MKSTEMP */
#if !defined (ACE_LACKS_MKTEMP)
ACE_NAMESPACE_INLINE_FUNCTION
diff --git a/ace/OS_NS_stdlib.inl b/ace/OS_NS_stdlib.inl
index 0f067ccbe5b..6fdc58fddfc 100644
--- a/ace/OS_NS_stdlib.inl
+++ b/ace/OS_NS_stdlib.inl
@@ -174,22 +174,27 @@ ACE_OS::itoa (int value, wchar_t *string, int radix)
}
#endif /* ACE_HAS_WCHAR */
-#if !defined (ACE_LACKS_MKSTEMP)
ACE_INLINE ACE_HANDLE
ACE_OS::mkstemp (char *s)
{
+#if !defined (ACE_LACKS_MKSTEMP)
return ::mkstemp (s);
+#else
+ return ACE_OS::mkstemp_emulation (ACE_TEXT_CHAR_TO_TCHAR (s));
+#endif /* !ACE_LACKS_MKSTEMP */
}
-# if defined (ACE_HAS_WCHAR)
+#if defined (ACE_HAS_WCHAR)
ACE_INLINE ACE_HANDLE
ACE_OS::mkstemp (wchar_t *s)
{
- ACE_Wide_To_Ascii narrow_s (s);
- return ::mkstemp (narrow_s.char_rep ());
+# if !defined (ACE_LACKS_MKSTEMP)
+ return ::mkstemp (ACE_TEXT_WCHAR_TO_TCHAR (ACE_TEXT_ALWAYS_CHAR (s)));
+# else
+ return ACE_OS::mkstemp_emulation (ACE_TEXT_WCHAR_TO_TCHAR (s));
+# endif /* !ACE_LACKS_MKSTEMP */
}
-# endif /* ACE_HAS_WCHAR */
-#endif /* !ACE_LACKS_MKSTEMP */
+#endif /* ACE_HAS_WCHAR */
#if !defined (ACE_LACKS_MKTEMP)
ACE_INLINE char *
diff --git a/ace/RB_Tree.h b/ace/RB_Tree.h
index e2ba71cee94..121b0731cfc 100644
--- a/ace/RB_Tree.h
+++ b/ace/RB_Tree.h
@@ -193,6 +193,7 @@ public:
typedef EXT_ID KEY;
typedef INT_ID VALUE;
+ typedef ACE_LOCK lock_type;
typedef ACE_RB_Tree_Node<EXT_ID, INT_ID> ENTRY;
// = ACE-style iterator typedefs.