~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-security

« back to all changes in this revision

Viewing changes to sm/call-dirmngr.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* call-dirmngr.c - communication with the dromngr 
2
 
 *      Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
6
6
 * GnuPG is free software; you can redistribute it and/or modify
7
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
 
8
 * the Free Software Foundation; either version 3 of the License, or
9
9
 * (at your option) any later version.
10
10
 *
11
11
 * GnuPG is distributed in the hope that it will be useful,
14
14
 * GNU General Public License for more details.
15
15
 *
16
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
 
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
18
 */
20
19
 
21
20
#include <config.h>
35
34
#include "i18n.h"
36
35
#include "keydb.h"
37
36
 
38
 
/* The name of the socket for a system daemon.  */
39
 
#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket"
40
37
 
41
38
struct membuf {
42
39
  size_t len;
47
44
 
48
45
 
49
46
 
50
 
static ASSUAN_CONTEXT dirmngr_ctx = NULL;
 
47
static assuan_context_t dirmngr_ctx = NULL;
51
48
static int force_pipe_server = 0;
52
49
 
53
50
struct inq_certificate_parm_s {
54
 
  ASSUAN_CONTEXT ctx;
 
51
  assuan_context_t ctx;
55
52
  ksba_cert_t cert;
56
53
  ksba_cert_t issuer_cert;
57
54
};
58
55
 
59
56
struct isvalid_status_parm_s {
60
 
  CTRL ctrl;
 
57
  ctrl_t ctrl;
61
58
  int seen;
62
59
  unsigned char fpr[20];
63
60
};
64
61
 
65
62
 
66
63
struct lookup_parm_s {
67
 
  CTRL ctrl;
68
 
  ASSUAN_CONTEXT ctx;
 
64
  ctrl_t ctrl;
 
65
  assuan_context_t ctx;
69
66
  void (*cb)(void *, ksba_cert_t);
70
67
  void *cb_value;
71
68
  struct membuf data;
73
70
};
74
71
 
75
72
struct run_command_parm_s {
76
 
  ASSUAN_CONTEXT ctx;
 
73
  assuan_context_t ctx;
77
74
};
78
75
 
79
76
 
137
134
}
138
135
 
139
136
 
 
137
/* This fucntion prepares the dirmngr for a new session.  The
 
138
   audit-events option is used so that other dirmngr clients won't get
 
139
   disturbed by such events.  */
 
140
static void
 
141
prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
 
142
{
 
143
  if (!ctrl->dirmngr_seen)
 
144
    {
 
145
      ctrl->dirmngr_seen = 1;
 
146
      if (!err)
 
147
        {
 
148
          err = assuan_transact (ctx, "OPTION audit-events=1",
 
149
                                 NULL, NULL, NULL, NULL, NULL, NULL);
 
150
          if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
 
151
            err = 0;  /* Allow the use of old dirmngr versions.  */
 
152
        }
 
153
      audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
 
154
    }
 
155
}
140
156
 
141
157
 
142
158
 
143
159
/* Try to connect to the agent via socket or fork it off and work by
144
160
   pipes.  Handle the server's initial greeting */
145
161
static int
146
 
start_dirmngr (void)
 
162
start_dirmngr (ctrl_t ctrl)
147
163
{
148
164
  int rc;
149
165
  char *infostr, *p;
150
 
  ASSUAN_CONTEXT ctx;
 
166
  assuan_context_t ctx;
151
167
  int try_default = 0;
152
168
 
 
169
  if (opt.disable_dirmngr)
 
170
    return gpg_error (GPG_ERR_NO_DIRMNGR);
 
171
 
153
172
  if (dirmngr_ctx)
154
 
    return 0; /* fixme: We need a context for each thread or serialize
155
 
                 the access to the dirmngr */
 
173
    {
 
174
      prepare_dirmngr (ctrl, dirmngr_ctx, 0);
 
175
      return 0; /* fixme: We need a context for each thread or serialize
 
176
                   the access to the dirmngr */
 
177
    }
156
178
  /* Note: if you change this to multiple connections, you also need
157
179
     to take care of the implicit option sending caching. */
158
180
 
 
181
#ifdef HAVE_W32_SYSTEM
 
182
  infostr = NULL;
 
183
  opt.prefer_system_dirmngr = 1;
 
184
#else
159
185
  infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO");
160
 
  if (opt.prefer_system_dirmngr && !force_pipe_server
161
 
      &&(!infostr || !*infostr))
 
186
#endif /*HAVE_W32_SYSTEM*/
 
187
  if (infostr && !*infostr)
 
188
    infostr = NULL;
 
189
  else if (infostr)
 
190
    infostr = xstrdup (infostr);
 
191
 
 
192
  if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr)
