tests: Add test for the ssh key export.
[gnupg.git] / common / sysutils.c
1 /* sysutils.c -  system helpers
2  * Copyright (C) 1991-2001, 2003-2004,
3  *               2006-2008  Free Software Foundation, Inc.
4  * Copyright (C) 2013-2014 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 <https://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 <stdint.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <errno.h>
45 #ifdef HAVE_STAT
46 # include <sys/stat.h>
47 #endif
48 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
49 # include <asm/sysinfo.h>
50 # include <asm/unistd.h>
51 #endif
52 #include <time.h>
53 #ifdef HAVE_SETRLIMIT
54 # include <sys/time.h>
55 # include <sys/resource.h>
56 #endif
57 #ifdef HAVE_W32_SYSTEM
58 # if WINVER < 0x0500
59 #   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
60 # endif
61 # ifdef HAVE_WINSOCK2_H
62 #  include <winsock2.h>
63 # endif
64 # include <windows.h>
65 #else /*!HAVE_W32_SYSTEM*/
66 # include <sys/socket.h>
67 # include <sys/un.h>
68 #endif
69 #ifdef HAVE_INOTIFY_INIT
70 # include <sys/inotify.h>
71 #endif /*HAVE_INOTIFY_INIT*/
72 #ifdef HAVE_NPTH
73 # include <npth.h>
74 #endif
75 #include <fcntl.h>
76
77 #include <assuan.h>
78
79 #include "util.h"
80 #include "i18n.h"
81
82 #include "sysutils.h"
83
84 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
85
86
87 static GPGRT_INLINE gpg_error_t
88 my_error_from_syserror (void)
89 {
90   return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
91 }
92
93 static GPGRT_INLINE gpg_error_t
94 my_error (int e)
95 {
96   return gpg_err_make (default_errsource, (e));
97 }
98
99
100
101 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
102 #warning using trap_unaligned
103 static int
104 setsysinfo(unsigned long op, void *buffer, unsigned long size,
105                      int *start, void *arg, unsigned long flag)
106 {
107     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
108 }
109
110 void
111 trap_unaligned(void)
112 {
113     unsigned int buf[2];
114
115     buf[0] = SSIN_UACPROC;
116     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
117     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
118 }
119 #else
120 void
121 trap_unaligned(void)
122 {  /* dummy */
123 }
124 #endif
125
126
127 int
128 disable_core_dumps (void)
129 {
130 #ifdef HAVE_DOSISH_SYSTEM
131     return 0;
132 #else
133 # ifdef HAVE_SETRLIMIT
134     struct rlimit limit;
135
136     /* We only set the current limit unless we were not able to
137        retrieve the old value. */
138     if (getrlimit (RLIMIT_CORE, &limit))
139       limit.rlim_max = 0;
140     limit.rlim_cur = 0;
141     if( !setrlimit (RLIMIT_CORE, &limit) )
142         return 0;
143     if( errno != EINVAL && errno != ENOSYS )
144         log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
145 #endif
146     return 1;
147 #endif
148 }
149
150 int
151 enable_core_dumps (void)
152 {
153 #ifdef HAVE_DOSISH_SYSTEM
154     return 0;
155 #else
156 # ifdef HAVE_SETRLIMIT
157     struct rlimit limit;
158
159     if (getrlimit (RLIMIT_CORE, &limit))
160       return 1;
161     limit.rlim_cur = limit.rlim_max;
162     setrlimit (RLIMIT_CORE, &limit);
163     return 1; /* We always return true because this function is
164                  merely a debugging aid. */
165 # endif
166     return 1;
167 #endif
168 }
169
170
171
172 /* Return a string which is used as a kind of process ID.  */
173 const byte *
174 get_session_marker (size_t *rlen)
175 {
176   static byte marker[SIZEOF_UNSIGNED_LONG*2];
177   static int initialized;
178
179   if (!initialized)
180     {
181       gcry_create_nonce (marker, sizeof marker);
182       initialized = 1;
183     }
184   *rlen = sizeof (marker);
185   return marker;
186 }
187
188 /* Return a random number in an unsigned int. */
189 unsigned int
190 get_uint_nonce (void)
191 {
192   unsigned int value;
193
194   gcry_create_nonce (&value, sizeof value);
195   return value;
196 }
197
198
199
200 #if 0 /* not yet needed - Note that this will require inclusion of
201          cmacros.am in Makefile.am */
202 int
203 check_permissions(const char *path,int extension,int checkonly)
204 {
205 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
206   char *tmppath;
207   struct stat statbuf;
208   int ret=1;
209   int isdir=0;
210
211   if(opt.no_perm_warn)
212     return 0;
213
214   if(extension && path[0]!=DIRSEP_C)
215     {
216       if(strchr(path,DIRSEP_C))
217         tmppath=make_filename(path,NULL);
218       else
219         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
220     }
221   else
222     tmppath=m_strdup(path);
223
224   /* It's okay if the file doesn't exist */
225   if(stat(tmppath,&statbuf)!=0)
226     {
227       ret=0;
228       goto end;
229     }
230
231   isdir=S_ISDIR(statbuf.st_mode);
232
233   /* Per-user files must be owned by the user.  Extensions must be
234      owned by the user or root. */
235   if((!extension && statbuf.st_uid != getuid()) ||
236      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
237     {
238       if(!checkonly)
239         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
240                  isdir?"directory":extension?"extension":"file",path);
241       goto end;
242     }
243
244   /* This works for both directories and files - basically, we don't
245      care what the owner permissions are, so long as the group and
246      other permissions are 0 for per-user files, and non-writable for
247      extensions. */
248   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
249      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
250     {
251       char *dir;
252
253       /* However, if the directory the directory/file is in is owned
254          by the user and is 700, then this is not a problem.
255          Theoretically, we could walk this test up to the root
256          directory /, but for the sake of sanity, I'm stopping at one
257          level down. */
258
259       dir= make_dirname (tmppath);
260       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
261          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
262         {
263           xfree (dir);
264           ret=0;
265           goto end;
266         }
267
268       m_free(dir);
269
270       if(!checkonly)
271         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
272                  isdir?"directory":extension?"extension":"file",path);
273       goto end;
274     }
275
276   ret=0;
277
278  end:
279   m_free(tmppath);
280
281   return ret;
282
283 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
284
285   return 0;
286 }
287 #endif
288
289
290 /* Wrapper around the usual sleep function.  This one won't wake up
291    before the sleep time has really elapsed.  When build with Pth it
292    merely calls pth_sleep and thus suspends only the current
293    thread. */
294 void
295 gnupg_sleep (unsigned int seconds)
296 {
297 #ifdef USE_NPTH
298   npth_sleep (seconds);
299 #else
300   /* Fixme:  make sure that a sleep won't wake up to early.  */
301 # ifdef HAVE_W32_SYSTEM
302   Sleep (seconds*1000);
303 # else
304   sleep (seconds);
305 # endif
306 #endif
307 }
308
309
310 /* Wrapper around the platforms usleep function.  This one won't wake
311  * up before the sleep time has really elapsed.  When build with nPth
312  * it merely calls npth_usleep and thus suspends only the current
313  * thread. */
314 void
315 gnupg_usleep (unsigned int usecs)
316 {
317 #if defined(USE_NPTH)
318
319   npth_usleep (usecs);
320
321 #elif defined(HAVE_W32_SYSTEM)
322
323   Sleep ((usecs + 999) / 1000);
324
325 #elif defined(HAVE_NANOSLEEP)
326
327   if (usecs)
328     {
329       struct timespec req;
330       struct timespec rem;
331
332       req.tv_sec = 0;
333       req.tv_nsec = usecs * 1000;
334
335       while (nanosleep (&req, &rem) < 0 && errno == EINTR)
336         req = rem;
337     }
338
339 #else /*Standard Unix*/
340
341   if (usecs)
342     {
343       struct timeval tv;
344
345       tv.tv_sec  = usecs / 1000000;
346       tv.tv_usec = usecs % 1000000;
347       select (0, NULL, NULL, NULL, &tv);
348     }
349
350 #endif
351 }
352
353
354 /* This function is a NOP for POSIX systems but required under Windows
355    as the file handles as returned by OS calls (like CreateFile) are
356    different from the libc file descriptors (like open). This function
357    translates system file handles to libc file handles.  FOR_WRITE
358    gives the direction of the handle.  */
359 int
360 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
361 {
362 #if defined(HAVE_W32CE_SYSTEM)
363   (void)for_write;
364   return (int) fd;
365 #elif defined(HAVE_W32_SYSTEM)
366   int x;
367
368   if (fd == GNUPG_INVALID_FD)
369     return -1;
370
371   /* Note that _open_osfhandle is currently defined to take and return
372      a long.  */
373   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
374   if (x == -1)
375     log_error ("failed to translate osfhandle %p\n", (void *) fd);
376   return x;
377 #else /*!HAVE_W32_SYSTEM */
378   (void)for_write;
379   return fd;
380 #endif
381 }
382
383 /* This is the same as translate_sys2libc_fd but takes an integer
384    which is assumed to be such an system handle.  On WindowsCE the
385    passed FD is a rendezvous ID and the function finishes the pipe
386    creation. */
387 int
388 translate_sys2libc_fd_int (int fd, int for_write)
389 {
390 #if HAVE_W32CE_SYSTEM
391   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
392   return translate_sys2libc_fd ((void*)fd, for_write);
393 #elif HAVE_W32_SYSTEM
394   if (fd <= 2)
395     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
396
397   return translate_sys2libc_fd ((void*)fd, for_write);
398 #else
399   (void)for_write;
400   return fd;
401 #endif
402 }
403
404
405
406 /* Replacement for tmpfile().  This is required because the tmpfile
407    function of Windows' runtime library is broken, insecure, ignores
408    TMPDIR and so on.  In addition we create a file with an inheritable
409    handle.  */
410 FILE *
411 gnupg_tmpfile (void)
412 {
413 #ifdef HAVE_W32_SYSTEM
414   int attempts, n;
415 #ifdef HAVE_W32CE_SYSTEM
416   wchar_t buffer[MAX_PATH+7+12+1];
417 # define mystrlen(a) wcslen (a)
418   wchar_t *name, *p;
419 #else
420   char buffer[MAX_PATH+7+12+1];
421 # define mystrlen(a) strlen (a)
422   char *name, *p;
423 #endif
424   HANDLE file;
425   int pid = GetCurrentProcessId ();
426   unsigned int value;
427   int i;
428   SECURITY_ATTRIBUTES sec_attr;
429
430   memset (&sec_attr, 0, sizeof sec_attr );
431   sec_attr.nLength = sizeof sec_attr;
432   sec_attr.bInheritHandle = TRUE;
433
434   n = GetTempPath (MAX_PATH+1, buffer);
435   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
436     {
437       gpg_err_set_errno (ENOENT);
438       return NULL;
439     }
440   p = buffer + mystrlen (buffer);
441 #ifdef HAVE_W32CE_SYSTEM
442   wcscpy (p, L"_gnupg");
443   p += 7;
444 #else
445   p = stpcpy (p, "_gnupg");
446 #endif
447   /* We try to create the directory but don't care about an error as
448      it may already exist and the CreateFile would throw an error
449      anyway.  */
450   CreateDirectory (buffer, NULL);
451   *p++ = '\\';
452   name = p;
453   for (attempts=0; attempts < 10; attempts++)
454     {
455       p = name;
456       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
457       for (i=0; i < 8; i++)
458         {
459           *p++ = tohex (((value >> 28) & 0x0f));
460           value <<= 4;
461         }
462 #ifdef HAVE_W32CE_SYSTEM
463       wcscpy (p, L".tmp");
464 #else
465       strcpy (p, ".tmp");
466 #endif
467       file = CreateFile (buffer,
468                          GENERIC_READ | GENERIC_WRITE,
469                          0,
470                          &sec_attr,
471                          CREATE_NEW,
472                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
473                          NULL);
474       if (file != INVALID_HANDLE_VALUE)
475         {
476           FILE *fp;
477 #ifdef HAVE_W32CE_SYSTEM
478           int fd = (int)file;
479           fp = _wfdopen (fd, L"w+b");
480 #else
481           int fd = _open_osfhandle ((long)file, 0);
482           if (fd == -1)
483             {
484               CloseHandle (file);
485               return NULL;
486             }
487           fp = fdopen (fd, "w+b");
488 #endif
489           if (!fp)
490             {
491               int save = errno;
492               close (fd);
493               gpg_err_set_errno (save);
494               return NULL;
495             }
496           return fp;
497         }
498       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
499     }
500   gpg_err_set_errno (ENOENT);
501   return NULL;
502 #undef mystrlen
503 #else /*!HAVE_W32_SYSTEM*/
504   return tmpfile ();
505 #endif /*!HAVE_W32_SYSTEM*/
506 }
507
508
509 /* Make sure that the standard file descriptors are opened. Obviously
510    some folks close them before an exec and the next file we open will
511    get one of them assigned and thus any output (i.e. diagnostics) end
512    up in that file (e.g. the trustdb).  Not actually a gpg problem as
513    this will happen with almost all utilities when called in a wrong
514    way.  However we try to minimize the damage here and raise
515    awareness of the problem.
516
517    Must be called before we open any files! */
518 void
519 gnupg_reopen_std (const char *pgmname)
520 {
521 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
522   struct stat statbuf;
523   int did_stdin = 0;
524   int did_stdout = 0;
525   int did_stderr = 0;
526   FILE *complain;
527
528   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
529     {
530       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
531         did_stdin = 1;
532       else
533         did_stdin = 2;
534     }
535
536   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
537     {
538       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
539         did_stdout = 1;
540       else
541         did_stdout = 2;
542     }
543
544   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
545     {
546       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
547         did_stderr = 1;
548       else
549         did_stderr = 2;
550     }
551
552   /* It's hard to log this sort of thing since the filehandle we would
553      complain to may be closed... */
554   if (!did_stderr)
555     complain = stderr;
556   else if (!did_stdout)
557     complain = stdout;
558   else
559     complain = NULL;
560
561   if (complain)
562     {
563       if (did_stdin == 1)
564         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
565       if (did_stdout == 1)
566         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
567       if (did_stderr == 1)
568         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
569
570       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
571         fprintf(complain,"%s: fatal: unable to reopen standard input,"
572                 " output, or error\n", pgmname);
573     }
574
575   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
576     exit (3);
577 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
578   (void)pgmname;
579 #endif
580 }
581
582
583 /* Hack required for Windows.  */
584 void
585 gnupg_allow_set_foregound_window (pid_t pid)
586 {
587   if (!pid)
588     log_info ("%s called with invalid pid %lu\n",
589               "gnupg_allow_set_foregound_window", (unsigned long)pid);
590 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
591   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
592     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
593                (unsigned long)pid, w32_strerror (-1));
594 #endif
595 }
596
597 int
598 gnupg_remove (const char *fname)
599 {
600 #ifdef HAVE_W32CE_SYSTEM
601   int rc;
602   wchar_t *wfname;
603
604   wfname = utf8_to_wchar (fname);
605   if (!wfname)
606     rc = 0;
607   else
608     {
609       rc = DeleteFile (wfname);
610       xfree (wfname);
611     }
612   if (!rc)
613     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
614   return 0;
615 #else
616   return remove (fname);
617 #endif
618 }
619
620
621 /* Wrapper for rename(2) to handle Windows peculiarities.  If
622  * BLOCK_SIGNALS is not NULL and points to a variable set to true, all
623  * signals will be blocked by calling gnupg_block_all_signals; the
624  * caller needs to call gnupg_unblock_all_signals if that variable is
625  * still set to true on return. */
626 gpg_error_t
627 gnupg_rename_file (const char *oldname, const char *newname, int *block_signals)
628 {
629   gpg_error_t err = 0;
630
631   if (block_signals && *block_signals)
632     gnupg_block_all_signals ();
633
634 #ifdef HAVE_DOSISH_SYSTEM
635   {
636     int wtime = 0;
637
638     gnupg_remove (newname);
639   again:
640     if (rename (oldname, newname))
641       {
642         if (GetLastError () == ERROR_SHARING_VIOLATION)
643           {
644             /* Another process has the file open.  We do not use a
645              * lock for read but instead we wait until the other
646              * process has closed the file.  This may take long but
647              * that would also be the case with a dotlock approach for
648              * read and write.  Note that we don't need this on Unix
649              * due to the inode concept.
650              *
651              * So let's wait until the rename has worked.  The retry
652              * intervals are 50, 100, 200, 400, 800, 50ms, ...  */
653             if (!wtime || wtime >= 800)
654               wtime = 50;
655             else
656               wtime *= 2;
657
658             if (wtime >= 800)
659               log_info (_("waiting for file '%s' to become accessible ...\n"),
660                         oldname);
661
662             Sleep (wtime);
663             goto again;
664           }
665         err = my_error_from_syserror ();
666       }
667   }
668 #else /* Unix */
669   {
670 #ifdef __riscos__
671     gnupg_remove (newname);
672 #endif
673     if (rename (oldname, newname) )
674       err = my_error_from_syserror ();
675   }
676 #endif /* Unix */
677
678   if (block_signals && *block_signals && err)
679     {
680       gnupg_unblock_all_signals ();
681       *block_signals = 0;
682     }
683
684   if (err)
685     log_error (_("renaming '%s' to '%s' failed: %s\n"),
686                oldname, newname, gpg_strerror (err));
687   return err;
688 }
689
690
691 #ifndef HAVE_W32_SYSTEM
692 static mode_t
693 modestr_to_mode (const char *modestr)
694 {
695   mode_t mode = 0;
696
697   if (modestr && *modestr)
698     {
699       modestr++;
700       if (*modestr && *modestr++ == 'r')
701         mode |= S_IRUSR;
702       if (*modestr && *modestr++ == 'w')
703         mode |= S_IWUSR;
704       if (*modestr && *modestr++ == 'x')
705         mode |= S_IXUSR;
706       if (*modestr && *modestr++ == 'r')
707         mode |= S_IRGRP;
708       if (*modestr && *modestr++ == 'w')
709         mode |= S_IWGRP;
710       if (*modestr && *modestr++ == 'x')
711         mode |= S_IXGRP;
712       if (*modestr && *modestr++ == 'r')
713         mode |= S_IROTH;
714       if (*modestr && *modestr++ == 'w')
715         mode |= S_IWOTH;
716       if (*modestr && *modestr++ == 'x')
717         mode |= S_IXOTH;
718     }
719
720   return mode;
721 }
722 #endif
723
724
725 /* A wrapper around mkdir which takes a string for the mode argument.
726    This makes it easier to handle the mode argument which is not
727    defined on all systems.  The format of the modestring is
728
729       "-rwxrwxrwx"
730
731    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
732    write allowed, execution allowed with the first group for the user,
733    the second for the group and the third for all others.  If the
734    string is shorter than above the missing mode characters are meant
735    to be not set.  */
736 int
737 gnupg_mkdir (const char *name, const char *modestr)
738 {
739 #ifdef HAVE_W32CE_SYSTEM
740   wchar_t *wname;
741   (void)modestr;
742
743   wname = utf8_to_wchar (name);
744   if (!wname)
745     return -1;
746   if (!CreateDirectoryW (wname, NULL))
747     {
748       xfree (wname);
749       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
750     }
751   xfree (wname);
752   return 0;
753 #elif MKDIR_TAKES_ONE_ARG
754   (void)modestr;
755   /* Note: In the case of W32 we better use CreateDirectory and try to
756      set appropriate permissions.  However using mkdir is easier
757      because this sets ERRNO.  */
758   return mkdir (name);
759 #else
760   return mkdir (name, modestr_to_mode (modestr));
761 #endif
762 }
763
764
765 /* A wrapper around chmod which takes a string for the mode argument.
766    This makes it easier to handle the mode argument which is not
767    defined on all systems.  The format of the modestring is the same
768    as for gnupg_mkdir.  */
769 int
770 gnupg_chmod (const char *name, const char *modestr)
771 {
772 #ifdef HAVE_W32_SYSTEM
773   (void)name;
774   (void)modestr;
775   return 0;
776 #else
777   return chmod (name, modestr_to_mode (modestr));
778 #endif
779 }
780
781
782 /* Our version of mkdtemp.  The API is identical to POSIX.1-2008
783    version.  We do not use a system provided mkdtemp because we have a
784    good RNG instantly available and this way we don't have diverging
785    versions.  */
786 char *
787 gnupg_mkdtemp (char *tmpl)
788 {
789   /* A lower bound on the number of temporary files to attempt to
790      generate.  The maximum total number of temporary file names that
791      can exist for a given template is 62**6 (5*36**3 for Windows).
792      It should never be necessary to try all these combinations.
793      Instead if a reasonable number of names is tried (we define
794      reasonable as 62**3 or 5*36**3) fail to give the system
795      administrator the chance to remove the problems.  */
796 #ifdef HAVE_W32_SYSTEM
797   static const char letters[] =
798     "abcdefghijklmnopqrstuvwxyz0123456789";
799 # define NUMBER_OF_LETTERS 36
800 # define ATTEMPTS_MIN (5 * 36 * 36 * 36)
801 #else
802   static const char letters[] =
803     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
804 # define NUMBER_OF_LETTERS 62
805 # define ATTEMPTS_MIN (62 * 62 * 62)
806 #endif
807   int len;
808   char *XXXXXX;
809   uint64_t value;
810   unsigned int count;
811   int save_errno = errno;
812   /* The number of times to attempt to generate a temporary file.  To
813      conform to POSIX, this must be no smaller than TMP_MAX.  */
814 #if ATTEMPTS_MIN < TMP_MAX
815   unsigned int attempts = TMP_MAX;
816 #else
817   unsigned int attempts = ATTEMPTS_MIN;
818 #endif
819
820   len = strlen (tmpl);
821   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
822     {
823       gpg_err_set_errno (EINVAL);
824       return NULL;
825     }
826
827   /* This is where the Xs start.  */
828   XXXXXX = &tmpl[len - 6];
829
830   /* Get a random start value.  */
831   gcry_create_nonce (&value, sizeof value);
832
833   /* Loop until a directory was created.  */
834   for (count = 0; count < attempts; value += 7777, ++count)
835     {
836       uint64_t v = value;
837
838       /* Fill in the random bits.  */
839       XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
840       v /= NUMBER_OF_LETTERS;
841       XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
842       v /= NUMBER_OF_LETTERS;
843       XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
844       v /= NUMBER_OF_LETTERS;
845       XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
846       v /= NUMBER_OF_LETTERS;
847       XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
848       v /= NUMBER_OF_LETTERS;
849       XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
850
851       if (!gnupg_mkdir (tmpl, "-rwx"))
852         {
853           gpg_err_set_errno (save_errno);
854           return tmpl;
855         }
856       if (errno != EEXIST)
857         return NULL;
858     }
859
860   /* We got out of the loop because we ran out of combinations to try.  */
861   gpg_err_set_errno (EEXIST);
862   return NULL;
863 }
864
865
866 int
867 gnupg_setenv (const char *name, const char *value, int overwrite)
868 {
869 #ifdef HAVE_W32CE_SYSTEM
870   (void)name;
871   (void)value;
872   (void)overwrite;
873   return 0;
874 #else /*!W32CE*/
875 # ifdef HAVE_W32_SYSTEM
876   /*  Windows maintains (at least) two sets of environment variables.
877       One set can be accessed by GetEnvironmentVariable and
878       SetEnvironmentVariable.  This set is inherited by the children.
879       The other set is maintained in the C runtime, and is accessed
880       using getenv and putenv.  We try to keep them in sync by
881       modifying both sets.  */
882   {
883     int exists;
884     char tmpbuf[10];
885     exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
886
887     if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
888       {
889         gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
890         return -1;
891       }
892   }
893 # endif /*W32*/
894
895 # ifdef HAVE_SETENV
896   return setenv (name, value, overwrite);
897 # else /*!HAVE_SETENV*/
898   if (! getenv (name) || overwrite)
899     {
900       char *buf;
901
902       (void)overwrite;
903       if (!name || !value)
904         {
905           gpg_err_set_errno (EINVAL);
906           return -1;
907         }
908       buf = strconcat (name, "=", value, NULL);
909       if (!buf)
910         return -1;
911 # if __GNUC__
912 #  warning no setenv - using putenv but leaking memory.
913 # endif
914       return putenv (buf);
915     }
916   return 0;
917 # endif /*!HAVE_SETENV*/
918 #endif /*!W32CE*/
919 }
920
921
922 int
923 gnupg_unsetenv (const char *name)
924 {
925 #ifdef HAVE_W32CE_SYSTEM
926   (void)name;
927   return 0;
928 #else /*!W32CE*/
929 # ifdef HAVE_W32_SYSTEM
930   /*  Windows maintains (at least) two sets of environment variables.
931       One set can be accessed by GetEnvironmentVariable and
932       SetEnvironmentVariable.  This set is inherited by the children.
933       The other set is maintained in the C runtime, and is accessed
934       using getenv and putenv.  We try to keep them in sync by
935       modifying both sets.  */
936   if (!SetEnvironmentVariable (name, NULL))
937     {
938       gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
939       return -1;
940     }
941 # endif /*W32*/
942
943 # ifdef HAVE_UNSETENV
944   return unsetenv (name);
945 # else /*!HAVE_UNSETENV*/
946   {
947     char *buf;
948
949     if (!name)
950       {
951         gpg_err_set_errno (EINVAL);
952         return -1;
953       }
954     buf = xtrystrdup (name);
955     if (!buf)
956       return -1;
957 #  if __GNUC__
958 #   warning no unsetenv - trying putenv but leaking memory.
959 #  endif
960     return putenv (buf);
961   }
962 # endif /*!HAVE_UNSETENV*/
963 #endif /*!W32CE*/
964 }
965
966
967 /* Return the current working directory as a malloced string.  Return
968    NULL and sets ERRNo on error.  */
969 char *
970 gnupg_getcwd (void)
971 {
972   char *buffer;
973   size_t size = 100;
974
975   for (;;)
976     {
977       buffer = xtrymalloc (size+1);
978       if (!buffer)
979         return NULL;
980 #ifdef HAVE_W32CE_SYSTEM
981       strcpy (buffer, "/");  /* Always "/".  */
982       return buffer;
983 #else
984       if (getcwd (buffer, size) == buffer)
985         return buffer;
986       xfree (buffer);
987       if (errno != ERANGE)
988         return NULL;
989       size *= 2;
990 #endif
991     }
992 }
993
994
995 \f
996 #ifdef HAVE_W32CE_SYSTEM
997 /* There is a isatty function declaration in cegcc but it does not
998    make sense, thus we redefine it.  */
999 int
1000 _gnupg_isatty (int fd)
1001 {
1002   (void)fd;
1003   return 0;
1004 }
1005 #endif
1006
1007
1008 #ifdef HAVE_W32CE_SYSTEM
1009 /* Replacement for getenv which takes care of the our use of getenv.
1010    The code is not thread safe but we expect it to work in all cases
1011    because it is called for the first time early enough.  */
1012 char *
1013 _gnupg_getenv (const char *name)
1014 {
1015   static int initialized;
1016   static char *assuan_debug;
1017
1018   if (!initialized)
1019     {
1020       assuan_debug = read_w32_registry_string (NULL,
1021                                                "\\Software\\GNU\\libassuan",
1022                                                "debug");
1023       initialized = 1;
1024     }
1025
1026   if (!strcmp (name, "ASSUAN_DEBUG"))
1027     return assuan_debug;
1028   else
1029     return NULL;
1030 }
1031
1032 #endif /*HAVE_W32CE_SYSTEM*/
1033
1034
1035 #ifdef HAVE_W32_SYSTEM
1036 /* Return the user's security identifier from the current process.  */
1037 PSID
1038 w32_get_user_sid (void)
1039 {
1040   int okay = 0;
1041   HANDLE proc = NULL;
1042   HANDLE token = NULL;
1043   TOKEN_USER *user = NULL;
1044   PSID sid = NULL;
1045   DWORD tokenlen, sidlen;
1046
1047   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
1048   if (!proc)
1049     goto leave;
1050
1051   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
1052     goto leave;
1053
1054   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
1055       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1056     goto leave;
1057
1058   user = xtrymalloc (tokenlen);
1059   if (!user)
1060     goto leave;
1061
1062   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
1063     goto leave;
1064   if (!IsValidSid (user->User.Sid))
1065     goto leave;
1066   sidlen = GetLengthSid (user->User.Sid);
1067   sid = xtrymalloc (sidlen);
1068   if (!sid)
1069     goto leave;
1070   if (!CopySid (sidlen, sid, user->User.Sid))
1071     goto leave;
1072   okay = 1;
1073
1074  leave:
1075   xfree (user);
1076   if (token)
1077     CloseHandle (token);
1078   if (proc)
1079     CloseHandle (proc);
1080
1081   if (!okay)
1082     {
1083       xfree (sid);
1084       sid = NULL;
1085     }
1086   return sid;
1087 }
1088 #endif /*HAVE_W32_SYSTEM*/
1089
1090
1091 \f
1092 /* Support for inotify under Linux.  */
1093
1094 /* Store a new inotify file handle for SOCKET_NAME at R_FD or return
1095  * an error code. */
1096 gpg_error_t
1097 gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
1098 {
1099 #if HAVE_INOTIFY_INIT
1100   gpg_error_t err;
1101   char *fname;
1102   int fd;
1103   char *p;
1104
1105   *r_fd = -1;
1106
1107   if (!socket_name)
1108     return my_error (GPG_ERR_INV_VALUE);
1109
1110   fname = xtrystrdup (socket_name);
1111   if (!fname)
1112     return my_error_from_syserror ();
1113
1114   fd = inotify_init ();
1115   if (fd == -1)
1116     {
1117       err = my_error_from_syserror ();
1118       xfree (fname);
1119       return err;
1120     }
1121
1122   /* We need to watch the directory for the file because there won't
1123    * be an IN_DELETE_SELF for a socket file.  To handle a removal of
1124    * the directory we also watch the directory itself. */
1125   p = strrchr (fname, '/');
1126   if (p)
1127     *p = 0;
1128   if (inotify_add_watch (fd, fname,
1129                          (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
1130     {
1131       err = my_error_from_syserror ();
1132       close (fd);
1133       xfree (fname);
1134       return err;
1135     }
1136
1137   xfree (fname);
1138
1139   *r_fd = fd;
1140   return 0;
1141 #else /*!HAVE_INOTIFY_INIT*/
1142
1143   (void)socket_name;
1144   *r_fd = -1;
1145   return my_error (GPG_ERR_NOT_SUPPORTED);
1146
1147 #endif /*!HAVE_INOTIFY_INIT*/
1148 }
1149
1150
1151 /* Read an inotify event and return true if it matches NAME or if it
1152  * sees an IN_DELETE_SELF event for the directory of NAME.  */
1153 int
1154 gnupg_inotify_has_name (int fd, const char *name)
1155 {
1156 #if USE_NPTH && HAVE_INOTIFY_INIT
1157 #define BUFSIZE_FOR_INOTIFY (sizeof (struct inotify_event) + 255 + 1)
1158   union {
1159     struct inotify_event ev;
1160     char _buf[sizeof (struct inotify_event) + 255 + 1];
1161   } buf;
1162   struct inotify_event *evp;
1163   int n;
1164
1165   n = npth_read (fd, &buf, sizeof buf);
1166   /* log_debug ("notify read: n=%d\n", n); */
1167   evp = &buf.ev;
1168   while (n >= sizeof (struct inotify_event))
1169     {
1170       /* log_debug ("             mask=%x len=%u name=(%s)\n", */
1171       /*        evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
1172       if ((evp->mask & IN_UNMOUNT))
1173         {
1174           /* log_debug ("             found (dir unmounted)\n"); */
1175           return 3; /* Directory was unmounted.  */
1176         }
1177       if ((evp->mask & IN_DELETE_SELF))
1178         {
1179           /* log_debug ("             found (dir removed)\n"); */
1180           return 2; /* Directory was removed.  */
1181         }
1182       if ((evp->mask & IN_DELETE))
1183         {
1184           if (evp->len >= strlen (name) && !strcmp (evp->name, name))
1185             {
1186               /* log_debug ("             found (file removed)\n"); */
1187               return 1; /* File was removed.  */
1188             }
1189         }
1190       n -= sizeof (*evp) + evp->len;
1191       evp = (struct inotify_event *)(void *)
1192         ((char *)evp + sizeof (*evp) + evp->len);
1193     }
1194
1195 #else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1196
1197   (void)fd;
1198   (void)name;
1199
1200 #endif  /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1201
1202   return 0; /* Not found.  */
1203 }
1204
1205
1206 /* Return a malloc'ed string that is the path to the passed
1207  * unix-domain socket (or return NULL if this is not a valid
1208  * unix-domain socket).  We use a plain int here because it is only
1209  * used on Linux.
1210  *
1211  * FIXME: This function needs to be moved to libassuan.  */
1212 #ifndef HAVE_W32_SYSTEM
1213 char *
1214 gnupg_get_socket_name (int fd)
1215 {
1216   struct sockaddr_un un;
1217   socklen_t len = sizeof(un);
1218   char *name = NULL;
1219
1220   if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
1221     log_error ("could not getsockname(%d): %s\n", fd,
1222                gpg_strerror (my_error_from_syserror ()));
1223   else if (un.sun_family != AF_UNIX)
1224     log_error ("file descriptor %d is not a unix-domain socket\n", fd);
1225   else if (len <= offsetof (struct sockaddr_un, sun_path))
1226     log_error ("socket name not present for file descriptor %d\n", fd);
1227   else if (len > sizeof(un))
1228     log_error ("socket name for file descriptor %d was truncated "
1229                "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
1230   else
1231     {
1232       size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
1233
1234       /* log_debug ("file descriptor %d has path %s (%zu octets)\n", fd, */
1235       /*            un.sun_path, namelen); */
1236       name = xtrymalloc (namelen + 1);
1237       if (!name)
1238         log_error ("failed to allocate memory for name of fd %d: %s\n",
1239                    fd, gpg_strerror (my_error_from_syserror ()));
1240       else
1241         {
1242           memcpy (name, un.sun_path, namelen);
1243           name[namelen] = 0;
1244         }
1245     }
1246
1247   return name;
1248 }
1249 #endif /*!HAVE_W32_SYSTEM*/