[sgen] Remove skip_size in sgen-scan-object.h.
[mono.git] / mono / metadata / security.c
index 6601b5f4080b3fcf04c1d64b8c6248586a38f77d..c61eab99f7bf0e1ca51e417c4799a0223d39d807 100644 (file)
@@ -4,13 +4,14 @@
  * Author:
  *     Sebastien Pouliot  <sebastien@ximian.com>
  *
- * (C) 2004 Novell (http://www.novell.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <mono/metadata/assembly.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/image.h>
 #include <mono/metadata/exception.h>
@@ -20,7 +21,7 @@
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strenc.h>
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 
 #include <aclapi.h>
 #include <accctrl.h>
 
 #endif /* defined(__GNUC__) */
 
-#endif /* not PLATFORM_WIN32 */
+#endif /* not HOST_WIN32 */
 
 
 /* internal functions - reuse driven */
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 
 /* ask a server to translate a SID into a textual representation */
 static gunichar2*
@@ -112,7 +113,20 @@ GetSidName (gunichar2 *server, PSID sid, gint32 *size)
 }
 
 
-#else /* not PLATFORM_WIN32 */
+#else /* not HOST_WIN32 */
+
+#define MONO_SYSCONF_DEFAULT_SIZE      ((size_t) 1024)
+
+/*
+ * Ensure we always get a valid (usable) value from sysconf.
+ * In case of error, we return the default value.
+ */
+static size_t mono_sysconf (int name)
+{
+       size_t size = (size_t) sysconf (name);
+       /* default value */
+       return (size == -1) ? MONO_SYSCONF_DEFAULT_SIZE : size;
+}
 
 
 static gchar*
@@ -131,9 +145,9 @@ GetTokenName (uid_t uid)
 
 #ifdef HAVE_GETPWUID_R
 #ifdef _SC_GETPW_R_SIZE_MAX
-       fbufsize = (size_t) sysconf (_SC_GETPW_R_SIZE_MAX);
+       fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
 #else
-       fbufsize = (size_t) 1024;
+       fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
 #endif
        fbuf = g_malloc0 (fbufsize);
        retval = getpwuid_r (uid, &pwd, fbuf, fbufsize, &p);
@@ -197,9 +211,9 @@ IsDefaultGroup (uid_t user, gid_t group)
 
 #ifdef HAVE_GETPWUID_R
 #ifdef _SC_GETPW_R_SIZE_MAX
-       fbufsize = (size_t) sysconf (_SC_GETPW_R_SIZE_MAX);
+       fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
 #else
-       fbufsize = (size_t) 1024;
+       fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
 #endif
 
        fbuf = g_malloc0 (fbufsize);
@@ -243,19 +257,6 @@ IsMemberOf (gid_t user, struct group *g)
 /* ICALLS */
 
 
-/* System.Environment */
-
-
-MonoString*
-ves_icall_System_Environment_get_UserName (void)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       /* using glib is more portable */
-       return mono_string_new (mono_domain_get (), g_get_user_name ());
-}
-
-
 /* System.Security.Principal.WindowsIdentity */
 
 
@@ -266,7 +267,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
 
        MONO_ARCH_SAVE_REGS;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        /* Note: This isn't a copy of the Token - we must not close it!!!
         * http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
         */
@@ -277,7 +278,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
                OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token);
        }
 #else
-       token = (gpointer) geteuid ();
+       token = GINT_TO_POINTER (geteuid ());
 #endif
        return token;
 }
@@ -290,7 +291,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
        gunichar2 *uniname = NULL;
        gint32 size = 0;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        MONO_ARCH_SAVE_REGS;
 
        GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
@@ -302,7 +303,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
                g_free (tu);
        }
 #else 
-       gchar *uname = GetTokenName ((uid_t) token);
+       gchar *uname = GetTokenName ((uid_t) GPOINTER_TO_INT (token));
 
        MONO_ARCH_SAVE_REGS;
 
@@ -311,7 +312,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
                uniname = g_utf8_to_utf16 (uname, size, NULL, NULL, NULL);
                g_free (uname);
        }
-#endif /* PLATFORM_WIN32 */
+#endif /* HOST_WIN32 */
 
        if (size > 0) {
                result = mono_string_new_utf16 (mono_domain_get (), uniname, size);
@@ -329,7 +330,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
 gpointer
 ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *username)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        gpointer token = NULL;
 
        MONO_ARCH_SAVE_REGS;
