~ubuntu-branches/ubuntu/natty/gnupg2/natty-security

« back to all changes in this revision

Viewing changes to gl/mkdtemp.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Urlichs
  • Date: 2005-12-08 22:13:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208221321-4rvs2vu835iam5wv
Tags: 1.9.19-2
* Convert debian/changelog to UTF-8.
* Put gnupg-agent and gpgsm lintian overrides in the respectively
  right package.  Closes: #335066
* Added debhelper tokens to maintainer scripts.
* xsession fixes:
  o Added host name to gpg-agent PID file name.  Closes: #312717
  o Fixed xsession script to be able to run under zsh.  Closes: #308516
  o Don't run gpg-agent if one is already running.  Closes: #336480
* debian/control:
  o Fixed package description of gpgsm package.  Closes: #299842
  o Added mention of gpg-agent to description of gnupg-agent package.
    Closes: #304355
* Thanks to Peter Eisentraut <petere@debian.org> for all of the above.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 1999, 2001-2003 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation; either version 2, or (at your option)
 
7
   any later version.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU General Public License along
 
15
   with this program; if not, write to the Free Software Foundation,
 
16
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
17
 
 
18
/* Extracted from misc/mkdtemp.c and sysdeps/posix/tempname.c.  */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
# include "config.h"
 
22
#endif
 
23
 
 
24
/* Specification.  */
 
25
#include "mkdtemp.h"
 
26
 
 
27
#include <errno.h>
 
28
#ifndef __set_errno
 
29
# define __set_errno(Val) errno = (Val)
 
30
#endif
 
31
 
 
32
#include <stddef.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
 
 
36
#include <stdio.h>
 
37
#ifndef TMP_MAX
 
38
# define TMP_MAX 238328
 
39
#endif
 
40
 
 
41
#if HAVE_STDINT_H || _LIBC
 
42
# include <stdint.h>
 
43
#endif
 
44
#if HAVE_INTTYPES_H
 
45
# include <inttypes.h>
 
46
#endif
 
47
 
 
48
#if HAVE_UNISTD_H || _LIBC
 
49
# include <unistd.h>
 
50
#endif
 
51
 
 
52
#if HAVE_GETTIMEOFDAY || _LIBC
 
53
# if HAVE_SYS_TIME_H || _LIBC
 
54
#  include <sys/time.h>
 
55
# endif
 
56
#else
 
57
# if HAVE_TIME_H || _LIBC
 
58
#  include <time.h>
 
59
# endif
 
60
#endif
 
61
 
 
62
#include <sys/stat.h>
 
63
#if STAT_MACROS_BROKEN
 
64
# undef S_ISDIR
 
65
#endif
 
66
#if !defined S_ISDIR && defined S_IFDIR
 
67
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
 
68
#endif
 
69
#if !S_IRUSR && S_IREAD
 
70
# define S_IRUSR S_IREAD
 
71
#endif
 
72
#if !S_IRUSR
 
73
# define S_IRUSR 00400
 
74
#endif
 
75
#if !S_IWUSR && S_IWRITE
 
76
# define S_IWUSR S_IWRITE
 
77
#endif
 
78
#if !S_IWUSR
 
79
# define S_IWUSR 00200
 
80
#endif
 
81
#if !S_IXUSR && S_IEXEC
 
82
# define S_IXUSR S_IEXEC
 
83
#endif
 
84
#if !S_IXUSR
 
85
# define S_IXUSR 00100
 
86
#endif
 
87
 
 
88
#ifdef __MINGW32__
 
89
/* mingw's mkdir() function has 1 argument, but we pass 2 arguments.
 
90
   Therefore we have to disable the argument count checking.  */
 
91
# define mkdir ((int (*)()) mkdir)
 
92
#endif
 
93
 
 
94
#if !_LIBC
 
95
# define __getpid getpid
 
96
# define __gettimeofday gettimeofday
 
97
# define __mkdir mkdir
 
