Line data Source code
1 : /* openfile.c
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
3 : * 2010 Free Software Foundation, Inc.
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <assert.h>
26 : #include <errno.h>
27 : #include <sys/types.h>
28 : #include <sys/stat.h>
29 : #include <fcntl.h>
30 : #include <unistd.h>
31 :
32 : #include "gpg.h"
33 : #include "util.h"
34 : #include "ttyio.h"
35 : #include "options.h"
36 : #include "main.h"
37 : #include "status.h"
38 : #include "i18n.h"
39 :
40 : #ifdef USE_ONLY_8DOT3
41 : #define SKELEXT ".skl"
42 : #else
43 : #define SKELEXT EXTSEP_S "skel"
44 : #endif
45 :
46 : #ifdef HAVE_W32_SYSTEM
47 : #define NAME_OF_DEV_NULL "nul"
48 : #else
49 : #define NAME_OF_DEV_NULL "/dev/null"
50 : #endif
51 :
52 :
53 : #if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
54 : #define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
55 : #else
56 : #define CMP_FILENAME(a,b) strcmp( (a), (b) )
57 : #endif
58 :
59 :
60 : /* FIXME: Implement opt.interactive. */
61 :
62 : /*
63 : * Check whether FNAME exists and ask if it's okay to overwrite an
64 : * existing one.
65 : * Returns: True: it's okay to overwrite or the file does not exist
66 : * False: Do not overwrite
67 : */
68 : int
69 1038 : overwrite_filep( const char *fname )
70 : {
71 1038 : if ( iobuf_is_pipe_filename (fname) )
72 0 : return 1; /* Writing to stdout is always okay. */
73 :
74 1038 : if ( access( fname, F_OK ) )
75 3 : return 1; /* Does not exist. */
76 :
77 1035 : if ( !compare_filenames (fname, NAME_OF_DEV_NULL) )
78 0 : return 1; /* Does not do any harm. */
79 :
80 1035 : if (opt.answer_yes)
81 1035 : return 1;
82 0 : if (opt.answer_no || opt.batch)
83 0 : return 0; /* Do not overwrite. */
84 :
85 0 : tty_printf (_("File '%s' exists. "), fname);
86 0 : if (cpr_enabled ())
87 0 : tty_printf ("\n");
88 0 : if (cpr_get_answer_is_yes ("openfile.overwrite.okay",
89 0 : _("Overwrite? (y/N) ")) )
90 0 : return 1;
91 0 : return 0;
92 : }
93 :
94 :
95 : /*
96 : * Strip known extensions from iname and return a newly allocated
97 : * filename. Return NULL if we can't do that.
98 : */
99 : char *
100 14 : make_outfile_name (const char *iname)
101 : {
102 : size_t n;
103 :
104 14 : if (iobuf_is_pipe_filename (iname))
105 14 : return xstrdup ("-");
106 :
107 0 : n = strlen (iname);
108 0 : if (n > 4 && (!CMP_FILENAME(iname+n-4, EXTSEP_S GPGEXT_GPG)
109 0 : || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
110 0 : || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
111 0 : || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc")))
112 : {
113 0 : char *buf = xstrdup (iname);
114 0 : buf[n-4] = 0;
115 0 : return buf;
116 : }
117 0 : else if (n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign"))
118 : {
119 0 : char *buf = xstrdup (iname);
120 0 : buf[n-5] = 0;
121 0 : return buf;
122 : }
123 :
124 0 : log_info (_("%s: unknown suffix\n"), iname);
125 0 : return NULL;
126 : }
127 :
128 :
129 : /* Ask for an output filename; use the given one as default. Return
130 : NULL if no file has been given or if it is not possible to ask the
131 : user. NAME is the template len which might conatin enbedded Nuls.
132 : NAMELEN is its actual length.
133 : */
134 : char *
135 0 : ask_outfile_name( const char *name, size_t namelen )
136 : {
137 : size_t n;
138 : const char *s;
139 : char *prompt;
140 : char *fname;
141 : char *defname;
142 :
143 0 : if ( opt.batch )
144 0 : return NULL;
145 :
146 0 : defname = name && namelen? make_printable_string (name, namelen, 0) : NULL;
147 :
148 0 : s = _("Enter new filename");
149 0 : n = strlen(s) + (defname?strlen (defname):0) + 10;
150 0 : prompt = xmalloc (n);
151 0 : if (defname)
152 0 : snprintf (prompt, n-1, "%s [%s]: ", s, defname );
153 : else
154 0 : snprintf (prompt, n-1, "%s: ", s );
155 : tty_enable_completion(NULL);
156 0 : fname = cpr_get ("openfile.askoutname", prompt );
157 0 : cpr_kill_prompt ();
158 : tty_disable_completion ();
159 0 : xfree (prompt);
160 0 : if ( !*fname )
161 : {
162 0 : xfree (fname);
163 0 : fname = defname;
164 0 : defname = NULL;
165 : }
166 0 : xfree (defname);
167 0 : if (fname)
168 0 : trim_spaces (fname);
169 0 : return fname;
170 : }
171 :
172 :
173 : /*
174 : * Make an output filename for the inputfile INAME.
175 : * Returns an IOBUF and an errorcode
176 : * Mode 0 = use ".gpg"
177 : * 1 = use ".asc"
178 : * 2 = use ".sig"
179 : * 3 = use ".rev"
180 : *
181 : * If INP_FD is not -1 the function simply creates an IOBUF for that
182 : * file descriptor and ignore INAME and MODE. Note that INP_FD won't
183 : * be closed if the returned IOBUF is closed. With RESTRICTEDPERM a
184 : * file will be created with mode 700 if possible.
185 : */
186 : int
187 558 : open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
188 : iobuf_t *a)
189 : {
190 558 : int rc = 0;
191 :
192 558 : *a = NULL;
193 558 : if (inp_fd != -1)
194 : {
195 : char xname[64];
196 :
197 0 : *a = iobuf_fdopen_nc (inp_fd, "wb");
198 0 : if (!*a)
199 : {
200 0 : rc = gpg_error_from_syserror ();
201 0 : snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
202 0 : log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc));
203 : }
204 0 : else if (opt.verbose)
205 : {
206 0 : snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
207 0 : log_info (_("writing to '%s'\n"), xname);
208 : }
209 : }
210 558 : else if (iobuf_is_pipe_filename (iname) && !opt.outfile)
211 : {
212 34 : *a = iobuf_create (NULL, 0);
213 68 : if ( !*a )
214 : {
215 0 : rc = gpg_error_from_syserror ();
216 0 : log_error (_("can't open '%s': %s\n"), "[stdout]", strerror(errno) );
217 : }
218 34 : else if ( opt.verbose )
219 0 : log_info (_("writing to stdout\n"));
220 : }
221 : else
222 : {
223 524 : char *buf = NULL;
224 : const char *name;
225 :
226 524 : if (opt.dry_run)
227 0 : name = NAME_OF_DEV_NULL;
228 524 : else if (opt.outfile)
229 522 : name = opt.outfile;
230 : else
231 : {
232 : #ifdef USE_ONLY_8DOT3
233 : if (opt.mangle_dos_filenames)
234 : {
235 : /* It is quite common for DOS systems to have only one
236 : dot in a filename. If we have something like this,
237 : we simple replace the suffix except in cases where
238 : the suffix is larger than 3 characters and not the
239 : same as the new one. We don't map the filenames to
240 : 8.3 because this is a duty of the file system. */
241 : char *dot;
242 : const char *newsfx;
243 :
244 : newsfx = (mode==1 ? ".asc" :
245 : mode==2 ? ".sig" :
246 : mode==3 ? ".rev" : ".gpg");
247 :
248 : buf = xmalloc (strlen(iname)+4+1);
249 : strcpy (buf, iname);
250 : dot = strchr (buf, '.' );
251 : if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
252 : && CMP_FILENAME (newsfx, dot) )
253 : strcpy (dot, newsfx);
254 : else if (dot && !dot[1]) /* Do not duplicate a dot. */
255 : strcpy (dot, newsfx+1);
256 : else
257 : strcat (buf, newsfx);
258 : }
259 : if (!buf)
260 : #endif /* USE_ONLY_8DOT3 */
261 : {
262 4 : buf = xstrconcat (iname,
263 : (mode==1 ? EXTSEP_S "asc" :
264 4 : mode==2 ? EXTSEP_S "sig" :
265 2 : mode==3 ? EXTSEP_S "rev" :
266 : /* */ EXTSEP_S GPGEXT_GPG),
267 : NULL);
268 : }
269 2 : name = buf;
270 : }
271 :
272 524 : rc = 0;
273 1048 : while ( !overwrite_filep (name) )
274 : {
275 0 : char *tmp = ask_outfile_name (NULL, 0);
276 0 : if ( !tmp || !*tmp )
277 : {
278 0 : xfree (tmp);
279 0 : rc = gpg_error (GPG_ERR_EEXIST);
280 0 : break;
281 : }
282 0 : xfree (buf);
283 0 : name = buf = tmp;
284 : }
285 :
286 524 : if ( !rc )
287 : {
288 524 : if (is_secured_filename (name) )
289 : {
290 0 : *a = NULL;
291 0 : gpg_err_set_errno (EPERM);
292 : }
293 : else
294 524 : *a = iobuf_create (name, restrictedperm);
295 524 : if (!*a)
296 : {
297 0 : rc = gpg_error_from_syserror ();
298 0 : log_error(_("can't create '%s': %s\n"), name, strerror(errno) );
299 : }
300 524 : else if( opt.verbose )
301 0 : log_info (_("writing to '%s'\n"), name );
302 : }
303 524 : xfree(buf);
304 : }
305 :
306 558 : if (*a)
307 558 : iobuf_ioctl (*a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
308 :
309 558 : return rc;
310 : }
311 :
312 :
313 : /* Find a matching data file for the signature file SIGFILENAME and
314 : return it as a malloced string. If no matching data file is found,
315 : return NULL. */
316 : char *
317 159 : get_matching_datafile (const char *sigfilename)
318 : {
319 159 : char *fname = NULL;
320 : size_t len;
321 :
322 159 : if (iobuf_is_pipe_filename (sigfilename))
323 109 : return NULL;
324 :
325 50 : len = strlen (sigfilename);
326 50 : if (len > 4
327 6 : && (!strcmp (sigfilename + len - 4, EXTSEP_S "sig")
328 6 : || (len > 5 && !strcmp(sigfilename + len - 5, EXTSEP_S "sign"))
329 6 : || !strcmp(sigfilename + len - 4, EXTSEP_S "asc")))
330 : {
331 :
332 0 : fname = xstrdup (sigfilename);
333 0 : fname[len-(fname[len-1]=='n'?5:4)] = 0 ;
334 0 : if (access (fname, R_OK ))
335 : {
336 : /* Not found or other error. */
337 0 : xfree (fname);
338 0 : fname = NULL;
339 : }
340 : }
341 :
342 50 : return fname;
343 : }
344 :
345 :
346 : /*
347 : * Try to open a file without the extension ".sig" or ".asc"
348 : * Return NULL if such a file is not available.
349 : */
350 : iobuf_t
351 16 : open_sigfile (const char *sigfilename, progress_filter_context_t *pfx)
352 : {
353 16 : iobuf_t a = NULL;
354 : char *buf;
355 :
356 16 : buf = get_matching_datafile (sigfilename);
357 16 : if (buf)
358 : {
359 0 : a = iobuf_open (buf);
360 0 : if (a && is_secured_file (iobuf_get_fd (a)))
361 : {
362 0 : iobuf_close (a);
363 0 : a = NULL;
364 0 : gpg_err_set_errno (EPERM);
365 : }
366 0 : if (a)
367 0 : log_info (_("assuming signed data in '%s'\n"), buf);
368 0 : if (a && pfx)
369 0 : handle_progress (pfx, a, buf);
370 0 : xfree (buf);
371 : }
372 :
373 16 : return a;
374 : }
375 :
376 :
377 : /****************
378 : * Copy the option file skeleton for NAME to the given directory.
379 : * Returns true if the new option file has any option.
380 : */
381 : static int
382 0 : copy_options_file (const char *destdir, const char *name)
383 : {
384 0 : const char *datadir = gnupg_datadir ();
385 : char *fname;
386 : FILE *src, *dst;
387 0 : int linefeeds=0;
388 : int c;
389 : mode_t oldmask;
390 0 : int esc = 0;
391 0 : int any_option = 0;
392 :
393 0 : if (opt.dry_run)
394 0 : return 0;
395 :
396 0 : fname = xstrconcat (datadir, DIRSEP_S, name, "-conf", SKELEXT, NULL);
397 0 : src = fopen (fname, "r");
398 0 : if (src && is_secured_file (fileno (src)))
399 : {
400 0 : fclose (src);
401 0 : src = NULL;
402 0 : gpg_err_set_errno (EPERM);
403 : }
404 0 : if (!src)
405 : {
406 0 : log_info (_("can't open '%s': %s\n"), fname, strerror(errno));
407 0 : xfree(fname);
408 0 : return 0;
409 : }
410 0 : xfree (fname);
411 0 : fname = xstrconcat (destdir, DIRSEP_S, name, EXTSEP_S, "conf", NULL);
412 :
413 0 : oldmask = umask (077);
414 0 : if (is_secured_filename (fname))
415 : {
416 0 : dst = NULL;
417 0 : gpg_err_set_errno (EPERM);
418 : }
419 : else
420 0 : dst = fopen( fname, "w" );
421 0 : umask (oldmask);
422 :
423 0 : if (!dst)
424 : {
425 0 : log_info (_("can't create '%s': %s\n"), fname, strerror(errno) );
426 0 : fclose (src);
427 0 : xfree (fname);
428 0 : return 0;
429 : }
430 :
431 0 : while ((c = getc (src)) != EOF)
432 : {
433 0 : if (linefeeds < 3)
434 : {
435 0 : if (c == '\n')
436 0 : linefeeds++;
437 : }
438 : else
439 : {
440 0 : putc (c, dst);
441 0 : if (c== '\n')
442 0 : esc = 1;
443 0 : else if (esc == 1)
444 : {
445 0 : if (c == ' ' || c == '\t')
446 : ;
447 0 : else if (c == '#')
448 0 : esc = 2;
449 : else
450 0 : any_option = 1;
451 : }
452 : }
453 : }
454 :
455 0 : fclose (dst);
456 0 : fclose (src);
457 :
458 0 : log_info (_("new configuration file '%s' created\n"), fname);
459 0 : xfree (fname);
460 0 : return any_option;
461 : }
462 :
463 :
464 : void
465 0 : try_make_homedir (const char *fname)
466 : {
467 0 : const char *defhome = standard_homedir ();
468 :
469 : /* Create the directory only if the supplied directory name is the
470 : same as the default one. This way we avoid to create arbitrary
471 : directories when a non-default home directory is used. To cope
472 : with HOME, we do compare only the suffix if we see that the
473 : default homedir does start with a tilde. */
474 0 : if ( opt.dry_run || opt.no_homedir_creation )
475 0 : return;
476 :
477 0 : if (
478 : #ifdef HAVE_W32_SYSTEM
479 : ( !compare_filenames (fname, defhome) )
480 : #else
481 0 : ( *defhome == '~'
482 0 : && (strlen(fname) >= strlen (defhome+1)
483 0 : && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
484 0 : || (*defhome != '~' && !compare_filenames( fname, defhome ) )
485 : #endif
486 : )
487 : {
488 0 : if (gnupg_mkdir (fname, "-rwx"))
489 0 : log_fatal ( _("can't create directory '%s': %s\n"),
490 0 : fname, strerror(errno) );
491 0 : else if (!opt.quiet )
492 0 : log_info ( _("directory '%s' created\n"), fname );
493 :
494 : /* Note that we also copy a dirmngr.conf file here. This is
495 : because gpg is likely the first invoked tool and thus creates
496 : the directory. */
497 0 : copy_options_file (fname, DIRMNGR_NAME);
498 0 : if (copy_options_file (fname, GPG_NAME))
499 0 : log_info (_("WARNING: options in '%s'"
500 : " are not yet active during this run\n"),
501 : fname);
502 : }
503 : }
504 :
505 :
506 : /* Get and if needed create a string with the directory used to store
507 : openpgp revocations. */
508 : char *
509 2 : get_openpgp_revocdir (const char *home)
510 : {
511 : char *fname;
512 : struct stat statbuf;
513 :
514 2 : fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL);
515 2 : if (stat (fname, &statbuf) && errno == ENOENT)
516 : {
517 1 : if (gnupg_mkdir (fname, "-rwx"))
518 0 : log_error (_("can't create directory '%s': %s\n"),
519 0 : fname, strerror (errno) );
520 1 : else if (!opt.quiet)
521 0 : log_info (_("directory '%s' created\n"), fname);
522 : }
523 2 : return fname;
524 : }
|