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