http: Allow overriding of the Host header.
[gnupg.git] / common / sysutils.c
index 82d9959..afb12ed 100644 (file)
@@ -1,15 +1,26 @@
 /* sysutils.c -  system helpers
  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
  *               2007, 2008  Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -20,9 +31,9 @@
 
 #include <config.h>
 
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-# undef HAVE_PTH
-# undef USE_GNU_PTH
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+# undef HAVE_NPTH
+# undef USE_NPTH
 #endif
 
 #include <stdio.h>
 # include <sys/resource.h>
 #endif
 #ifdef HAVE_W32_SYSTEM
-# define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
+# if WINVER < 0x0500
+#   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
+# endif
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
 # include <windows.h>
 #endif
-#ifdef HAVE_PTH      
-# include <pth.h>
+#ifdef HAVE_NPTH
+# include <npth.h>
 #endif
 #include <fcntl.h>
 
@@ -140,7 +156,7 @@ get_session_marker (size_t *rlen)
 {
   static byte marker[SIZEOF_UNSIGNED_LONG*2];
   static int initialized;
-  
+
   if (!initialized)
     {
       gcry_create_nonce (marker, sizeof marker);
@@ -150,6 +166,17 @@ get_session_marker (size_t *rlen)
   return marker;
 }
 
+/* Return a random number in an unsigned int. */
+unsigned int
+get_uint_nonce (void)
+{
+  unsigned int value;
+
+  gcry_create_nonce (&value, sizeof value);
+  return value;
+}
+
+
 
 #if 0 /* not yet needed - Note that this will require inclusion of
          cmacros.am in Makefile.am */
@@ -248,21 +275,11 @@ check_permissions(const char *path,int extension,int checkonly)
 void
 gnupg_sleep (unsigned int seconds)
 {
-#ifdef HAVE_PTH
-  /* With Pth we force a regular sleep for seconds == 0 so that also
-     the process will give up its timeslot.  */
-  if (!seconds)
-    {
-# ifdef HAVE_W32_SYSTEM    
-      Sleep (0);
-# else
-      sleep (0);
-# endif
-    }
-  pth_sleep (seconds);
+#ifdef USE_NPTH
+  npth_sleep (seconds);
 #else
   /* Fixme:  make sure that a sleep won't wake up to early.  */
-# ifdef HAVE_W32_SYSTEM    
+# ifdef HAVE_W32_SYSTEM
   Sleep (seconds*1000);
 # else
   sleep (seconds);
@@ -287,7 +304,7 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
 
   if (fd == GNUPG_INVALID_FD)
     return -1;
-  
+
   /* Note that _open_osfhandle is currently defined to take and return
      a long.  */
   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
@@ -437,7 +454,7 @@ gnupg_tmpfile (void)
    Must be called before we open any files! */
 void
 gnupg_reopen_std (const char *pgmname)
-{  
+{
 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
   struct stat statbuf;
   int did_stdin = 0;
@@ -452,7 +469,7 @@ gnupg_reopen_std (const char *pgmname)
       else
        did_stdin = 2;
     }
-  
+
   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
     {
       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
@@ -501,7 +518,7 @@ gnupg_reopen_std (const char *pgmname)
 
 
 /* Hack required for Windows.  */
-void 
+void
 gnupg_allow_set_foregound_window (pid_t pid)
 {
   if (!pid)
@@ -530,8 +547,8 @@ gnupg_remove (const char *fname)
       xfree (wfname);
     }
   if (!rc)
-    gpg_err_set_errno (EIO);
-  return !rc;
+    return -1; /* ERRNO is automagically provided by gpg-error.h.  */
+  return 0;
 #else
   return remove (fname);
 #endif
@@ -543,7 +560,7 @@ gnupg_remove (const char *fname)
    defined on all systems.  The format of the modestring is
 
       "-rwxrwxrwx"
-      
+
    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
    write allowed, execution allowed with the first group for the user,
    the second for the group and the third for all others.  If the
@@ -555,7 +572,7 @@ gnupg_mkdir (const char *name, const char *modestr)
 #ifdef HAVE_W32CE_SYSTEM
   wchar_t *wname;
   (void)modestr;
-  
+
   wname = utf8_to_wchar (name);
   if (!wname)
     return -1;
@@ -615,7 +632,7 @@ gnupg_setenv (const char *name, const char *value, int overwrite)
 #endif
 }
 
-int 
+int
 gnupg_unsetenv (const char *name)
 {
 #ifdef HAVE_W32CE_SYSTEM
@@ -630,10 +647,40 @@ gnupg_unsetenv (const char *name)
 #endif
 }
 
+
+/* Return the current working directory as a malloced string.  Return
+   NULL and sets ERRNo on error.  */
+char *
+gnupg_getcwd (void)
+{
+  char *buffer;
+  size_t size = 100;
+
+  for (;;)
+    {
+      buffer = xtrymalloc (size+1);
+      if (!buffer)
+        return NULL;
+#ifdef HAVE_W32CE_SYSTEM
+      strcpy (buffer, "/");  /* Always "/".  */
+      return buffer;
+#else
+      if (getcwd (buffer, size) == buffer)
+        return buffer;
+      xfree (buffer);
+      if (errno != ERANGE)
+        return NULL;
+      size *= 2;
+#endif
+    }
+}
+
+
+\f
 #ifdef HAVE_W32CE_SYSTEM
 /* There is a isatty function declaration in cegcc but it does not
    make sense, thus we redefine it.  */
-int 
+int
 _gnupg_isatty (int fd)
 {
   (void)fd;
@@ -651,10 +698,10 @@ _gnupg_getenv (const char *name)
 {
   static int initialized;
   static char *assuan_debug;
-  
+
   if (!initialized)
     {
-      assuan_debug = read_w32_registry_string (NULL, 
+      assuan_debug = read_w32_registry_string (NULL,
                                                "\\Software\\GNU\\libassuan",
                                                "debug");
       initialized = 1;
@@ -668,3 +715,58 @@ _gnupg_getenv (const char *name)
 
 #endif /*HAVE_W32CE_SYSTEM*/
 
+
+#ifdef HAVE_W32_SYSTEM
+/* Return the user's security identifier from the current process.  */
+PSID
+w32_get_user_sid (void)
+{
+  int okay = 0;
+  HANDLE proc = NULL;
+  HANDLE token = NULL;
+  TOKEN_USER *user = NULL;
+  PSID sid = NULL;
+  DWORD tokenlen, sidlen;
+
+  proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
+  if (!proc)
+    goto leave;
+
+  if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
+    goto leave;
+
+  if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
+      && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+    goto leave;
+
+  user = xtrymalloc (tokenlen);
+  if (!user)
+    goto leave;
+
+  if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
+    goto leave;
+  if (!IsValidSid (user->User.Sid))
+    goto leave;
+  sidlen = GetLengthSid (user->User.Sid);
+  sid = xtrymalloc (sidlen);
+  if (!sid)
+    goto leave;
+  if (!CopySid (sidlen, sid, user->User.Sid))
+    goto leave;
+  okay = 1;
+
+ leave:
+  xfree (user);
+  if (token)
+    CloseHandle (token);
+  if (proc)
+    CloseHandle (proc);
+
+  if (!okay)
+    {
+      xfree (sid);
+      sid = NULL;
+    }
+  return sid;
+}
+#endif /*HAVE_W32_SYSTEM*/