162
193
    {
163
 
      infostr = DEFAULT_SOCKET_NAME;
 
194
      infostr = xstrdup (dirmngr_socket_name ());
164
195
      try_default = 1;
165
196
    }
166
 
  if (!infostr || !*infostr)
 
197
  if (!infostr)
167
198
    {
168
199
      const char *pgmname;
169
200
      const char *argv[3];
170
201
      int no_close_list[3];
171
202
      int i;
172
203
 
 
204
      if (!opt.dirmngr_program || !*opt.dirmngr_program)
 
205
        opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
 
206
      if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
 
207
        pgmname = opt.dirmngr_program;
 
208
      else
 
209
        pgmname++;
 
210
 
173
211
      if (opt.verbose)
174
 
        log_info (_("no running dirmngr - starting one\n"));
 
212
        log_info (_("no running dirmngr - starting `%s'\n"),
 
213
                  opt.dirmngr_program);
175
214
      
176
215
      if (fflush (NULL))
177
216
        {
180
219
          return tmperr;
181
220
        }
182
221
 
183
 
      if (!opt.dirmngr_program || !*opt.dirmngr_program)
184
 
        opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR;
185
 
      if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
186
 
        pgmname = opt.dirmngr_program;
187
 
      else
188
 
        pgmname++;
189
 
 
190
222
      argv[0] = pgmname;
191
223
      argv[1] = "--server";
192
224
      argv[2] = NULL;
198
230
      no_close_list[i] = -1;
199
231
 
200
232
      /* connect to the agent and perform initial handshaking */
201
 
      rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, (char**)argv,
 
233
      rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, argv,
202
234
                                no_close_list);
203
235
    }
204
236
  else
206
238
      int prot;
207
239
      int pid;
208
240
 
209
 
      infostr = xstrdup (infostr);
210
 
      if (!try_default && *infostr)
 
241
      if (!try_default)
211
242
        {
212
243
          if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
213
244
            {
214
245
              log_error (_("malformed DIRMNGR_INFO environment variable\n"));
215
246
              xfree (infostr);
216
247
              force_pipe_server = 1;
217
 
              return start_dirmngr ();
 
248
              return start_dirmngr (ctrl);
218
249
            }
219
250
          *p++ = 0;
220
251
          pid = atoi (p);
227
258
                         prot);
228
259
              xfree (infostr);
229
260
              force_pipe_server = 1;
230
 
              return start_dirmngr ();
 
261
              return start_dirmngr (ctrl);
231
262
            }
232
263
        }
233
264
      else
234
265
        pid = -1;
235
266
 
236
267
      rc = assuan_socket_connect (&ctx, infostr, pid);
 
268
#ifdef HAVE_W32_SYSTEM
 
269
      if (rc)
 
270
        log_debug ("connecting dirmngr at `%s' failed\n", infostr);
 
271
#endif
 
272
 
237
273
      xfree (infostr);
238
 
      if (rc == ASSUAN_Connect_Failed)
 
274
#ifndef HAVE_W32_SYSTEM
 
275
      if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
239
276
        {
240
277
          log_error (_("can't connect to the dirmngr - trying fall back\n"));
241
278
          force_pipe_server = 1;
242
 
          return start_dirmngr ();
 
279
          return start_dirmngr (ctrl);
243
280
        }
 