@@ -340,7 +341,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *us
         */
        g_warning ("Unsupported on Win32 (anyway requires W2K3 minimum)");
 
-#else /* PLATFORM_WIN32*/
+#else /* HOST_WIN32*/
 
 #ifdef HAVE_GETPWNAM_R
        struct passwd pwd;
@@ -359,9 +360,9 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *us
 
 #ifdef HAVE_GETPWNAM_R
 #ifdef _SC_GETPW_R_SIZE_MAX
-       fbufsize = (size_t) sysconf (_SC_GETPW_R_SIZE_MAX);
+       fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
 #else
-       fbufsize = (size_t) 1024;
+       fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
 #endif
 
        fbuf = g_malloc0 (fbufsize);
@@ -374,7 +375,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *us
 #endif
 
        if (result) {
-               token = (gpointer) p->pw_uid;
+               token = GINT_TO_POINTER (p->pw_uid);
        }
 
 #ifdef HAVE_GETPWNAM_R
@@ -394,7 +395,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
 {
        MonoArray *array = NULL;
        MonoDomain *domain = mono_domain_get (); 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        gint32 size = 0;
 
        MONO_ARCH_SAVE_REGS;
@@ -414,7 +415,7 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
 
                                if (uniname) {
                                        MonoString *str = mono_string_new_utf16 (domain, uniname, size);
-                                       mono_array_set (array, MonoString *, i, str);
+                                       mono_array_setref (array, i, str);
                                        g_free (uniname);
                                }
                        }
@@ -443,7 +444,7 @@ ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken (gpoi
 
        MONO_ARCH_SAVE_REGS;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        result = (CloseHandle (token) != 0);
 #endif
        return result;
@@ -457,7 +458,7 @@ ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (
 
        MONO_ARCH_SAVE_REGS;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        if (DuplicateToken (token, SecurityImpersonation, &dupe) == 0) {
                dupe = NULL;
        }
@@ -495,13 +496,13 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer
 {
        gboolean result = FALSE;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        MONO_ARCH_SAVE_REGS;
 
        /* The convertion from an ID to a string is done in managed code for Windows */
        g_warning ("IsMemberOfGroupId should never be called on Win32");
 
-#else /* PLATFORM_WIN32 */
+#else /* HOST_WIN32 */
 
 #ifdef HAVE_GETGRGID_R
        struct group grp;
@@ -515,28 +516,28 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer
 
 #ifdef HAVE_GETGRGID_R
 #ifdef _SC_GETGR_R_SIZE_MAX
-       fbufsize = (size_t) sysconf (_SC_GETGR_R_SIZE_MAX);
+       fbufsize = mono_sysconf (_SC_GETGR_R_SIZE_MAX);
 #else
-       fbufsize = (size_t) 1024;
+       fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
 #endif
        fbuf = g_malloc0 (fbufsize);
-       retval = getgrgid_r ((gid_t) group, &grp, fbuf, fbufsize, &g);
+       retval = getgrgid_r ((gid_t) GPOINTER_TO_INT (group), &grp, fbuf, fbufsize, &g);
        result = ((retval == 0) && (g == &grp));
 #else
        /* default to non thread-safe but posix compliant function */
-       g = getgrgid ((gid_t) group);
+       g = getgrgid ((gid_t) GPOINTER_TO_INT (group));
        result = (g != NULL);
 #endif
 
        if (result) {
-               result = IsMemberOf ((uid_t) user, g);
+               result = IsMemberOf ((uid_t) GPOINTER_TO_INT (user), g);
        }
 
 #ifdef HAVE_GETGRGID_R
        g_free (fbuf);
 #endif
 
-#endif /* PLATFORM_WIN32 */
+#endif /* HOST_WIN32 */
 
        return result;
 }
@@ -547,14 +548,14 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
 {
        gboolean result = FALSE;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 
        MONO_ARCH_SAVE_REGS;
 
        /* Windows version use a cache built using WindowsIdentity._GetRoles */
        g_warning ("IsMemberOfGroupName should never be called on Win32");
 
-#else /* PLATFORM_WIN32 */
+#else /* HOST_WIN32 */
        gchar *utf8_groupname;
 
        MONO_ARCH_SAVE_REGS;
@@ -567,9 +568,9 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
                gchar *fbuf;
                gint32 retval;
 #ifdef _SC_GETGR_R_SIZE_MAX
-               size_t fbufsize = (size_t) sysconf (_SC_GETGR_R_SIZE_MAX);
+               size_t fbufsize = mono_sysconf (_SC_GETGR_R_SIZE_MAX);
 #else
-               size_t fbufsize = (size_t) 1024;
+               size_t fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
 #endif
                fbuf = g_malloc0 (fbufsize);
                retval = getgrnam_r (utf8_groupname, &grp, fbuf, fbufsize, &g);
@@ -581,7 +582,7 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
 #endif
 
                if (result) {
-                       result = IsMemberOf ((uid_t) user, g);
+                       result = IsMemberOf ((uid_t) GPOINTER_TO_INT (user), g);
                }
 
 #ifdef HAVE_GETGRNAM_R
@@ -589,7 +590,7 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
 #endif
                g_free (utf8_groupname);
        }
-#endif /* PLATFORM_WIN32 */
+#endif /* HOST_WIN32 */
 
        return result;
 }
@@ -597,7 +598,7 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
 
 /* Mono.Security.Cryptography IO related internal calls */
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 
 static PSID
 GetAdministratorsSid (void) 
@@ -846,13 +847,13 @@ Protect (MonoString *path, gint32 file_mode, gint32 add_dir_mode)
        return result;
 }
 
