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