w32: Include winsock2.h to silence warnings.
[gnupg.git] / common / sysutils.c
1 /* sysutils.c -  system helpers
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
3  *               2007, 2008  Free Software Foundation, Inc.
4  * Copyright (C) 2013 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * This file is free software; you can redistribute it and/or modify
9  * it under the terms of either
10  *
11  *   - the GNU Lesser General Public License as published by the Free
12  *     Software Foundation; either version 3 of the License, or (at
13  *     your option) any later version.
14  *
15  * or
16  *
17  *   - the GNU General Public License as published by the Free
18  *     Software Foundation; either version 2 of the License, or (at
19  *     your option) any later version.
20  *
21  * or both in parallel, as here.
22  *
23  * This file is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <http://www.gnu.org/licenses/>.
30  */
31
32 #include <config.h>
33
34 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
35 # undef HAVE_NPTH
36 # undef USE_NPTH
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <errno.h>
44 #ifdef HAVE_STAT
45 # include <sys/stat.h>
46 #endif
47 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
48 # include <asm/sysinfo.h>
49 # include <asm/unistd.h>
50 #endif
51 #ifdef HAVE_SETRLIMIT
52 # include <time.h>
53 # include <sys/time.h>
54 # include <sys/resource.h>
55 #endif
56 #ifdef HAVE_W32_SYSTEM
57 # if WINVER < 0x0500
58 #   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
59 # endif
60 # ifdef HAVE_WINSOCK2_H
61 #  include <winsock2.h>
62 # endif
63 # include <windows.h>
64 #endif
65 #ifdef HAVE_NPTH
66 # include <npth.h>
67 #endif
68 #include <fcntl.h>
69
70 #include <assuan.h>
71
72 #include "setenv.h"   /* Gnulib replacement.  */
73
74 #include "util.h"
75 #include "i18n.h"
76
77 #include "sysutils.h"
78
79 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
80
81
82 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
83 #warning using trap_unaligned
84 static int
85 setsysinfo(unsigned long op, void *buffer, unsigned long size,
86                      int *start, void *arg, unsigned long flag)
87 {
88     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
89 }
90
91 void
92 trap_unaligned(void)
93 {
94     unsigned int buf[2];
95
96     buf[0] = SSIN_UACPROC;
97     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
98     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
99 }
100 #else
101 void
102 trap_unaligned(void)
103 {  /* dummy */
104 }
105 #endif
106
107
108 int
109 disable_core_dumps (void)
110 {
111 #ifdef HAVE_DOSISH_SYSTEM
112     return 0;
113 #else
114 # ifdef HAVE_SETRLIMIT
115     struct rlimit limit;
116
117     /* We only set the current limit unless we were not able to
118        retrieve the old value. */
119     if (getrlimit (RLIMIT_CORE, &limit))
120       limit.rlim_max = 0;
121     limit.rlim_cur = 0;
122     if( !setrlimit (RLIMIT_CORE, &limit) )
123         return 0;
124     if( errno != EINVAL && errno != ENOSYS )
125         log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
126 #endif
127     return 1;
128 #endif
129 }
130
131 int
132 enable_core_dumps (void)
133 {
134 #ifdef HAVE_DOSISH_SYSTEM
135     return 0;
136 #else
137 # ifdef HAVE_SETRLIMIT
138     struct rlimit limit;
139
140     if (getrlimit (RLIMIT_CORE, &limit))
141       return 1;
142     limit.rlim_cur = limit.rlim_max;
143     setrlimit (RLIMIT_CORE, &limit);
144     return 1; /* We always return true because this function is
145                  merely a debugging aid. */
146 # endif
147     return 1;
148 #endif
149 }
150
151
152
153 /* Return a string which is used as a kind of process ID.  */
154 const byte *
155 get_session_marker (size_t *rlen)
156 {
157   static byte marker[SIZEOF_UNSIGNED_LONG*2];
158   static int initialized;
159
160   if (!initialized)
161     {
162       gcry_create_nonce (marker, sizeof marker);
163       initialized = 1;
164     }
165   *rlen = sizeof (marker);
166   return marker;
167 }
168
169 /* Return a random number in an unsigned int. */
170 unsigned int
171 get_uint_nonce (void)
172 {
173   unsigned int value;
174
175   gcry_create_nonce (&value, sizeof value);
176   return value;
177 }
178
179
180
181 #if 0 /* not yet needed - Note that this will require inclusion of
182          cmacros.am in Makefile.am */
183 int
184 check_permissions(const char *path,int extension,int checkonly)
185 {
186 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
187   char *tmppath;
188   struct stat statbuf;
189   int ret=1;
190   int isdir=0;
191
192   if(opt.no_perm_warn)
193     return 0;
194
195   if(extension && path[0]!=DIRSEP_C)
196     {
197       if(strchr(path,DIRSEP_C))
198         tmppath=make_filename(path,NULL);
199       else
200         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
201     }
202   else
203     tmppath=m_strdup(path);
204
205   /* It's okay if the file doesn't exist */
206   if(stat(tmppath,&statbuf)!=0)
207     {
208       ret=0;
209       goto end;
210     }
211
212   isdir=S_ISDIR(statbuf.st_mode);
213
214   /* Per-user files must be owned by the user.  Extensions must be
215      owned by the user or root. */
216   if((!extension && statbuf.st_uid != getuid()) ||
217      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
218     {
219       if(!checkonly)
220         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
221                  isdir?"directory":extension?"extension":"file",path);
222       goto end;
223     }
224
225   /* This works for both directories and files - basically, we don't
226      care what the owner permissions are, so long as the group and
227      other permissions are 0 for per-user files, and non-writable for
228      extensions. */
229   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
230      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
231     {
232       char *dir;
233
234       /* However, if the directory the directory/file is in is owned
235          by the user and is 700, then this is not a problem.
236          Theoretically, we could walk this test up to the root
237          directory /, but for the sake of sanity, I'm stopping at one
238          level down. */
239
240       dir= make_dirname (tmppath);
241       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
242          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
243         {
244           xfree (dir);
245           ret=0;
246           goto end;
247         }
248
249       m_free(dir);
250
251       if(!checkonly)
252         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
253                  isdir?"directory":extension?"extension":"file",path);
254       goto end;
255     }
256
257   ret=0;
258
259  end:
260   m_free(tmppath);
261
262   return ret;
263
264 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
265
266   return 0;
267 }
268 #endif
269
270
271 /* Wrapper around the usual sleep fucntion.  This one won't wake up
272    before the sleep time has really elapsed.  When build with Pth it
273    merely calls pth_sleep and thus suspends only the current
274    thread. */
275 void
276 gnupg_sleep (unsigned int seconds)
277 {
278 #ifdef HAVE_NPTH
279   /* With Pth we force a regular sleep for seconds == 0 so that also
280      the process will give up its timeslot.  */
281   if (!seconds)
282     {
283 # ifdef HAVE_W32_SYSTEM
284       Sleep (0);
285 # else
286       sleep (0);
287 # endif
288     }
289   pth_sleep (seconds);
290 #else
291   /* Fixme:  make sure that a sleep won't wake up to early.  */
292 # ifdef HAVE_W32_SYSTEM
293   Sleep (seconds*1000);
294 # else
295   sleep (seconds);
296 # endif
297 #endif
298 }
299
300
301 /* This function is a NOP for POSIX systems but required under Windows
302    as the file handles as returned by OS calls (like CreateFile) are
303    different from the libc file descriptors (like open). This function
304    translates system file handles to libc file handles.  FOR_WRITE
305    gives the direction of the handle.  */
306 int
307 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
308 {
309 #if defined(HAVE_W32CE_SYSTEM)
310   (void)for_write;
311   return (int) fd;
312 #elif defined(HAVE_W32_SYSTEM)
313   int x;
314
315   if (fd == GNUPG_INVALID_FD)
316     return -1;
317
318   /* Note that _open_osfhandle is currently defined to take and return
319      a long.  */
320   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
321   if (x == -1)
322     log_error ("failed to translate osfhandle %p\n", (void *) fd);
323   return x;
324 #else /*!HAVE_W32_SYSTEM */
325   (void)for_write;
326   return fd;
327 #endif
328 }
329
330 /* This is the same as translate_sys2libc_fd but takes an integer
331    which is assumed to be such an system handle.  On WindowsCE the
332    passed FD is a rendezvous ID and the function finishes the pipe
333    creation. */
334 int
335 translate_sys2libc_fd_int (int fd, int for_write)
336 {
337 #if HAVE_W32CE_SYSTEM
338   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
339   return translate_sys2libc_fd ((void*)fd, for_write);
340 #elif HAVE_W32_SYSTEM
341   if (fd <= 2)
342     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
343
344   return translate_sys2libc_fd ((void*)fd, for_write);
345 #else
346   (void)for_write;
347   return fd;
348 #endif
349 }
350
351
352
353 /* Replacement for tmpfile().  This is required because the tmpfile
354    function of Windows' runtime library is broken, insecure, ignores
355    TMPDIR and so on.  In addition we create a file with an inheritable
356    handle.  */
357 FILE *
358 gnupg_tmpfile (void)
359 {
360 #ifdef HAVE_W32_SYSTEM
361   int attempts, n;
362 #ifdef HAVE_W32CE_SYSTEM
363   wchar_t buffer[MAX_PATH+7+12+1];
364 # define mystrlen(a) wcslen (a)
365   wchar_t *name, *p;
366 #else
367   char buffer[MAX_PATH+7+12+1];
368 # define mystrlen(a) strlen (a)
369   char *name, *p;
370 #endif
371   HANDLE file;
372   int pid = GetCurrentProcessId ();
373   unsigned int value;
374   int i;
375   SECURITY_ATTRIBUTES sec_attr;
376
377   memset (&sec_attr, 0, sizeof sec_attr );
378   sec_attr.nLength = sizeof sec_attr;
379   sec_attr.bInheritHandle = TRUE;
380
381   n = GetTempPath (MAX_PATH+1, buffer);
382   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
383     {
384       gpg_err_set_errno (ENOENT);
385       return NULL;
386     }
387   p = buffer + mystrlen (buffer);
388 #ifdef HAVE_W32CE_SYSTEM
389   wcscpy (p, L"_gnupg");
390   p += 7;
391 #else
392   p = stpcpy (p, "_gnupg");
393 #endif
394   /* We try to create the directory but don't care about an error as
395      it may already exist and the CreateFile would throw an error
396      anyway.  */
397   CreateDirectory (buffer, NULL);
398   *p++ = '\\';
399   name = p;
400   for (attempts=0; attempts < 10; attempts++)
401     {
402       p = name;
403       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
404       for (i=0; i < 8; i++)
405         {
406           *p++ = tohex (((value >> 28) & 0x0f));
407           value <<= 4;
408         }
409 #ifdef HAVE_W32CE_SYSTEM
410       wcscpy (p, L".tmp");
411 #else
412       strcpy (p, ".tmp");
413 #endif
414       file = CreateFile (buffer,
415                          GENERIC_READ | GENERIC_WRITE,
416                          0,
417                          &sec_attr,
418                          CREATE_NEW,
419                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
420                          NULL);
421       if (file != INVALID_HANDLE_VALUE)
422         {
423           FILE *fp;
424 #ifdef HAVE_W32CE_SYSTEM
425           int fd = (int)file;
426           fp = _wfdopen (fd, L"w+b");
427 #else
428           int fd = _open_osfhandle ((long)file, 0);
429           if (fd == -1)
430             {
431               CloseHandle (file);
432               return NULL;
433             }
434           fp = fdopen (fd, "w+b");
435 #endif
436           if (!fp)
437             {
438               int save = errno;
439               close (fd);
440               gpg_err_set_errno (save);
441               return NULL;
442             }
443           return fp;
444         }
445       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
446     }
447   gpg_err_set_errno (ENOENT);
448   return NULL;
449 #undef mystrlen
450 #else /*!HAVE_W32_SYSTEM*/
451   return tmpfile ();
452 #endif /*!HAVE_W32_SYSTEM*/
453 }
454
455
456 /* Make sure that the standard file descriptors are opened. Obviously
457    some folks close them before an exec and the next file we open will
458    get one of them assigned and thus any output (i.e. diagnostics) end
459    up in that file (e.g. the trustdb).  Not actually a gpg problem as
460    this will hapen with almost all utilities when called in a wrong
461    way.  However we try to minimize the damage here and raise
462    awareness of the problem.
463
464    Must be called before we open any files! */
465 void
466 gnupg_reopen_std (const char *pgmname)
467 {
468 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
469   struct stat statbuf;
470   int did_stdin = 0;
471   int did_stdout = 0;
472   int did_stderr = 0;
473   FILE *complain;
474
475   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
476     {
477       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
478         did_stdin = 1;
479       else
480         did_stdin = 2;
481     }
482
483   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
484     {
485       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
486         did_stdout = 1;
487       else
488         did_stdout = 2;
489     }
490
491   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
492     {
493       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
494         did_stderr = 1;
495       else
496         did_stderr = 2;
497     }
498
499   /* It's hard to log this sort of thing since the filehandle we would
500      complain to may be closed... */
501   if (!did_stderr)
502     complain = stderr;
503   else if (!did_stdout)
504     complain = stdout;
505   else
506     complain = NULL;
507
508   if (complain)
509     {
510       if (did_stdin == 1)
511         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
512       if (did_stdout == 1)
513         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
514       if (did_stderr == 1)
515         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
516
517       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
518         fprintf(complain,"%s: fatal: unable to reopen standard input,"
519                 " output, or error\n", pgmname);
520     }
521
522   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
523     exit (3);
524 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
525   (void)pgmname;
526 #endif
527 }
528
529
530 /* Hack required for Windows.  */
531 void
532 gnupg_allow_set_foregound_window (pid_t pid)
533 {
534   if (!pid)
535     log_info ("%s called with invalid pid %lu\n",
536               "gnupg_allow_set_foregound_window", (unsigned long)pid);
537 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
538   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
539     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
540                (unsigned long)pid, w32_strerror (-1));
541 #endif
542 }
543
544 int
545 gnupg_remove (const char *fname)
546 {
547 #ifdef HAVE_W32CE_SYSTEM
548   int rc;
549   wchar_t *wfname;
550
551   wfname = utf8_to_wchar (fname);
552   if (!wfname)
553     rc = 0;
554   else
555     {
556       rc = DeleteFile (wfname);
557       xfree (wfname);
558     }
559   if (!rc)
560     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
561   return 0;
562 #else
563   return remove (fname);
564 #endif
565 }
566
567
568 /* A wrapper around mkdir which takes a string for the mode argument.
569    This makes it easier to handle the mode argument which is not
570    defined on all systems.  The format of the modestring is
571
572       "-rwxrwxrwx"
573
574    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
575    write allowed, execution allowed with the first group for the user,
576    the second for the group and the third for all others.  If the
577    string is shorter than above the missing mode characters are meant
578    to be not set.  */
579 int
580 gnupg_mkdir (const char *name, const char *modestr)
581 {
582 #ifdef HAVE_W32CE_SYSTEM
583   wchar_t *wname;
584   (void)modestr;
585
586   wname = utf8_to_wchar (name);
587   if (!wname)
588     return -1;
589   if (!CreateDirectoryW (wname, NULL))
590     {
591       xfree (wname);
592       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
593     }
594   xfree (wname);
595   return 0;
596 #elif MKDIR_TAKES_ONE_ARG
597   (void)modestr;
598   /* Note: In the case of W32 we better use CreateDirectory and try to
599      set appropriate permissions.  However using mkdir is easier
600      because this sets ERRNO.  */
601   return mkdir (name);
602 #else
603   mode_t mode = 0;
604
605   if (modestr && *modestr)
606     {
607       modestr++;
608       if (*modestr && *modestr++ == 'r')
609         mode |= S_IRUSR;
610       if (*modestr && *modestr++ == 'w')
611         mode |= S_IWUSR;
612       if (*modestr && *modestr++ == 'x')
613         mode |= S_IXUSR;
614       if (*modestr && *modestr++ == 'r')
615         mode |= S_IRGRP;
616       if (*modestr && *modestr++ == 'w')
617         mode |= S_IWGRP;
618       if (*modestr && *modestr++ == 'x')
619         mode |= S_IXGRP;
620       if (*modestr && *modestr++ == 'r')
621         mode |= S_IROTH;
622       if (*modestr && *modestr++ == 'w')
623         mode |= S_IWOTH;
624       if (*modestr && *modestr++ == 'x')
625         mode |= S_IXOTH;
626     }
627   return mkdir (name, mode);
628 #endif
629 }
630
631
632 int
633 gnupg_setenv (const char *name, const char *value, int overwrite)
634 {
635 #ifdef HAVE_W32CE_SYSTEM
636   (void)name;
637   (void)value;
638   (void)overwrite;
639   return 0;
640 #else
641   return setenv (name, value, overwrite);
642 #endif
643 }
644
645 int
646 gnupg_unsetenv (const char *name)
647 {
648 #ifdef HAVE_W32CE_SYSTEM
649   (void)name;
650   return 0;
651 #else
652 # ifdef HAVE_UNSETENV
653   return unsetenv (name);
654 # else
655   return putenv (name);
656 # endif
657 #endif
658 }
659
660 #ifdef HAVE_W32CE_SYSTEM
661 /* There is a isatty function declaration in cegcc but it does not
662    make sense, thus we redefine it.  */
663 int
664 _gnupg_isatty (int fd)
665 {
666   (void)fd;
667   return 0;
668 }
669 #endif
670
671
672 #ifdef HAVE_W32CE_SYSTEM
673 /* Replacement for getenv which takes care of the our use of getenv.
674    The code is not thread safe but we expect it to work in all cases
675    because it is called for the first time early enough.  */
676 char *
677 _gnupg_getenv (const char *name)
678 {
679   static int initialized;
680   static char *assuan_debug;
681
682   if (!initialized)
683     {
684       assuan_debug = read_w32_registry_string (NULL,
685                                                "\\Software\\GNU\\libassuan",
686                                                "debug");
687       initialized = 1;
688     }
689
690   if (!strcmp (name, "ASSUAN_DEBUG"))
691     return assuan_debug;
692   else
693     return NULL;
694 }
695
696 #endif /*HAVE_W32CE_SYSTEM*/
697
698
699 #ifdef HAVE_W32_SYSTEM
700 /* Return the user's security identifier from the current process.  */
701 PSID
702 w32_get_user_sid (void)
703 {
704   int okay = 0;
705   HANDLE proc = NULL;
706   HANDLE token = NULL;
707   TOKEN_USER *user = NULL;
708   PSID sid = NULL;
709   DWORD tokenlen, sidlen;
710
711   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
712   if (!proc)
713     goto leave;
714
715   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
716     goto leave;
717
718   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
719       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
720     goto leave;
721
722   user = xtrymalloc (tokenlen);
723   if (!user)
724     goto leave;
725
726   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
727     goto leave;
728   if (!IsValidSid (user->User.Sid))
729     goto leave;
730   sidlen = GetLengthSid (user->User.Sid);
731   sid = xtrymalloc (sidlen);
732   if (!sid)
733     goto leave;
734   if (!CopySid (sidlen, sid, user->User.Sid))
735     goto leave;
736   okay = 1;
737
738  leave:
739   xfree (user);
740   if (token)
741     CloseHandle (token);
742   if (proc)
743     CloseHandle (proc);
744
745   if (!okay)
746     {
747       xfree (sid);
748       sid = NULL;
749     }
750   return sid;
751 }
752 #endif /*HAVE_W32_SYSTEM*/