281
#endif /*!HAVE_W32_SYSTEM*/
244
282
    }
245
283
 
 
284
  prepare_dirmngr (ctrl, ctx, rc);
 
285
 
246
286
  if (rc)
247
287
    {
248
 
      log_error ("can't connect to the dirmngr: %s\n", assuan_strerror (rc));
 
288
      log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
249
289
      return gpg_error (GPG_ERR_NO_DIRMNGR);
250
290
    }
251
291
  dirmngr_ctx = ctx;
258
298
 
259
299
 
260
300
/* Handle a SENDCERT inquiry. */
261
 
static AssuanError
 
301
static int
262
302
inq_certificate (void *opaque, const char *line)
263
303
{
264
304
  struct inq_certificate_parm_s *parm = opaque;
265
 
  AssuanError rc;
 
305
  int rc;
266
306
  const unsigned char *der;
267
307
  size_t derlen;
268
308
  int issuer_mode = 0;
294
334
  else
295
335
    {
296
336
      log_error ("unsupported inquiry `%s'\n", line);
297
 
      return ASSUAN_Inquire_Unknown;
 
337
      return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
298
338
    }
299
339
 
300
340
  if (!*line)
302
342
      der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
303
343
                                 &derlen);
304
344
      if (!der)
305
 
        rc = ASSUAN_Inquire_Error;
 
345
        rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
306
346
      else
307
347
        rc = assuan_send_data (parm->ctx, der, derlen);
308
348
    }
310
350
    {
311
351
      log_error ("sending specific issuer certificate back "
312
352
                 "is not yet implemented\n");
313
 
      rc = ASSUAN_Inquire_Error;
 
353
      rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
314
354
    }
315
355
  else 
316
356
    { /* Send the given certificate. */
322
362
      if (err)
323
363
        {
324
364
          log_error ("certificate not found: %s\n", gpg_strerror (err));
325
 
          rc = ASSUAN_Inquire_Error;
 
365
          rc = gpg_error (GPG_ERR_NOT_FOUND);
326
366
        }
327
367
      else
328
368
        {
329
369
          der = ksba_cert_get_image (cert, &derlen);
330
370
          if (!der)
331
 
            rc = ASSUAN_Inquire_Error;
 
371
            rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
332
372
          else
333
373
            rc = assuan_send_data (parm->ctx, der, derlen);
334
374
          ksba_cert_release (cert);
371
411
          for (line += 8; *line == ' '; line++)
372
412
            ;
373
413
          if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
374
 
            return ASSUAN_Canceled;
 
414
            return gpg_error (GPG_ERR_ASS_CANCELED);
375
415
        }
376
416
    }
377
417
  else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
394
434
  GPG_ERR_NO_CRL_KNOWN
395
435
  GPG_ERR_CRL_TOO_OLD
396
436
 
397
 
  With USE_OCSP set to true, the dirmngr is asked to do an OCSP
398
 
  request first.
 
437
  Values for USE_OCSP:
 
438
     0 = Do CRL check.
 
439
     1 = Do an OCSP check.
 
440
     2 = Do an OCSP check using only the default responder.
399
441
 */
400
442
int
401
443
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
408
450
  struct inq_certificate_parm_s parm;
409
451
  struct isvalid_status_parm_s stparm;
410
452
 
411
 
 
412
 
  rc = start_dirmngr ();
 
453
  rc = start_dirmngr (ctrl);
413
454
  if (rc)
414
455
    return rc;
415
456
 
445
486
 
446
487
  /* FIXME: If --disable-crl-checks has been set, we should pass an
447
488
     option to dirmngr, so that no fallback CRL check is done after an
448
 
     ocsp check. */
 
489
     ocsp check.  It is not a problem right now as dirmngr does not
 
490
     fallback to CRL checking.  */
449
491
 
450
492
  /* It is sufficient to send the options only once because we have
451
493
     one connection per process only. */
