* openfile.c (ask_outfile_name): Fixed buffer overflow occurring
[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 2 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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33
34 #include "gpg.h"
35 #include "util.h"
36 #include "ttyio.h"
37 #include "options.h"
38 #include "main.h"
39 #include "status.h"
40 #include "i18n.h"
41
42 #ifdef USE_ONLY_8DOT3
43 #define SKELEXT ".skl"
44 #else
45 #define SKELEXT EXTSEP_S "skel"
46 #endif
47
48 #if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
49 #define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
50 #else
51 #define CMP_FILENAME(a,b) strcmp( (a), (b) )
52 #endif
53
54 #ifdef MKDIR_TAKES_ONE_ARG
55 #undef mkdir
56 #define mkdir(a,b) mkdir(a)
57 #endif
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 overwrite_filep( const char *fname )
69 {
70     if( iobuf_is_pipe_filename (fname) )
71         return 1; /* Writing to stdout is always okay */
72
73     if( access( fname, F_OK ) )
74         return 1; /* does not exist */
75
76 #ifndef HAVE_DOSISH_SYSTEM
77     if ( !strcmp ( fname, "/dev/null" ) )
78         return 1; /* does not do any harm */
79 #endif
80
81     /* fixme: add some backup stuff in case of overwrite */
82     if( opt.answer_yes )
83         return 1;
84     if( opt.answer_no || opt.batch )
85         return 0;  /* do not overwrite */
86
87     tty_printf(_("File `%s' exists. "), fname);
88     if( cpr_enabled () )
89         tty_printf ("\n");
90     if( cpr_get_answer_is_yes("openfile.overwrite.okay",
91                                _("Overwrite? (y/N) ")) )
92         return 1;
93     return 0;
94 }
95
96
97 /****************
98  * Strip known extensions from iname and return a newly allocated
99  * filename.  Return NULL if we can't do that.
100  */
101 char *
102 make_outfile_name( const char *iname )
103 {
104     size_t n;
105
106     if ( iobuf_is_pipe_filename (iname) )
107         return xstrdup("-");
108
109     n = strlen(iname);
110     if( n > 4 && (    !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
111                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
112                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
113                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
114         char *buf = xstrdup( iname );
115         buf[n-4] = 0;
116         return buf;
117     }
118     else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
119         char *buf = xstrdup( iname );
120         buf[n-5] = 0;
121         return buf;
122     }
123
124     log_info(_("%s: unknown suffix\n"), iname );
125     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 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   if ( opt.batch )
144     return NULL;
145   
146   defname = name && namelen? make_printable_string (name, namelen, 0) : NULL;
147
148   s = _("Enter new filename");
149   n = strlen(s) + (defname?strlen (defname):0) + 10;
150   prompt = xmalloc (n);
151   if (defname)
152     snprintf (prompt, n-1, "%s [%s]: ", s, defname );
153   else
154     snprintf (prompt, n-1, "%s: ", s );
155   tty_enable_completion(NULL);
156   fname = cpr_get ("openfile.askoutname", prompt );
157   cpr_kill_prompt ();
158   tty_disable_completion ();
159   xfree (prompt);
160   if ( !*fname ) 
161     {
162       xfree (fname); 
163       fname = defname;
164       defname = NULL;
165     }
166   xfree (defname);
167   if (fname)
168     trim_spaces (fname);
169   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  */
180 int
181 open_outfile( const char *iname, int mode, IOBUF *a )
182 {
183   int rc = 0;
184
185   *a = NULL;
186   if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
187     *a = iobuf_create(NULL);
188     if( !*a ) {
189       rc = gpg_error_from_syserror ();
190       log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
191     }
192     else if( opt.verbose )
193       log_info(_("writing to stdout\n"));
194   }
195   else {
196     char *buf = NULL;
197     const char *name;
198     
199     if( opt.dry_run )
200       name = "/dev/null";
201     else if( opt.outfile )
202       name = opt.outfile;
203     else {
204 #ifdef USE_ONLY_8DOT3
205       if (opt.mangle_dos_filenames)
206         {
207           /* It is quite common DOS system to have only one dot in a
208            * a filename So if we have something like this, we simple
209            * replace the suffix execpt in cases where the suffix is
210            * larger than 3 characters and not the same as.
211            * We should really map the filenames to 8.3 but this tends to
212            * be more complicated and is probaly a duty of the filesystem
213            */
214           char *dot;
215           const char *newsfx = mode==1 ? ".asc" :
216                                mode==2 ? ".sig" : ".gpg";
217           
218           buf = xmalloc(strlen(iname)+4+1);
219           strcpy(buf,iname);
220           dot = strchr(buf, '.' );
221           if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
222                                   && CMP_FILENAME(newsfx, dot) )
223             {
224               strcpy(dot, newsfx );
225             }
226           else if ( dot && !dot[1] ) /* don't duplicate a dot */
227             strcpy( dot, newsfx+1 );
228           else
229             strcat ( buf, newsfx );
230         }
231       if (!buf)
232 #endif /* USE_ONLY_8DOT3 */
233         {
234           buf = xmalloc(strlen(iname)+4+1);
235           strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
236                                    mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
237         }
238       name = buf;
239     }
240
241     rc = 0;
242     while( !overwrite_filep (name) )
243       {
244         char *tmp = ask_outfile_name (NULL, 0);
245         if ( !tmp || !*tmp )
246           {
247             xfree (tmp);
248             rc = gpg_error (GPG_ERR_EEXIST);
249             break;
250           }
251         xfree (buf);
252         name = buf = tmp;
253       }
254     
255     if( !rc )
256       {
257         if (is_secured_filename (name) )
258           {
259             *a = NULL;
260             errno = EPERM;
261           }
262         else
263           *a = iobuf_create( name );
264         if( !*a )
265           {
266             rc = gpg_error_from_syserror ();
267             log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
268           }
269         else if( opt.verbose )
270           log_info(_("writing to `%s'\n"), name );
271       }
272     xfree(buf);
273   }
274
275   if (*a)
276     iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
277
278   return rc;
279 }
280
281
282 /****************
283  * Try to open a file without the extension ".sig" or ".asc"
284  * Return NULL if such a file is not available.
285  */
286 IOBUF
287 open_sigfile( const char *iname, progress_filter_context_t *pfx )
288 {
289     IOBUF a = NULL;
290     size_t len;
291
292     if( !iobuf_is_pipe_filename (iname) ) {
293         len = strlen(iname);
294         if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
295                         || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
296                         || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
297             char *buf;
298             buf = xstrdup(iname);
299             buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
300             a = iobuf_open( buf );
301             if (a && is_secured_file (iobuf_get_fd (a)))
302               {
303                 iobuf_close (a);
304                 a = NULL;
305                 errno = EPERM;
306               }
307             if( a && opt.verbose )
308                 log_info(_("assuming signed data in `%s'\n"), buf );
309             if (a && pfx)
310               handle_progress (pfx, a, buf);
311             xfree(buf);
312         }
313     }
314     return a;
315 }
316
317 /****************
318  * Copy the option file skeleton to the given directory.
319  */
320 static void
321 copy_options_file( const char *destdir )
322 {
323     const char *datadir = GNUPG_DATADIR;
324     char *fname;
325     FILE *src, *dst;
326     int linefeeds=0;
327     int c;
328     mode_t oldmask;
329     int esc = 0;
330     int any_option = 0;
331
332     if( opt.dry_run )
333         return;
334
335     fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
336     strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT );
337     src = fopen( fname, "r" );
338     if (src && is_secured_file (fileno (src)))
339       {
340         fclose (src);
341         src = NULL;
342         errno = EPERM;
343       }
344     if( !src ) {
345         log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
346         xfree(fname);
347         return;
348     }
349     strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
350     oldmask=umask(077);
351     if ( is_secured_filename (fname) )
352       {
353         dst = NULL;
354         errno = EPERM;
355       }
356     else
357       dst = fopen( fname, "w" );
358     umask(oldmask);
359     if( !dst ) {
360         log_error(_("can't create `%s': %s\n"), fname, strerror(errno) );
361         fclose( src );
362         xfree(fname);
363         return;
364     }
365
366     while( (c=getc(src)) != EOF ) {
367         if( linefeeds < 3 ) {
368             if( c == '\n' )
369                 linefeeds++;
370         }
371         else {
372             putc( c, dst );
373             if (c== '\n')
374                 esc = 1;
375             else if (esc == 1) {
376                 if (c == ' ' || c == '\t')
377                     ;
378                 else if (c == '#')
379                     esc = 2;
380                 else 
381                     any_option = 1;
382             }
383         }
384     }
385     fclose( dst );
386     fclose( src );
387     log_info(_("new configuration file `%s' created\n"), fname );
388     if (any_option)
389         log_info (_("WARNING: options in `%s'"
390                     " are not yet active during this run\n"),
391                   fname);
392     xfree(fname);
393 }
394
395
396 void
397 try_make_homedir( const char *fname )
398 {
399     const char *defhome = GNUPG_DEFAULT_HOMEDIR;
400
401     /* Create the directory only if the supplied directory name
402      * is the same as the default one.  This way we avoid to create
403      * arbitrary directories when a non-default homedirectory is used.
404      * To cope with HOME, we do compare only the suffix if we see that
405      * the default homedir does start with a tilde.
406      */
407     if( opt.dry_run || opt.no_homedir_creation )
408         return;
409
410     if ( ( *defhome == '~'
411            && ( strlen(fname) >= strlen (defhome+1)
412                 && !strcmp(fname+strlen(fname)-strlen(defhome+1),
413                            defhome+1 ) ))
414          || ( *defhome != '~'
415               && !compare_filenames( fname, defhome ) )
416         ) {
417         if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
418             log_fatal( _("can't create directory `%s': %s\n"),
419                                         fname,  strerror(errno) );
420         else if( !opt.quiet )
421             log_info( _("directory `%s' created\n"), fname );
422         copy_options_file( fname );
423 /*      log_info(_("you have to start GnuPG again, " */
424 /*                 "so it can read the new configuration file\n") ); */
425 /*      g10_exit(1); */
426     }
427 }