A whole bunch of changes to allow building for Windows.
[gnupg.git] / g10 / decrypt.c
1 /* decrypt.c - verify signed data
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3  *               2007 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 <errno.h>
28 #include <assert.h>
29
30 #include "gpg.h"
31 #include "options.h"
32 #include "packet.h"
33 #include "errors.h"
34 #include "iobuf.h"
35 #include "keydb.h"
36 #include "util.h"
37 #include "main.h"
38 #include "status.h"
39 #include "i18n.h"
40
41
42
43 /****************
44  * Assume that the input is an encrypted message and decrypt
45  * (and if signed, verify the signature on) it.
46  * This command differs from the default operation, as it never
47  * writes to the filename which is included in the file and it
48  * rejects files which don't begin with an encrypted message.
49  */
50
51 int
52 decrypt_message( const char *filename )
53 {
54     IOBUF fp;
55     armor_filter_context_t *afx = NULL;
56     progress_filter_context_t *pfx;
57     int rc;
58     int no_out = 0;
59
60     pfx = new_progress_context ();
61
62     /* Open the message file.  */
63     fp = iobuf_open(filename);
64     if (fp && is_secured_file (iobuf_get_fd (fp)))
65       {
66         iobuf_close (fp);
67         fp = NULL;
68         errno = EPERM;
69       }
70     if( !fp ) {
71         rc = gpg_error_from_syserror ();
72         log_error (_("can't open `%s': %s\n"), print_fname_stdin(filename),
73                    gpg_strerror (rc));
74         release_progress_context (pfx);
75         return rc;
76     }
77
78     handle_progress (pfx, fp, filename);
79
80     if( !opt.no_armor ) {
81         if( use_armor_filter( fp ) ) {
82             afx = new_armor_context ();
83             push_armor_filter ( afx, fp );
84         }
85     }
86
87     if( !opt.outfile ) {
88         no_out = 1;
89         opt.outfile = "-";
90     }
91     rc = proc_encryption_packets( NULL, fp );
92     if( no_out )
93        opt.outfile = NULL;
94     iobuf_close(fp);
95     release_armor_context (afx);
96     release_progress_context (pfx);
97     return rc;
98 }
99
100 void
101 decrypt_messages(int nfiles, char *files[])
102 {
103   IOBUF fp;
104   armor_filter_context_t *afx = NULL;  
105   progress_filter_context_t *pfx;
106   char *p, *output = NULL;
107   int rc=0,use_stdin=0;
108   unsigned int lno=0;
109   
110   if (opt.outfile)
111     {
112       log_error(_("--output doesn't work for this command\n"));
113       return;
114     }
115
116   pfx = new_progress_context ();
117
118   if(!nfiles)
119     use_stdin=1;
120
121   for(;;)
122     {
123       char line[2048];
124       char *filename=NULL;
125
126       if(use_stdin)
127         {
128           if(fgets(line, DIM(line), stdin))
129             {
130               lno++;
131               if (!*line || line[strlen(line)-1] != '\n')
132                 log_error("input line %u too long or missing LF\n", lno);
133               else
134                 {
135                   line[strlen(line)-1] = '\0';
136                   filename=line;
137                 }
138             }
139         }
140       else
141         {
142           if(nfiles)
143             {
144               filename=*files;
145               nfiles--;
146               files++;
147             }
148         }
149
150       if(filename==NULL)
151         break;
152
153       print_file_status(STATUS_FILE_START, filename, 3);      
154       output = make_outfile_name(filename);
155       if (!output)
156         goto next_file;
157       fp = iobuf_open(filename);
158       if (fp)
159         iobuf_ioctl (fp,3,1,NULL); /* disable fd caching */
160       if (fp && is_secured_file (iobuf_get_fd (fp)))
161         {
162           iobuf_close (fp);
163           fp = NULL;
164           errno = EPERM;
165         }
166       if (!fp)
167         {
168           log_error(_("can't open `%s'\n"), print_fname_stdin(filename));
169           goto next_file;
170         }
171
172       handle_progress (pfx, fp, filename);
173
174       if (!opt.no_armor)
175         {
176           if (use_armor_filter(fp))
177             {
178               afx = new_armor_context ();
179               push_armor_filter ( afx, fp );
180             }
181         }
182       rc = proc_packets(NULL, fp);
183       iobuf_close(fp);
184       if (rc)
185         log_error("%s: decryption failed: %s\n", print_fname_stdin(filename),
186                   g10_errstr(rc));
187       p = get_last_passphrase();
188       set_next_passphrase(p);
189       xfree (p);
190
191     next_file:
192       /* Note that we emit file_done even after an error. */
193       write_status( STATUS_FILE_DONE );
194       xfree(output);
195       reset_literals_seen();
196     }
197
198   set_next_passphrase(NULL);  
199   release_armor_context (afx);
200   release_progress_context (pfx);
201 }