456
498
                         NULL, NULL, NULL, NULL, NULL, NULL);
457
499
      did_options = 1;
458
500
    }
459
 
  snprintf (line, DIM(line)-1, "ISVALID %s", certid);
 
501
  snprintf (line, DIM(line)-1, "ISVALID%s %s", 
 
502
            use_ocsp == 2? " --only-ocsp --force-default-responder":"",
 
503
            certid);
460
504
  line[DIM(line)-1] = 0;
461
505
  xfree (certid);
462
506
 
464
508
                        inq_certificate, &parm,
465
509
                        isvalid_status_cb, &stparm);
466
510
  if (opt.verbose > 1)
467
 
    log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay");
468
 
  rc = map_assuan_err (rc);
 
511
    log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
 
512
  rc = rc;
469
513
 
470
514
  if (!rc && stparm.seen)
471
515
    {
504
548
                rc = gpg_error (GPG_ERR_INV_CRL);
505
549
              else
506
550
                {
507
 
                  /* Note, the flag = 1: This avoids checking this
508
 
                     certificate over and over again. */
509
 
                  rc = gpgsm_validate_chain (ctrl, rspcert, NULL, 0, NULL, 1);
 
551
                  /* Note the no_dirmngr flag: This avoids checking
 
552
                     this certificate over and over again. */
 
553
                  rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL, 
 
554
                                             VALIDATE_FLAG_NO_DIRMNGR, NULL);
510
555
                  if (rc)
511
556
                    {
512
557
                      log_error ("invalid certificate used for CRL/OCSP: %s\n",
524
569
 
525
570
 
526
571
/* Lookup helpers*/
527
 
static AssuanError
 
572
static int
528
573
lookup_cb (void *opaque, const void *buffer, size_t length)
529
574
{
530
575
  struct lookup_parm_s *parm = opaque;
573
618
/* Return a properly escaped pattern from NAMES.  The only error
574
619
   return is NULL to indicate a malloc failure. */
575
620
static char *
576
 
pattern_from_strlist (STRLIST names)
 
621
pattern_from_strlist (strlist_t names)
577
622
{
578
 
  STRLIST sl;
 
623
  strlist_t sl;
579
624
  int n;
580
625
  const char *s;
581
626
  char *pattern, *p;
630
675
  return pattern;
631
676
}
632
677
 
633
 
static AssuanError
 
678
static int
634
679
lookup_status_cb (void *opaque, const char *line)
635
680
{
636
681
  struct lookup_parm_s *parm = opaque;
642
687
          for (line += 8; *line == ' '; line++)
643
688
            ;
644
689
          if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
645
 
            return ASSUAN_Canceled;
 
690
            return gpg_error (GPG_ERR_ASS_CANCELED);
646
691
        }
647
692
    }
648
693
  else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
661
706
/* Run the Directroy Managers lookup command using the pattern
662
707
   compiled from the strings given in NAMES.  The caller must provide
663
708
   the callback CB which will be passed cert by cert.  Note that CTRL
664
 
   is optional. */
 
709
   is optional.  With CACHE_ONLY the dirmngr will search only its own
 
710
   key cache. */
665
711
int 
666
 
gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names,
 
712
gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
667
713
                      void (*cb)(void*, ksba_cert_t), void *cb_value)
668
714
669
715
  int rc;
672
718
  struct lookup_parm_s parm;
673
719
  size_t len;
674
720
 
675
 
  rc = start_dirmngr ();
 
721
  rc = start_dirmngr (ctrl);
676
722
  if (rc)
677
723
    return rc;
678
724
 
679
725
  pattern = pattern_from_strlist (names);
680
726
  if (!pattern)
681
 
    return OUT_OF_CORE (errno);
682
 
  snprintf (line, DIM(line)-1, "LOOKUP %s", pattern);
 
727
    return out_of_core ();
 
728
  snprintf (line, DIM(line)-1, "LOOKUP%s %s", 
 
729
            cache_only? " --cache-only":"", pattern);
683
730
  line[DIM(line)-1] = 0;
684
731
  xfree (pattern);
685
732
 
694
741
                        NULL, NULL, lookup_status_cb, &parm);
695
742
  xfree (get_membuf (&parm.data, &len));
696
743
  if (rc)
697
 
    return map_assuan_err (rc);
 
744
    return rc;
698
745
  return parm.error;
699
746
}
700
747
 
