gpg: Make the use of "--verify FILE" for detached sigs harder.
[gnupg.git] / g10 / openfile.c
1 /* openfile.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005 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 #if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
47 #define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
48 #else
49 #define CMP_FILENAME(a,b) strcmp( (a), (b) )
50 #endif
51
52 #ifdef MKDIR_TAKES_ONE_ARG
53 #undef mkdir
54 #define mkdir(a,b) mkdir(a)
55 #endif
56
57 /* FIXME:  Implement opt.interactive. */
58
59 /****************
60  * Check whether FNAME exists and ask if it's okay to overwrite an
61  * existing one.
62  * Returns: True: it's okay to overwrite or the file does not exist
63  *          False: Do not overwrite
64  */
65 int
66 overwrite_filep( const char *fname )
67 {
68     if( iobuf_is_pipe_filename (fname) )
69         return 1; /* Writing to stdout is always okay */
70
71     if( access( fname, F_OK ) )
72         return 1; /* does not exist */
73
74 #ifndef HAVE_DOSISH_SYSTEM
75     if ( !strcmp ( fname, "/dev/null" ) )
76         return 1; /* does not do any harm */
77 #endif
78 #ifdef HAVE_W32_SYSTEM
79     if ( !strcmp ( fname, "nul" ) )
80         return 1;
81 #endif
82
83     /* fixme: add some backup stuff in case of overwrite */
84     if( opt.answer_yes )
85         return 1;
86     if( opt.answer_no || opt.batch )
87         return 0;  /* do not overwrite */
88
89     tty_printf(_("File `%s' exists. "), fname);
90     if( cpr_enabled () )
91         tty_printf ("\n");
92     if( cpr_get_answer_is_yes("openfile.overwrite.okay",
93                                _("Overwrite? (y/N) ")) )
94         return 1;
95     return 0;
96 }
97
98
99 /****************
100  * Strip known extensions from iname and return a newly allocated
101  * filename.  Return NULL if we can't do that.
102  */
103 char *
104 make_outfile_name( const char *iname )
105 {
106     size_t n;
107
108     if ( iobuf_is_pipe_filename (iname) )
109         return xstrdup("-");
110
111     n = strlen(iname);
112     if( n > 4 && (    !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
113                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
114                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
115                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
116         char *buf = xstrdup( iname );
117         buf[n-4] = 0;
118         return buf;
119     }
120     else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
121         char *buf = xstrdup( iname );
122         buf[n-5] = 0;
123         return buf;
124     }
125
126     log_info(_("%s: unknown suffix\n"), iname );
127     return NULL;
128 }
129
130
131 /* Ask for an output filename; use the given one as default.  Return
132    NULL if no file has been given or if it is not possible to ask the
133    user.  NAME is the template len which might conatin enbedded Nuls.
134    NAMELEN is its actual length.
135  */
136 char *
137 ask_outfile_name( const char *name, size_t namelen )
138 {
139   size_t n;
140   const char *s;
141   char *prompt;
142   char *fname;
143   char *defname;
144
145   if ( opt.batch )
146     return NULL;
147
148   defname = name && namelen? make_printable_string (name, namelen, 0) : NULL;
149
150   s = _("Enter new filename");
151   n = strlen(s) + (defname?strlen (defname):0) + 10;
152   prompt = xmalloc (n);
153   if (defname)
154     snprintf (prompt, n-1, "%s [%s]: ", s, defname );
155   else
156     snprintf (prompt, n-1, "%s: ", s );
157   tty_enable_completion(NULL);
158   fname = cpr_get ("openfile.askoutname", prompt );
159   cpr_kill_prompt ();
160   tty_disable_completion ();
161   xfree (prompt);
162   if ( !*fname )
163     {
164       xfree (fname);
165       fname = defname;
166       defname = NULL;
167     }
168   xfree (defname);
169   if (fname)
170     trim_spaces (fname);
171   return fname;
172 }
173
174
175 /****************
176  * Make an output filename for the inputfile INAME.
177  * Returns an IOBUF and an errorcode
178  * Mode 0 = use ".gpg"
179  *      1 = use ".asc"
180  *      2 = use ".sig"
181  */
182 int
183 open_outfile( const char *iname, int mode, IOBUF *a )
184 {
185   int rc = 0;
186
187   *a = NULL;
188   if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
189     *a = iobuf_create(NULL);
190     if( !*a ) {
191       rc = gpg_error_from_syserror ();
192       log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
193     }
194     else if( opt.verbose )
195       log_info(_("writing to stdout\n"));
196   }
197   else {
198     char *buf = NULL;
199     const char *name;
200
201     if ( opt.dry_run )
202       {
203 #ifdef HAVE_W32_SYSTEM
204         name = "nul";
205 #else
206         name = "/dev/null";
207 #endif
208       }
209     else if( opt.outfile )
210       name = opt.outfile;
211     else {
212 #ifdef USE_ONLY_8DOT3
213       if (opt.mangle_dos_filenames)
214         {
215           /* It is quite common DOS system to have only one dot in a
216            * a filename So if we have something like this, we simple
217            * replace the suffix execpt in cases where the suffix is
218            * larger than 3 characters and not the same as.
219            * We should really map the filenames to 8.3 but this tends to
220            * be more complicated and is probaly a duty of the filesystem
221            */
222           char *dot;
223           const char *newsfx = mode==1 ? ".asc" :
224                                mode==2 ? ".sig" : ".gpg";
225
226           buf = xmalloc(strlen(iname)+4+1);
227           strcpy(buf,iname);
228           dot = strchr(buf, '.' );
229           if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
230                                   && CMP_FILENAME(newsfx, dot) )
231             {
232               strcpy(dot, newsfx );
233             }
234           else if ( dot && !dot[1] ) /* don't duplicate a dot */
235             strcpy( dot, newsfx+1 );
236           else
237             strcat ( buf, newsfx );
238         }
239       if (!buf)
240 #endif /* USE_ONLY_8DOT3 */
241         {
242           buf = xmalloc(strlen(iname)+4+1);
243           strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
244                                    mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
245         }
246       name = buf;
247     }
248
249     rc = 0;
250     while( !overwrite_filep (name) )
251       {
252         char *tmp = ask_outfile_name (NULL, 0);
253         if ( !tmp || !*tmp )
254           {
255             xfree (tmp);
256             rc = gpg_error (GPG_ERR_EEXIST);
257             break;
258           }
259         xfree (buf);
260         name = buf = tmp;
261       }
262
263     if( !rc )
264       {
265         if (is_secured_filename (name) )
266           {
267             *a = NULL;
268             errno = EPERM;
269           }
270         else
271           *a = iobuf_create( name );
272         if( !*a )
273           {
274             rc = gpg_error_from_syserror ();
275             log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
276           }
277         else if( opt.verbose )
278           log_info(_("writing to `%s'\n"), name );
279       }
280     xfree(buf);
281   }
282
283   if (*a)
284     iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
285
286   return rc;
287 }
288
289
290 /* Find a matching data file for the signature file SIGFILENAME and
291    return it as a malloced string.  If no matching data file is found,
292    return NULL.  */
293 char *
294 get_matching_datafile (const char *sigfilename)
295 {
296   char *fname = NULL;
297   size_t len;
298
299   if (iobuf_is_pipe_filename (sigfilename))
300     return NULL;
301
302   len = strlen (sigfilename);
303   if (len > 4
304       && (!strcmp (sigfilename + len - 4, EXTSEP_S "sig")
305           || (len > 5 && !strcmp(sigfilename + len - 5, EXTSEP_S "sign"))
306           || !strcmp(sigfilename + len - 4, EXTSEP_S "asc")))
307     {
308
309       fname = xstrdup (sigfilename);
310       fname[len-(fname[len-1]=='n'?5:4)] = 0 ;
311       if (access (fname, R_OK ))
312         {
313           /* Not found or other error.  */
314           xfree (fname);
315           fname = NULL;
316         }
317     }
318
319   return fname;
320 }
321
322
323 /****************
324  * Try to open a file without the extension ".sig" or ".asc"
325  * Return NULL if such a file is not available.
326  */
327 iobuf_t
328 open_sigfile (const char *sigfilename, progress_filter_context_t *pfx)
329 {
330   iobuf_t a = NULL;
331   char *buf;
332
333   buf = get_matching_datafile (sigfilename);
334   if (buf)
335     {
336       a = iobuf_open (buf);
337       if (a && is_secured_file (iobuf_get_fd (a)))
338         {
339           iobuf_close (a);
340           a = NULL;
341           gpg_err_set_errno (EPERM);
342         }
343       if (a)
344         log_info (_("assuming signed data in '%s'\n"), buf);
345       if (a && pfx)
346         handle_progress (pfx, a, buf);
347       xfree (buf);
348     }
349
350   return a;
351 }
352
353
354 /****************
355  * Copy the option file skeleton to the given directory.
356  */
357 static void
358 copy_options_file( const char *destdir )
359 {
360     const char *datadir = gnupg_datadir ();
361     char *fname;
362     FILE *src, *dst;
363     int linefeeds=0;
364     int c;
365     mode_t oldmask;
366     int esc = 0;
367     int any_option = 0;
368
369     if( opt.dry_run )
370         return;
371
372     fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
373     strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT );
374     src = fopen( fname, "r" );
375     if (src && is_secured_file (fileno (src)))
376       {
377         fclose (src);
378         src = NULL;
379         errno = EPERM;
380       }
381     if( !src ) {
382         log_info (_("can't open `%s': %s\n"), fname, strerror(errno) );
383         xfree(fname);
384         return;
385     }
386     strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
387     oldmask=umask(077);
388     if ( is_secured_filename (fname) )
389       {
390         dst = NULL;
391         errno = EPERM;
392       }
393     else
394       dst = fopen( fname, "w" );
395     umask(oldmask);
396     if( !dst ) {
397         log_info (_("can't create `%s': %s\n"), fname, strerror(errno) );
398         fclose( src );
399         xfree(fname);
400         return;
401     }
402
403     while( (c=getc(src)) != EOF ) {
404         if( linefeeds < 3 ) {
405             if( c == '\n' )
406                 linefeeds++;
407         }
408         else {
409             putc( c, dst );
410             if (c== '\n')
411                 esc = 1;
412             else if (esc == 1) {
413                 if (c == ' ' || c == '\t')
414                     ;
415                 else if (c == '#')
416                     esc = 2;
417                 else
418                     any_option = 1;
419             }
420         }
421     }
422     fclose( dst );
423     fclose( src );
424     log_info(_("new configuration file `%s' created\n"), fname );
425     if (any_option)
426         log_info (_("WARNING: options in `%s'"
427                     " are not yet active during this run\n"),
428                   fname);
429     xfree(fname);
430 }
431
432
433 void
434 try_make_homedir (const char *fname)
435 {
436   const char *defhome = standard_homedir ();
437
438   /* Create the directory only if the supplied directory name is the
439      same as the default one.  This way we avoid to create arbitrary
440      directories when a non-default home directory is used.  To cope
441      with HOME, we do compare only the suffix if we see that the
442      default homedir does start with a tilde.  */
443   if ( opt.dry_run || opt.no_homedir_creation )
444     return;
445
446   if (
447 #ifdef HAVE_W32_SYSTEM
448       ( !compare_filenames (fname, defhome) )
449 #else
450       ( *defhome == '~'
451         && (strlen(fname) >= strlen (defhome+1)
452             && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
453       || (*defhome != '~'  && !compare_filenames( fname, defhome ) )
454 #endif
455       )
456     {
457       if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
458         log_fatal ( _("can't create directory `%s': %s\n"),
459                     fname, strerror(errno) );
460       else if (!opt.quiet )
461         log_info ( _("directory `%s' created\n"), fname );
462       copy_options_file( fname );
463
464     }
465 }