-#endif /* not PLATFORM_WIN32 */
+#endif /* not HOST_WIN32 */
 
 
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure (MonoString *root)
 {
-#if PLATFORM_WIN32
+#if HOST_WIN32
        gint32 flags;
 
        MONO_ARCH_SAVE_REGS;
@@ -877,7 +878,7 @@ ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected (Mono
        MONO_ARCH_SAVE_REGS;
 
        /* no one, but the owner, should have write access to the directory */
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        ret = IsMachineProtected (mono_string_chars (path));
 #else
        ret = IsProtected (path, (S_IWGRP | S_IWOTH));
@@ -894,7 +895,7 @@ ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected (MonoStr
        MONO_ARCH_SAVE_REGS;
 
        /* no one, but the user, should have access to the directory */
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        ret = IsUserProtected (mono_string_chars (path));
 #else
        ret = IsProtected (path, (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH));
@@ -911,7 +912,7 @@ ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine (MonoStri
        MONO_ARCH_SAVE_REGS;
 
        /* read/write to owner, read to everyone else */
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        ret = ProtectMachine (mono_string_chars (path));
 #else
        ret = Protect (path, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), (S_IXUSR | S_IXGRP | S_IXOTH));
@@ -928,7 +929,7 @@ ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser (MonoString
        MONO_ARCH_SAVE_REGS;
 
        /* read/write to user, no access to everyone else */
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        ret = ProtectUser (mono_string_chars (path));
 #else
        ret = Protect (path, (S_IRUSR | S_IWUSR), S_IXUSR);
@@ -951,3 +952,45 @@ ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent (MonoReflectionA
        }
        return FALSE;
 }
+
+
+/* System.Security.SecureString related internal calls */
+
+static MonoImage *system_security_assembly = NULL;
+
+void
+ves_icall_System_Security_SecureString_DecryptInternal (MonoArray *data, MonoObject *scope)
+{
+       invoke_protected_memory_method (data, scope, FALSE);
+}
+void
+ves_icall_System_Security_SecureString_EncryptInternal (MonoArray* data, MonoObject *scope)
+{
+       invoke_protected_memory_method (data, scope, TRUE);
+}
+
+void invoke_protected_memory_method (MonoArray *data, MonoObject *scope, gboolean encrypt)
+{
+       MonoClass *klass;
+       MonoMethod *method;
+       void *params [2];
+
+       MONO_ARCH_SAVE_REGS;
+
+       if (system_security_assembly == NULL) {
+               system_security_assembly = mono_image_loaded ("System.Security");
+               if (!system_security_assembly) {
+                       MonoAssembly *sa = mono_assembly_open ("System.Security.dll", NULL);
+                       if (!sa)
+                               g_assert_not_reached ();
+                       system_security_assembly = mono_assembly_get_image (sa);
+               }
+       }
+
+       klass = mono_class_from_name (system_security_assembly,
+                                                                 "System.Security.Cryptography", "ProtectedMemory");
+       method = mono_class_get_method_from_name (klass, encrypt ? "Protect" : "Unprotect", 2);
+       params [0] = data;
+       params [1] = scope; /* MemoryProtectionScope.SameProcess */
+       mono_runtime_invoke (method, NULL, params, NULL);
+}