703
750
/* Run Command helpers*/
704
751
 
705
752
/* Fairly simple callback to write all output of dirmngr to stdout. */
706
 
static AssuanError
 
753
static int
707
754
run_command_cb (void *opaque, const void *buffer, size_t length)
708
755
{
709
756
  if (buffer)
715
762
}
716
763
 
717
764
/* Handle inquiries from the dirmngr COMMAND. */
718
 
static AssuanError
 
765
static int
719
766
run_command_inq_cb (void *opaque, const char *line)
720
767
{
721
768
  struct run_command_parm_s *parm = opaque;
722
 
  AssuanError rc = 0;
 
769
  int rc = 0;
723
770
 
724
771
  if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
725
772
    { /* send the given certificate */
730
777
 
731
778
      line += 8;
732
779
      if (!*line)
733
 
        return ASSUAN_Inquire_Error;
 
780
        return gpg_error (GPG_ERR_ASS_PARAMETER);
734
781
 
735
782
      err = gpgsm_find_cert (line, NULL, &cert);
736
783
      if (err)
737
784
        {
738
785
          log_error ("certificate not found: %s\n", gpg_strerror (err));
739
 
          rc = ASSUAN_Inquire_Error;
 
786
          rc = gpg_error (GPG_ERR_NOT_FOUND);
740
787
        }
741
788
      else
742
789
        {
743
790
          der = ksba_cert_get_image (cert, &derlen);
744
791
          if (!der)
745
 
            rc = ASSUAN_Inquire_Error;
 
792
            rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
746
793
          else
747
794
            rc = assuan_send_data (parm->ctx, der, derlen);
748
795
          ksba_cert_release (cert);
756
803
  else
757
804
    {
758
805
      log_error ("unsupported inquiry `%s'\n", line);
759
 
      rc = ASSUAN_Inquire_Unknown;
 
806
      rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
760
807
    }
761
808
 
762
809
  return rc; 
763
810
}
764
811
 
765
 
static AssuanError
 
812
static int
766
813
run_command_status_cb (void *opaque, const char *line)
767
814
{
768
815
  ctrl_t ctrl = opaque;
778
825
          for (line += 8; *line == ' '; line++)
779
826
            ;
780
827
          if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
781
 
            return ASSUAN_Canceled;
 
828
            return gpg_error (GPG_ERR_ASS_CANCELED);
782
829
        }
783
830
    }
784
831
  return 0;
792
839
   percent characters within the argument strings are percent escaped
793
840
   so that blanks can act as delimiters. */
794
841
int
795
 
gpgsm_dirmngr_run_command (CTRL ctrl, const char *command,
 
842
gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
796
843
                           int argc, char **argv)
797
844
798
845
  int rc;
802
849
  size_t len;
803
850
  struct run_command_parm_s parm;
804
851
 
805
 
  rc = start_dirmngr ();
 
852
  rc = start_dirmngr (ctrl);
806
853
  if (rc)
807
854
    return rc;
808
855
 
813
860
    len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
814
861
  line = xtrymalloc (len);
815
862
  if (!line)
816
 
    return OUT_OF_CORE (errno);
 
863
    return out_of_core ();
817
864
 
818
865
  p = stpcpy (line, command);
819
866
  for (i=0; i < argc; i++)
841
888
                        run_command_inq_cb, &parm,
842
889
                        run_command_status_cb, ctrl);
843
890
  xfree (line);
844
 
  log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay");
845
 
  return map_assuan_err (rc);
 
891
  log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
 
892
  return rc;
846
893
}