98
#endif
 
99
 
 
100
/* Use the widest available unsigned type if uint64_t is not
 
101
   available.  The algorithm below extracts a number less than 62**6
 
102
   (approximately 2**35.725) from uint64_t, so ancient hosts where
 
103
   uintmax_t is only 32 bits lose about 3.725 bits of randomness,
 
104
   which is better than not having mkstemp at all.  */
 
105
#if !defined UINT64_MAX && !defined uint64_t
 
106
# define uint64_t uintmax_t
 
107
#endif
 
108
 
 
109
/* These are the characters used in temporary filenames.  */
 
110
static const char letters[] =
 
111
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
112
 
 
113
/* Generate a temporary file name based on TMPL.  TMPL must match the
 
114
   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
 
115
   does not exist at the time of the call to __gen_tempname.  TMPL is
 
116
   overwritten with the result.
 
117
 
 
118
   KIND is:
 
119
   __GT_DIR:            create a directory, which will be mode 0700.
 
120
 
 
121
   We use a clever algorithm to get hard-to-predict names. */
 
122
static int
 
123
gen_tempname (char *tmpl)
 
124
{
 
125
  int len;
 
126
  char *XXXXXX;
 
127
  static uint64_t value;
 
128
  uint64_t random_time_bits;
 
129
  int count, fd = -1;
 
130
  int save_errno = errno;
 
131
 
 
132
  len = strlen (tmpl);
 
133
  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
 
134
    {
 
135
      __set_errno (EINVAL);
 
136
      return -1;
 
137
    }
 
138
 
 
139
  /* This is where the Xs start.  */
 
140
  XXXXXX = &tmpl[len - 6];
 
141
 
 
142
  /* Get some more or less random data.  */
 
143
#ifdef RANDOM_BITS
 
144
  RANDOM_BITS (random_time_bits);
 
145
#else
 
146
# if HAVE_GETTIMEOFDAY || _LIBC
 
147
  {
 
148
    struct timeval tv;
 
149
    __gettimeofday (&tv, NULL);
 
150
    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
 
151
  }
 
152
# else
 
153
  random_time_bits = time (NULL);
 
154
# endif
 
155
#endif
 
156
  value += random_time_bits ^ __getpid ();
 
157
 
 
158
  for (count = 0; count < TMP_MAX; value += 7777, ++count)
 
159
    {
 
160
      uint64_t v = value;
 
161
 
 
162
      /* Fill in the random bits.  */
 
163
      XXXXXX[0] = letters[v % 62];
 
164
      v /= 62;
 
165
      XXXXXX[1] = letters[v % 62];
 
166
      v /= 62;
 
167
      XXXXXX[2] = letters[v % 62];
 
168
      v /= 62;
 
169
      XXXXXX[3] = letters[v % 62];
 
170
      v /= 62;
 
171
      XXXXXX[4] = letters[v % 62];
 
172
      v /= 62;
 
173
      XXXXXX[5] = letters[v % 62];
 
174
 
 
175
      fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
 
176
 
 
177
      if (fd >= 0)
 
178
        {
 
179
          __set_errno (save_errno);
 
180
          return fd;
 
181
        }
 
182
      else if (errno != EEXIST)
 
183
        return -1;
 
184
    }
 
185
 
 
186
  /* We got out of the loop because we ran out of combinations to try.  */
 
187
  __set_errno (EEXIST);
 
188
  return -1;
 
189
}
 
190
 
 
191
/* Generate a unique temporary directory from TEMPLATE.
 
192
   The last six characters of TEMPLATE must be "XXXXXX";
 
193
   they are replaced with a string that makes the filename unique.
 
194
   The directory is created, mode 700, and its name is returned.
 
195
   (This function comes from OpenBSD.) */
 
196
char *
 
197
mkdtemp (char *template)
 
198
{
 
199
  if (gen_tempname (template))
 
200
    return NULL;
 
201
  else
 
202
    return template;
 
203
}