* protect-tool.c: New option --enable-status-msg.
[gnupg.git] / sm / import.c
1 /* import.c - Import certificates
2  *      Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29 #include <signal.h>
30 #include <fcntl.h>
31 #include <sys/wait.h>
32
33 #include "gpgsm.h"
34 #include <gcrypt.h>
35 #include <ksba.h>
36
37 #include "keydb.h"
38 #include "i18n.h"
39
40 #ifdef _POSIX_OPEN_MAX
41 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
42 #else
43 #define MAX_OPEN_FDS 20
44 #endif
45
46
47 struct stats_s {
48   unsigned long count;
49   unsigned long imported;
50   unsigned long unchanged;
51   unsigned long not_imported;
52   unsigned long secret_read;
53   unsigned long secret_imported;
54   unsigned long secret_dups;
55  };
56
57
58 static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp,
59                               struct stats_s *stats);
60
61
62
63 static void
64 print_imported_status (CTRL ctrl, ksba_cert_t cert, int new_cert)
65 {
66   char *fpr;
67      
68   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
69   if (new_cert)
70     gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL);
71
72   gpgsm_status2 (ctrl, STATUS_IMPORT_OK, 
73                  new_cert? "1":"0",  fpr, NULL);
74
75   xfree (fpr);
76 }
77
78
79 /* Print an IMPORT_PROBLEM status.  REASON is one of:
80    0 := "No specific reason given".
81    1 := "Invalid Certificate".
82    2 := "Issuer Certificate missing".
83    3 := "Certificate Chain too long".
84    4 := "Error storing certificate".
85 */
86 static void
87 print_import_problem (CTRL ctrl, ksba_cert_t cert, int reason)
88 {
89   char *fpr = NULL;
90   char buf[25];
91   int i;
92
93   sprintf (buf, "%d", reason);
94   if (cert)
95     {
96       fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
97       /* detetect an error (all high) value */
98       for (i=0; fpr[i] == 'F'; i++)
99         ;
100       if (!fpr[i])
101         {
102           xfree (fpr);
103           fpr = NULL;
104         }
105     }
106   gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL);
107   xfree (fpr);
108 }
109
110
111 void
112 print_imported_summary (CTRL ctrl, struct stats_s *stats)
113 {
114   char buf[14*25];
115
116   if (!opt.quiet)
117     {
118       log_info (_("total number processed: %lu\n"), stats->count);
119       if (stats->imported) 
120         {
121           log_info (_("              imported: %lu"), stats->imported );
122           log_printf ("\n");
123         }
124       if (stats->unchanged)
125         log_info (_("             unchanged: %lu\n"), stats->unchanged);
126       if (stats->secret_read)
127         log_info (_("      secret keys read: %lu\n"), stats->secret_read );
128       if (stats->secret_imported)
129         log_info (_("  secret keys imported: %lu\n"), stats->secret_imported );
130       if (stats->secret_dups)
131         log_info (_(" secret keys unchanged: %lu\n"), stats->secret_dups );
132       if (stats->not_imported)
133         log_info (_("          not imported: %lu\n"), stats->not_imported);
134     }
135
136   sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
137           stats->count,
138           0l /*stats->no_user_id*/,
139           stats->imported,
140           0l /*stats->imported_rsa*/,
141           stats->unchanged,
142           0l /*stats->n_uids*/,
143           0l /*stats->n_subk*/,
144           0l /*stats->n_sigs*/,
145           0l /*stats->n_revoc*/,
146           stats->secret_read,
147           stats->secret_imported,
148           stats->secret_dups,
149           0l /*stats->skipped_new_keys*/,
150           stats->not_imported
151           );
152   gpgsm_status (ctrl, STATUS_IMPORT_RES, buf);
153 }
154
155
156
157 static void
158 check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth)
159 {
160   int rc;
161
162   if (stats)
163     stats->count++;
164   if ( depth >= 50 )
165     {
166       log_error (_("certificate chain too long\n"));
167       if (stats)
168         stats->not_imported++;
169       print_import_problem (ctrl, cert, 3);
170       return;
171     }
172
173   /* Some basic checks, but don't care about missing certificates;
174      this is so that we are able to import entire certificate chains
175      w/o requirening a special order (i.e. root-CA first).  This used
176      to be different but because gpgsm_verify even imports
177      certificates without any checks, it doesn't matter much and the
178      code gets much cleaner.  A housekeeping function to remove
179      certificates w/o an anchor would be nice, though. */
180   rc = gpgsm_basic_cert_check (cert);
181   if (!rc || gpg_err_code (rc) == GPG_ERR_MISSING_CERT)
182     {
183       int existed;
184
185       if (!keydb_store_cert (cert, 0, &existed))
186         {
187           ksba_cert_t next = NULL;
188
189           if (!existed)
190             {
191               print_imported_status (ctrl, cert, 1);
192               if (stats)
193                 stats->imported++;
194             }
195           else
196             {
197               print_imported_status (ctrl, cert, 0);
198               if (stats)
199                 stats->unchanged++;
200             }
201             
202           if (opt.verbose > 1 && existed)
203             {
204               if (depth)
205                 log_info ("issuer certificate already in DB\n");
206               else
207                 log_info ("certificate already in DB\n");
208             }
209           else if (opt.verbose && !existed)
210             {
211               if (depth)
212                 log_info ("issuer certificate imported\n");
213               else
214                 log_info ("certificate imported\n");
215             }
216
217           /* Now lets walk up the chain and import all certificates up
218              the chain.  This is required in case we already stored
219              parent certificates in the ephemeral keybox.  Do not
220              update the statistics, though. */
221           if (!gpgsm_walk_cert_chain (cert, &next))
222             {
223               check_and_store (ctrl, NULL, next, depth+1);
224               ksba_cert_release (next);
225             }
226         }
227       else
228         {
229           log_error (_("error storing certificate\n"));
230           if (stats)
231             stats->not_imported++;
232           print_import_problem (ctrl, cert, 4);
233         }
234     }
235   else
236     {
237       log_error (_("basic certificate checks failed - not imported\n"));
238       if (stats)
239         stats->not_imported++;
240       print_import_problem (ctrl, cert,
241                             gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
242                             gpg_err_code (rc) == GPG_ERR_BAD_CERT?     1 : 0);
243     }
244 }
245
246
247 \f
248
249 static int
250 import_one (CTRL ctrl, struct stats_s *stats, int in_fd)
251 {
252   int rc;
253   Base64Context b64reader = NULL;
254   ksba_reader_t reader;
255   ksba_cert_t cert = NULL;
256   ksba_cms_t cms = NULL;
257   FILE *fp = NULL;
258   ksba_content_type_t ct;
259   int any = 0;
260
261   fp = fdopen ( dup (in_fd), "rb");
262   if (!fp)
263     {
264       rc = gpg_error (gpg_err_code_from_errno (errno));
265       log_error ("fdopen() failed: %s\n", strerror (errno));
266       goto leave;
267     }
268
269   rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader);
270   if (rc)
271     {
272       log_error ("can't create reader: %s\n", gpg_strerror (rc));
273       goto leave;
274     }
275   
276   
277   /* We need to loop here to handle multiple PEM objects in one
278      file. */
279   do
280     {
281       ksba_cms_release (cms); cms = NULL;
282       ksba_cert_release (cert); cert = NULL;
283       
284       ct = ksba_cms_identify (reader);
285       if (ct == KSBA_CT_SIGNED_DATA)
286         { /* This is probably a signed-only message - import the certs */
287           ksba_stop_reason_t stopreason;
288           int i;
289           
290           rc = ksba_cms_new (&cms);
291           if (rc)
292             goto leave;
293           
294           rc = ksba_cms_set_reader_writer (cms, reader, NULL);
295           if (rc)
296             {
297               log_error ("ksba_cms_set_reader_writer failed: %s\n",
298                          gpg_strerror (rc));
299               goto leave;
300             }
301
302           do 
303             {
304               rc = ksba_cms_parse (cms, &stopreason);
305               if (rc)
306                 {
307                   log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
308                   goto leave;
309                 }
310
311               if (stopreason == KSBA_SR_BEGIN_DATA)
312                 log_info ("not a certs-only message\n");
313             }
314           while (stopreason != KSBA_SR_READY);   
315       
316           for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
317             {
318               check_and_store (ctrl, stats, cert, 0);
319               ksba_cert_release (cert); 
320               cert = NULL;
321             }
322           if (!i)
323             log_error ("no certificate found\n");
324           else
325             any = 1;
326         }
327       else if (ct == KSBA_CT_PKCS12)
328         { /* This seems to be a pkcs12 message.  We use an external
329              tool to parse the message and to store the private keys.
330              We need to use a another reader here to parse the
331              certificate we included in the p12 file; then we continue
332              to look for other pkcs12 files (works only if they are in
333              PEM format. */
334           FILE *certfp;
335           Base64Context b64p12rdr;
336           ksba_reader_t p12rdr;
337           
338           rc = parse_p12 (reader, &certfp, stats);
339           if (!rc)
340             {
341               any = 1;
342               
343               rewind (certfp);
344               rc = gpgsm_create_reader (&b64p12rdr, ctrl, certfp, 1, &p12rdr);
345               if (rc)
346                 {
347                   log_error ("can't create reader: %s\n", gpg_strerror (rc));
348                   fclose (certfp);
349                   goto leave;
350                 }
351
352               do
353                 {
354                   ksba_cert_release (cert); cert = NULL;
355                   rc = ksba_cert_new (&cert);
356                   if (!rc)
357                     {
358                       rc = ksba_cert_read_der (cert, p12rdr);
359                       if (!rc)
360                         check_and_store (ctrl, stats, cert, 0);
361                     }
362                   ksba_reader_clear (p12rdr, NULL, NULL);
363                 }
364               while (!rc && !gpgsm_reader_eof_seen (b64p12rdr));
365
366               if (gpg_err_code (rc) == GPG_ERR_EOF)
367                 rc = 0;
368               gpgsm_destroy_reader (b64p12rdr);
369               fclose (certfp);
370               if (rc)
371                 goto leave;
372             }
373         }
374       else if (ct == KSBA_CT_NONE)
375         { /* Failed to identify this message - assume a certificate */
376
377           rc = ksba_cert_new (&cert);
378           if (rc)
379             goto leave;
380
381           rc = ksba_cert_read_der (cert, reader);
382           if (rc)
383             goto leave;
384
385           check_and_store (ctrl, stats, cert, 0);
386           any = 1;
387         }
388       else
389         {
390           log_error ("can't extract certificates from input\n");
391           rc = gpg_error (GPG_ERR_NO_DATA);
392         }
393       
394       ksba_reader_clear (reader, NULL, NULL);
395     }
396   while (!gpgsm_reader_eof_seen (b64reader));
397
398  leave:
399   if (any && gpg_err_code (rc) == GPG_ERR_EOF)
400     rc = 0;
401   ksba_cms_release (cms);
402   ksba_cert_release (cert);
403   gpgsm_destroy_reader (b64reader);
404   if (fp)
405     fclose (fp);
406   return rc;
407 }
408
409
410 int
411 gpgsm_import (CTRL ctrl, int in_fd)
412 {
413   int rc;
414   struct stats_s stats;
415
416   memset (&stats, 0, sizeof stats);
417   rc = import_one (ctrl, &stats, in_fd);
418   print_imported_summary (ctrl, &stats);
419   /* If we never printed an error message do it now so that a command
420      line invocation will return with an error (log_error keeps a
421      global errorcount) */
422   if (rc && !log_get_errorcount (0))
423     log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
424   return rc;
425 }
426
427
428 int
429 gpgsm_import_files (CTRL ctrl, int nfiles, char **files,
430                     int (*of)(const char *fname))
431 {
432   int rc = 0;
433   struct stats_s stats;
434
435   memset (&stats, 0, sizeof stats);
436   
437   if (!nfiles)
438     rc = import_one (ctrl, &stats, 0);
439   else
440     {
441       for (; nfiles && !rc ; nfiles--, files++)
442         {
443           int fd = of (*files);
444           rc = import_one (ctrl, &stats, fd);
445           close (fd);
446           if (rc == -1)
447             rc = 0;
448         }
449     }
450   print_imported_summary (ctrl, &stats);
451   /* If we never printed an error message do it now so that a command
452      line invocation will return with an error (log_error keeps a
453      global errorcount) */
454   if (rc && !log_get_errorcount (0))
455     log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
456   return rc;
457 }
458
459
460 /* Fork and exec the protecttool, connect the file descriptor of
461    INFILE to stdin, return a new stream in STATUSFILE, write the
462    output to OUTFILE and the pid of the process in PID.  Returns 0 on
463    success or an error code. */
464 static gpg_error_t
465 popen_protect_tool (const char *pgmname,
466                     FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid)
467 {
468   gpg_error_t err;
469   int fd, fdout, rp[2];
470   int n, i;
471
472   fflush (infile);
473   rewind (infile);
474   fd = fileno (infile);
475   fdout = fileno (outfile);
476   if (fd == -1 || fdout == -1)
477     log_fatal ("no file descriptor for temporary file: %s\n",
478                strerror (errno));
479
480   /* Now start the protect-tool. */
481   if (pipe (rp) == -1)
482     {
483       err = gpg_error_from_errno (errno);
484       log_error (_("error creating a pipe: %s\n"), strerror (errno));
485       return err;
486     }
487       
488   *pid = fork ();
489   if (*pid == -1)
490     {
491       err = gpg_error_from_errno (errno);
492       log_error (_("error forking process: %s\n"), strerror (errno));
493       close (rp[0]);
494       close (rp[1]);
495       return err;
496     }
497
498   if (!*pid)
499     { /* Child. */
500       const char *arg0;
501
502       arg0 = strrchr (pgmname, '/');
503       if (arg0)
504         arg0++;
505       else
506         arg0 = pgmname;
507
508       /* Connect the infile to stdin. */
509       if (fd != 0 && dup2 (fd, 0) == -1)
510         log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
511
512       /* Connect the outfile to stdout. */
513       if (fdout != 1 && dup2 (fdout, 1) == -1)
514         log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
515       
516       /* Connect stderr to our pipe. */
517       if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
518         log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
519
520       /* Close all other files. */
521       n = sysconf (_SC_OPEN_MAX);
522       if (n < 0)
523         n = MAX_OPEN_FDS;
524       for (i=3; i < n; i++)
525         close(i);
526       errno = 0;
527
528       setup_pinentry_env ();
529
530       execlp (pgmname, arg0,
531               "--homedir", opt.homedir,
532               "--p12-import",
533               "--store", 
534               "--no-fail-on-exist",
535               "--enable-status-msg",
536               "--",
537               NULL);
538       /* No way to print anything, as we have closed all streams. */
539       _exit (31);
540     }
541
542   /* Parent. */
543   close (rp[1]);
544   *statusfile = fdopen (rp[0], "r");
545   if (!*statusfile)
546     {
547       err = gpg_error_from_errno (errno);
548       log_error ("can't fdopen pipe for reading: %s", strerror (errno));
549       kill (*pid, SIGTERM);
550       return err;
551     }
552
553   return 0;
554 }
555
556
557 /* Assume that the reader is at a pkcs#12 message and try to import
558    certificates from that stupid format. We will alos store secret
559    keys.  All of the pkcs#12 parsing and key storing is handled by the
560    gpg-protect-tool, we merely have to take care of receiving the
561    certificates. On success RETFP returns a temporary file with
562    certificates. */
563 static gpg_error_t
564 parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
565 {
566   const char *pgmname;
567   gpg_error_t err = 0, child_err = 0;
568   int i, c, cont_line;
569   unsigned int pos;
570   FILE *tmpfp, *certfp = NULL, *fp = NULL;
571   char buffer[1024];
572   size_t nread;
573   pid_t pid = -1;
574
575   if (!opt.protect_tool_program || !*opt.protect_tool_program)
576     pgmname = GNUPG_DEFAULT_PROTECT_TOOL;
577   else
578     pgmname = opt.protect_tool_program;
579
580   *retfp = NULL;
581
582   /* To avoid an extra feeder process or doing selects and because
583      gpg-protect-tool will anyway parse the entire pkcs#12 message in
584      memory, we simply use tempfiles here and pass them to
585      the gpg-protect-tool. */
586   tmpfp = tmpfile ();
587   if (!tmpfp)
588     {
589       err = gpg_error_from_errno (errno);
590       log_error (_("error creating temporary file: %s\n"), strerror (errno));
591       goto cleanup;
592     }
593   while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread)))
594     {
595       if (nread && fwrite (buffer, nread, 1, tmpfp) != 1)
596         {
597           err = gpg_error_from_errno (errno);
598           log_error (_("error writing to temporary file: %s\n"),
599                      strerror (errno));
600           goto cleanup;
601         }
602     }
603   if (gpg_err_code (err) == GPG_ERR_EOF)
604     err = 0;
605   if (err)
606     {
607       log_error (_("error reading input: %s\n"), gpg_strerror (err));
608       goto cleanup;
609     }
610
611   certfp = tmpfile ();
612   if (!certfp)
613     {
614       err = gpg_error_from_errno (errno);
615       log_error (_("error creating temporary file: %s\n"), strerror (errno));
616       goto cleanup;
617     }
618
619   err = popen_protect_tool (pgmname, tmpfp, certfp, &fp, &pid);
620   if (err)
621     {
622       pid = -1;
623       goto cleanup;
624     }
625   fclose (tmpfp);
626   tmpfp = NULL;
627
628   /* Read stderr of the protect tool. */
629   pos = 0;
630   cont_line = 0;
631   while ((c=getc (fp)) != EOF)
632     {
633       /* fixme: We could here grep for status information of the
634          protect tool to figure out better error codes for
635          CHILD_ERR. */
636       buffer[pos++] = c;
637       if (pos >= sizeof buffer - 5 || c == '\n')
638         {
639           buffer[pos - (c == '\n')] = 0;
640           if (cont_line)
641             log_printf ("%s", buffer);
642           else
643             {
644               if (!strncmp (buffer, "gpg-protect-tool: [PROTECT-TOOL:] ",34))
645                 {
646                   char *p, *pend;
647
648                   p = buffer + 34;
649                   pend = strchr (p, ' ');
650                   if (pend)
651                     *pend = 0;
652                   if ( !strcmp (p, "secretkey-stored"))
653                     {
654                       stats->count++;
655                       stats->secret_read++;
656                       stats->secret_imported++;
657                     }
658                   else if ( !strcmp (p, "secretkey-exists"))
659                     {
660                       stats->count++;
661                       stats->secret_read++;
662                       stats->secret_dups++;
663                     }
664                   else if ( !strcmp (p, "bad-passphrase"))
665                     ;
666                 }
667               else
668                 log_info ("%s", buffer);
669             }
670           pos = 0;
671           cont_line = (c != '\n');
672         }
673     }
674
675   if (pos)
676     {
677       buffer[pos] = 0;
678       if (cont_line)
679         log_printf ("%s\n", buffer);
680       else
681         log_info ("%s\n", buffer);
682     }
683
684   /* If we found no error in the output of the cild, setup a suitable
685      error code, which will later be reset if the exit status of the
686      child is 0. */
687   if (!child_err)
688     child_err = gpg_error (GPG_ERR_DECRYPT_FAILED);
689
690
691  cleanup:
692   if (tmpfp)
693     fclose (tmpfp);
694   if (fp)
695     fclose (fp);
696   if (pid != -1)
697     {
698       int status;
699
700       while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
701         ;
702       if (i == -1)
703         log_error (_("waiting for protect-tool to terminate failed: %s\n"),
704                    strerror (errno));
705       else if (WIFEXITED (status) && WEXITSTATUS (status) == 31)
706         log_error (_("error running `%s': probably not installed\n"), pgmname);
707       else if (WIFEXITED (status) && WEXITSTATUS (status))
708         log_error (_("error running `%s': exit status %d\n"), pgmname,
709                      WEXITSTATUS (status));
710       else if (!WIFEXITED (status))
711         log_error (_("error running `%s': terminated\n"), pgmname);
712       else 
713         child_err = 0;
714     }
715   if (!err)
716     err = child_err;
717   if (err)
718     {
719       if (certfp)
720         fclose (certfp);
721     }
722   else
723     *retfp = certfp;
724   return err;
725 }