Typo fixes.
[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 USE_NPTH
279   npth_sleep (seconds);
280 #else
281   /* Fixme:  make sure that a sleep won't wake up to early.  */
282 # ifdef HAVE_W32_SYSTEM
283   Sleep (seconds*1000);
284 # else
285   sleep (seconds);
286 # endif
287 #endif
288 }
289
290
291 /* This function is a NOP for POSIX systems but required under Windows
292    as the file handles as returned by OS calls (like CreateFile) are
293    different from the libc file descriptors (like open). This function
294    translates system file handles to libc file handles.  FOR_WRITE
295    gives the direction of the handle.  */
296 int
297 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
298 {
299 #if defined(HAVE_W32CE_SYSTEM)
300   (void)for_write;
301   return (int) fd;
302 #elif defined(HAVE_W32_SYSTEM)
303   int x;
304
305   if (fd == GNUPG_INVALID_FD)
306     return -1;
307
308   /* Note that _open_osfhandle is currently defined to take and return
309      a long.  */
310   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
311   if (x == -1)
312     log_error ("failed to translate osfhandle %p\n", (void *) fd);
313   return x;
314 #else /*!HAVE_W32_SYSTEM */
315   (void)for_write;
316   return fd;
317 #endif
318 }
319
320 /* This is the same as translate_sys2libc_fd but takes an integer
321    which is assumed to be such an system handle.  On WindowsCE the
322    passed FD is a rendezvous ID and the function finishes the pipe
323    creation. */
324 int
325 translate_sys2libc_fd_int (int fd, int for_write)
326 {
327 #if HAVE_W32CE_SYSTEM
328   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
329   return translate_sys2libc_fd ((void*)fd, for_write);
330 #elif HAVE_W32_SYSTEM
331   if (fd <= 2)
332     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
333
334   return translate_sys2libc_fd ((void*)fd, for_write);
335 #else
336   (void)for_write;
337   return fd;
338 #endif
339 }
340
341
342
343 /* Replacement for tmpfile().  This is required because the tmpfile
344    function of Windows' runtime library is broken, insecure, ignores
345    TMPDIR and so on.  In addition we create a file with an inheritable
346    handle.  */
347 FILE *
348 gnupg_tmpfile (void)
349 {
350 #ifdef HAVE_W32_SYSTEM
351   int attempts, n;
352 #ifdef HAVE_W32CE_SYSTEM
353   wchar_t buffer[MAX_PATH+7+12+1];
354 # define mystrlen(a) wcslen (a)
355   wchar_t *name, *p;
356 #else
357   char buffer[MAX_PATH+7+12+1];
358 # define mystrlen(a) strlen (a)
359   char *name, *p;
360 #endif
361   HANDLE file;
362   int pid = GetCurrentProcessId ();
363   unsigned int value;
364   int i;
365   SECURITY_ATTRIBUTES sec_attr;
366
367   memset (&sec_attr, 0, sizeof sec_attr );
368   sec_attr.nLength = sizeof sec_attr;
369   sec_attr.bInheritHandle = TRUE;
370
371   n = GetTempPath (MAX_PATH+1, buffer);
372   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
373     {
374       gpg_err_set_errno (ENOENT);
375       return NULL;
376     }
377   p = buffer + mystrlen (buffer);
378 #ifdef HAVE_W32CE_SYSTEM
379   wcscpy (p, L"_gnupg");
380   p += 7;
381 #else
382   p = stpcpy (p, "_gnupg");
383 #endif
384   /* We try to create the directory but don't care about an error as
385      it may already exist and the CreateFile would throw an error
386      anyway.  */
387   CreateDirectory (buffer, NULL);
388   *p++ = '\\';
389   name = p;
390   for (attempts=0; attempts < 10; attempts++)
391     {
392       p = name;
393       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
394       for (i=0; i < 8; i++)
395         {
396           *p++ = tohex (((value >> 28) & 0x0f));
397           value <<= 4;
398         }
399 #ifdef HAVE_W32CE_SYSTEM
400       wcscpy (p, L".tmp");
401 #else
402       strcpy (p, ".tmp");
403 #endif
404       file = CreateFile (buffer,
405                          GENERIC_READ | GENERIC_WRITE,
406                          0,
407                          &sec_attr,
408                          CREATE_NEW,
409                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
410                          NULL);
411       if (file != INVALID_HANDLE_VALUE)
412         {
413           FILE *fp;
414 #ifdef HAVE_W32CE_SYSTEM
415           int fd = (int)file;
416           fp = _wfdopen (fd, L"w+b");
417 #else
418           int fd = _open_osfhandle ((long)file, 0);
419           if (fd == -1)
420             {
421               CloseHandle (file);
422               return NULL;
423             }
424           fp = fdopen (fd, "w+b");
425 #endif
426           if (!fp)
427             {
428               int save = errno;
429               close (fd);
430               gpg_err_set_errno (save);
431               return NULL;
432             }
433           return fp;
434         }
435       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
436     }
437   gpg_err_set_errno (ENOENT);
438   return NULL;
439 #undef mystrlen
440 #else /*!HAVE_W32_SYSTEM*/
441   return tmpfile ();
442 #endif /*!HAVE_W32_SYSTEM*/
443 }
444
445
446 /* Make sure that the standard file descriptors are opened. Obviously
447    some folks close them before an exec and the next file we open will
448    get one of them assigned and thus any output (i.e. diagnostics) end
449    up in that file (e.g. the trustdb).  Not actually a gpg problem as
450    this will hapen with almost all utilities when called in a wrong
451    way.  However we try to minimize the damage here and raise
452    awareness of the problem.
453
454    Must be called before we open any files! */
455 void
456 gnupg_reopen_std (const char *pgmname)
457 {
458 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
459   struct stat statbuf;
460   int did_stdin = 0;
461   int did_stdout = 0;
462   int did_stderr = 0;
463   FILE *complain;
464
465   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
466     {
467       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
468         did_stdin = 1;
469       else
470         did_stdin = 2;
471     }
472
473   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
474     {
475       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
476         did_stdout = 1;
477       else
478         did_stdout = 2;
479     }
480
481   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
482     {
483       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
484         did_stderr = 1;
485       else
486         did_stderr = 2;
487     }
488
489   /* It's hard to log this sort of thing since the filehandle we would
490      complain to may be closed... */
491   if (!did_stderr)
492     complain = stderr;
493   else if (!did_stdout)
494     complain = stdout;
495   else
496     complain = NULL;
497
498   if (complain)
499     {
500       if (did_stdin == 1)
501         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
502       if (did_stdout == 1)
503         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
504       if (did_stderr == 1)
505         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
506
507       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
508         fprintf(complain,"%s: fatal: unable to reopen standard input,"
509                 " output, or error\n", pgmname);
510     }
511
512   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
513     exit (3);
514 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
515   (void)pgmname;
516 #endif
517 }
518
519
520 /* Hack required for Windows.  */
521 void
522 gnupg_allow_set_foregound_window (pid_t pid)
523 {
524   if (!pid)
525     log_info ("%s called with invalid pid %lu\n",
526               "gnupg_allow_set_foregound_window", (unsigned long)pid);
527 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
528   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
529     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
530                (unsigned long)pid, w32_strerror (-1));
531 #endif
532 }
533
534 int
535 gnupg_remove (const char *fname)
536 {
537 #ifdef HAVE_W32CE_SYSTEM
538   int rc;
539   wchar_t *wfname;
540
541   wfname = utf8_to_wchar (fname);
542   if (!wfname)
543     rc = 0;
544   else
545     {
546       rc = DeleteFile (wfname);
547       xfree (wfname);
548     }
549   if (!rc)
550     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
551   return 0;
552 #else
553   return remove (fname);
554 #endif
555 }
556
557
558 /* A wrapper around mkdir which takes a string for the mode argument.
559    This makes it easier to handle the mode argument which is not
560    defined on all systems.  The format of the modestring is
561
562       "-rwxrwxrwx"
563
564    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
565    write allowed, execution allowed with the first group for the user,
566    the second for the group and the third for all others.  If the
567    string is shorter than above the missing mode characters are meant
568    to be not set.  */
569 int
570 gnupg_mkdir (const char *name, const char *modestr)
571 {
572 #ifdef HAVE_W32CE_SYSTEM
573   wchar_t *wname;
574   (void)modestr;
575
576   wname = utf8_to_wchar (name);
577   if (!wname)
578     return -1;
579   if (!CreateDirectoryW (wname, NULL))
580     {
581       xfree (wname);
582       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
583     }
584   xfree (wname);
585   return 0;
586 #elif MKDIR_TAKES_ONE_ARG
587   (void)modestr;
588   /* Note: In the case of W32 we better use CreateDirectory and try to
589      set appropriate permissions.  However using mkdir is easier
590      because this sets ERRNO.  */
591   return mkdir (name);
592 #else
593   mode_t mode = 0;
594
595   if (modestr && *modestr)
596     {
597       modestr++;
598       if (*modestr && *modestr++ == 'r')
599         mode |= S_IRUSR;
600       if (*modestr && *modestr++ == 'w')
601         mode |= S_IWUSR;
602       if (*modestr && *modestr++ == 'x')
603         mode |= S_IXUSR;
604       if (*modestr && *modestr++ == 'r')
605         mode |= S_IRGRP;
606       if (*modestr && *modestr++ == 'w')
607         mode |= S_IWGRP;
608       if (*modestr && *modestr++ == 'x')
609         mode |= S_IXGRP;
610       if (*modestr && *modestr++ == 'r')
611         mode |= S_IROTH;
612       if (*modestr && *modestr++ == 'w')
613         mode |= S_IWOTH;
614       if (*modestr && *modestr++ == 'x')
615         mode |= S_IXOTH;
616     }
617   return mkdir (name, mode);
618 #endif
619 }
620
621
622 int
623 gnupg_setenv (const char *name, const char *value, int overwrite)
624 {
625 #ifdef HAVE_W32CE_SYSTEM
626   (void)name;
627   (void)value;
628   (void)overwrite;
629   return 0;
630 #else
631   return setenv (name, value, overwrite);
632 #endif
633 }
634
635 int
636 gnupg_unsetenv (const char *name)
637 {
638 #ifdef HAVE_W32CE_SYSTEM
639   (void)name;
640   return 0;
641 #else
642 # ifdef HAVE_UNSETENV
643   return unsetenv (name);
644 # else
645   return putenv (name);
646 # endif
647 #endif
648 }
649
650
651 /* Return the current working directory as a malloced string.  Return
652    NULL and sets ERRNo on error.  */
653 char *
654 gnupg_getcwd (void)
655 {
656   char *buffer;
657   size_t size = 100;
658
659   for (;;)
660     {
661       buffer = xtrymalloc (size+1);
662       if (!buffer)
663         return NULL;
664 #ifdef HAVE_W32CE_SYSTEM
665       strcpy (buffer, "/");  /* Always "/".  */
666       return buffer;
667 #else
668       if (getcwd (buffer, size) == buffer)
669         return buffer;
670       xfree (buffer);
671       if (errno != ERANGE)
672         return NULL;
673       size *= 2;
674 #endif
675     }
676 }
677
678
679 \f
680 #ifdef HAVE_W32CE_SYSTEM
681 /* There is a isatty function declaration in cegcc but it does not
682    make sense, thus we redefine it.  */
683 int
684 _gnupg_isatty (int fd)
685 {
686   (void)fd;
687   return 0;
688 }
689 #endif
690
691
692 #ifdef HAVE_W32CE_SYSTEM
693 /* Replacement for getenv which takes care of the our use of getenv.
694    The code is not thread safe but we expect it to work in all cases
695    because it is called for the first time early enough.  */
696 char *
697 _gnupg_getenv (const char *name)
698 {
699   static int initialized;
700   static char *assuan_debug;
701
702   if (!initialized)
703     {
704       assuan_debug = read_w32_registry_string (NULL,
705                                                "\\Software\\GNU\\libassuan",
706                                                "debug");
707       initialized = 1;
708     }
709
710   if (!strcmp (name, "ASSUAN_DEBUG"))
711     return assuan_debug;
712   else
713     return NULL;
714 }
715
716 #endif /*HAVE_W32CE_SYSTEM*/
717
718
719 #ifdef HAVE_W32_SYSTEM
720 /* Return the user's security identifier from the current process.  */
721 PSID
722 w32_get_user_sid (void)
723 {
724   int okay = 0;
725   HANDLE proc = NULL;
726   HANDLE token = NULL;
727   TOKEN_USER *user = NULL;
728   PSID sid = NULL;
729   DWORD tokenlen, sidlen;
730
731   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
732   if (!proc)
733     goto leave;
734
735   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
736     goto leave;
737
738   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
739       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
740     goto leave;
741
742   user = xtrymalloc (tokenlen);
743   if (!user)
744     goto leave;
745
746   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
747     goto leave;
748   if (!IsValidSid (user->User.Sid))
749     goto leave;
750   sidlen = GetLengthSid (user->User.Sid);
751   sid = xtrymalloc (sidlen);
752   if (!sid)
753     goto leave;
754   if (!CopySid (sidlen, sid, user->User.Sid))
755     goto leave;
756   okay = 1;
757
758  leave:
759   xfree (user);
760   if (token)
761     CloseHandle (token);
762   if (proc)
763     CloseHandle (proc);
764
765   if (!okay)
766     {
767       xfree (sid);
768       sid = NULL;
769     }
770   return sid;
771 }
772 #endif /*HAVE_W32_SYSTEM*/