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

« back to all changes in this revision

Viewing changes to agent/command.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
/* command.c - gpg-agent command handler
2
 
 * Copyright (C) 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
2
 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
 
3
 *               2006, 2008  Free Software Foundation, Inc.
3
4
 *
4
5
 * This file is part of GnuPG.
5
6
 *
6
7
 * GnuPG is free software; you can redistribute it and/or modify
7
8
 * 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
 * the Free Software Foundation; either version 3 of the License, or
9
10
 * (at your option) any later version.
10
11
 *
11
12
 * GnuPG is distributed in the hope that it will be useful,
14
15
 * GNU General Public License for more details.
15
16
 *
16
17
 * 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
 
18
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
21
21
/* FIXME: we should not use the default assuan buffering but setup
40
40
/* maximum allowed size of the key parameters */
41
41
#define MAXLEN_KEYPARAM 1024
42
42
 
43
 
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
 
43
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
44
44
 
45
45
 
46
46
#if MAX_DIGEST_LEN < 20
48
48
#endif
49
49
 
50
50
/* Data used to associate an Assuan context with local server data */
51
 
struct server_local_s {
52
 
  ASSUAN_CONTEXT assuan_ctx;
 
51
struct server_local_s
 
52
{
 
53
  assuan_context_t assuan_ctx;
53
54
  int message_fd;
54
55
  int use_cache_for_signing;
55
56
  char *keydesc;  /* Allocated description for the next key
56
57
                     operation. */
57
 
};
 
58
  int pause_io_logging; /* Used to suppress I/O logging during a command */
 
59
#ifdef HAVE_W32_SYSTEM
 
60
  int stopme;    /* If set to true the agent will be terminated after
 
61
                    the end of this session.  */
 
62
#endif
 
63
  int allow_pinentry_notify; /* Set if pinentry notifications should
 
64
                                be done. */
 
65
};
 
66
 
 
67
 
 
68
/* An entry for the getval/putval commands. */
 
69
struct putval_item_s
 
70
{
 
71
  struct putval_item_s *next;
 
72
  size_t off;  /* Offset to the value into DATA.  */
 
73
  size_t len;  /* Length of the value.  */
 
74
  char d[1];   /* Key | Nul | value.  */ 
 
75
};
 
76
 
 
77
 
 
78
/* A list of key value pairs fpr the getval/putval commands.  */
 
79
static struct putval_item_s *putval_list;
 
80
 
 
81
 
 
82
 
 
83
/* To help polling clients, we keep tarck of the number of certain
 
84
   events.  This structure keeps those counters.  The counters are
 
85
   integers and there should be no problem if they are overflowing as
 
86
   callers need to check only whether a counter changed.  The actual
 
87
   values are not meaningful. */
 
88
struct 
 
89
{
 
90
  /* Incremented if any of the other counters below changed. */
 
91
  unsigned int any;
 
92
 
 
93
  /* Incremented if a key is added or removed from the internal privat
 
94
     key database. */
 
95
  unsigned int key; 
 
96
 
 
97
  /* Incremented if a change of the card readers stati has been
 
98
     detected. */
 
99
  unsigned int card;
 
100
 
 
101
} eventcounter;
58
102
 
59
103
 
60
104
 
87
131
 
88
132
  p = get_membuf (mb, &n);
89
133
  if (!p)
90
 
    return gpg_error (GPG_ERR_ENOMEM);
 
134
    return out_of_core ();
91
135
  ae = assuan_send_data (ctx, p, n);
92
136
  memset (p, 0, n);
93
137
  xfree (p);
94
 
  return map_assuan_err (ae);
 
138
  return ae;
95
139
}
96
140
 
97
141
 
98
142
static void
99
 
reset_notify (ASSUAN_CONTEXT ctx)
 
143
reset_notify (assuan_context_t ctx)
100
144
{
101
145
  ctrl_t ctrl = assuan_get_pointer (ctx);
102
146
 
120
164
  return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
121
165
}
122
166
 
 
167
/* Same as has_option but does only test for the name of the option
 
168
   and ignores an argument, i.e. with NAME being "--hash" it would
 
169
   return true for "--hash" as well as for "--hash=foo". */
 
170
static int
 
171
has_option_name (const char *line, const char *name)
 
172
{
 
173
  const char *s;
 
174
  int n = strlen (name);
 
175
 
 
176
  s = strstr (line, name);
 
177
  return (s && (s == line || spacep (s-1))
 
178
          && (!s[n] || spacep (s+n) || s[n] == '='));
 
179
}
 
180
 
 
181
 
 
182
/* Skip over options.  It is assumed that leading spaces have been
 
183
   removed (this is the case for lines passed to a handler from
 
184
   assuan).  Blanks after the options are also removed. */
 
185
static char *
 
186
skip_options (char *line)
 
187
{
 
188
  while ( *line == '-' && line[1] == '-' )
 
189
    {
 
190
      while (*line && !spacep (line))
 
191
        line++;
 
192
      while (spacep (line))
 
193
        line++;
 
194
    }
 
195
  return line;
 
196
}
 
197
 
 
198
 
123
199
/* Replace all '+' by a blank. */
124
200
static void
125
201
plus_to_blank (char *s)
132
208
}
133
209
 
134
210
 
 
211
/* Do the percent and plus/space unescaping in place and return the
 
212
   length of the valid buffer. */
 
213
static size_t
 
214
percent_plus_unescape (char *string)
 
215
{
 
216
  unsigned char *p = (unsigned char *)string;
 
217
  size_t n = 0;
 
218
 
 
219
  while (*string)
 
220
    {
 
221
      if (*string == '%' && string[1] && string[2])
 
222
        { 
 
223
          string++;
 
224
          *p++ = xtoi_2 (string);
 
225
          n++;
 
226
          string+= 2;
 
227
        }
 
228
      else if (*string == '+')
 
229
        {
 
230
          *p++ = ' ';
 
231
          n++;
 
232
          string++;
 
233
        }
 
234
      else
 
235
        {
 
236
          *p++ = *string++;
 
237
          n++;
 
238
        }
 
239
    }
 
240
 
 
241
  return n;
 
242
}
 
243
 
 
244
 
 
245
 
 
246
 
135
247
/* Parse a hex string.  Return an Assuan error code or 0 on success and the
136
248
   length of the parsed string in LEN. */
137
249
static int
138
 
parse_hexstring (ASSUAN_CONTEXT ctx, const char *string, size_t *len)
 
250
parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
139
251
{
140
252
  const char *p;
141
253
  size_t n;
144
256
  for (p=string, n=0; hexdigitp (p); p++, n++)
145
257
    ;
146
258
  if (*p != ' ' && *p != '\t' && *p)
147
 
    return set_error (Parameter_Error, "invalid hexstring");
 
259
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
148
260
  if ((n&1))
149
 
    return set_error (Parameter_Error, "odd number of digits");
 
261
    return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
150
262
  *len = n;
151
263
  return 0;
152
264
}
153
265
 
154
266
/* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
155
 
   provide space for 20 bytes. BUF is not changed if the fucntions
 
267
   provide space for 20 bytes. BUF is not changed if the function
156
268
   returns an error. */
157
269
static int
158
 
parse_keygrip (ASSUAN_CONTEXT ctx, const char *string, unsigned char *buf)
 
270
parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
159
271
{
160
272
  int rc;
161
273
  size_t n;
166
278
    return rc;
167
279
  n /= 2;
168
280
  if (n != 20)
169
 
    return set_error (Parameter_Error, "invalid length of keygrip");
 
281
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
170
282
 
171
283
  for (p=(const unsigned char*)string, n=0; n < 20; p += 2, n++)
172
284
    buf[n] = xtoi_2 (p);
175
287
}
176
288
 
177
289
 
178
 
 
179
 
 
 
290
/* Write an assuan status line. */
 
291
gpg_error_t
 
292
agent_write_status (ctrl_t ctrl, const char *keyword, ...)
 
293
{
 
294
  gpg_error_t err = 0;
 
295
  va_list arg_ptr;
 
296
  const char *text;
 
297
  assuan_context_t ctx = ctrl->server_local->assuan_ctx;
 
298
  char buf[950], *p;
 
299
  size_t n;
 
300
 
 
301
  va_start (arg_ptr, keyword);
 
302
 
 
303
  p = buf; 
 
304
  n = 0;
 
305
  while ( (text = va_arg (arg_ptr, const char *)) )
 
306
    {
 
307
      if (n)
 
308
        {
 
309
          *p++ = ' ';
 
310
          n++;
 
311
        }
 
312
      for ( ; *text && n < DIM (buf)-2; n++)
 
313
        *p++ = *text++;
 
314
    }
 
315
  *p = 0;
 
316
  err = assuan_write_status (ctx, keyword, buf);
 
317
 
 
318
  va_end (arg_ptr);
 
319
  return err;
 
320
}
 
321
 
 
322
 
 
323
/* Helper to notify the client about a launched Pinentry.  Because
 
324
   that might disturb some older clients, this is only done if enabled
 
325
   via an option.  Returns an gpg error code. */
 
326
gpg_error_t
 
327
agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
 
328
{
 
329
  char line[100];
 
330
 
 
331
  if (!ctrl || !ctrl->server_local 
 
332
      || !ctrl->server_local->allow_pinentry_notify)
 
333
    return 0;
 
334
  snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
 
335
  return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
 
336
}
 
337
 
 
338
 
 
339
 
 
340
/* GETEVENTCOUNTER
 
341
 
 
342
   Return a a status line named EVENTCOUNTER with the current values
 
343
   of all event counters.  The values are decimal numbers in the range
 
344
   0 to UINT_MAX and wrapping around to 0.  The actual values should
 
345
   not be relied upon, they shall only be used to detect a change.
 
346
 
 
347
   The currently defined counters are:
 
348
 
 
349
   ANY  - Incremented with any change of any of the other counters.
 
350
   KEY  - Incremented for added or removed private keys.
 
351
   CARD - Incremented for changes of the card readers stati.
 
352
*/
 
353
static int
 
354
cmd_geteventcounter (assuan_context_t ctx, char *line)
 
355
{
 
356
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
357
  char any_counter[25];
 
358
  char key_counter[25];
 
359
  char card_counter[25];
 
360
 
 
361
  snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
 
362
  snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
 
363
  snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
 
364
 
 
365
  return agent_write_status (ctrl, "EVENTCOUNTER",
 
366
                             any_counter,
 
367
                             key_counter,
 
368
                             card_counter,
 
369
                             NULL);
 
370
}
 
371
 
 
372
 
 
373
/* This function should be called once for all key removals or
 
374
   additions.  This function is assured not to do any context
 
375
   switches. */
 
376
void
 
377
bump_key_eventcounter (void)
 
378
{
 
379
  eventcounter.key++;
 
380
  eventcounter.any++;
 
381
}
 
382
 
 
383
/* This function should be called for all card reader status
 
384
   changes.  This function is assured not to do any context
 
385
   switches. */
 
386
void
 
387
bump_card_eventcounter (void)
 
388
{
 
389
  eventcounter.card++;
 
390
  eventcounter.any++;
 
391
}
 
392
 
 
393
 
 
394
 
 
395
 
180
396
/* ISTRUSTED <hexstring_with_fingerprint>
181
397
 
182
398
   Return OK when we have an entry with this fingerprint in our
183
399
   trustlist */
184
400
static int
185
 
cmd_istrusted (ASSUAN_CONTEXT ctx, char *line)
 
401
cmd_istrusted (assuan_context_t ctx, char *line)
186
402
{
 
403
  ctrl_t ctrl = assuan_get_pointer (ctx);
187
404
  int rc, n, i;
188
405
  char *p;
189
406
  char fpr[41];
190
407
 
191
 
  /* parse the fingerprint value */
 
408
  /* Parse the fingerprint value. */
192
409
  for (p=line,n=0; hexdigitp (p); p++, n++)
193
410
    ;
194
411
  if (*p || !(n == 40 || n == 32))
195
 
    return set_error (Parameter_Error, "invalid fingerprint");
 
412
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
196
413
  i = 0;
197
414
  if (n==32)
198
415
    {
202
419
  for (p=line; i < 40; p++, i++)
203
420
    fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
204
421
  fpr[i] = 0;
205
 
  rc = agent_istrusted (fpr);
206
 
  if (!rc)
207
 
    return 0;
208
 
  else if (rc == -1)
209
 
    return ASSUAN_Not_Trusted;
 
422
  rc = agent_istrusted (ctrl, fpr);
 
423
  if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
 
424
    return rc;
 
425
  else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
 
426
    return gpg_error (GPG_ERR_NOT_TRUSTED);
210
427
  else
211
428
    {
212
429
      log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
213
 
      return map_to_assuan_status (rc);
 
430
      return rc;
214
431
    }
215
432
}
216
433
 
218
435
 
219
436
   List all entries from the trustlist */
220
437
static int
221
 
cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line)
 
438
cmd_listtrusted (assuan_context_t ctx, char *line)
222
439
{
223
440
  int rc = agent_listtrusted (ctx);
224
441
  if (rc)
225
442
    log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
226
 
  return map_to_assuan_status (rc);
 
443
  return rc;
227
444
}
228
445
 
229
446
 
231
448
 
232
449
   Store a new key in into the trustlist*/
233
450
static int
234
 
cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line)
 
451
cmd_marktrusted (assuan_context_t ctx, char *line)
235
452
{
236
453
  ctrl_t ctrl = assuan_get_pointer (ctx);
237
454
  int rc, n, i;
243
460
  for (p=line,n=0; hexdigitp (p); p++, n++)
244
461
    ;
245
462
  if (!spacep (p) || !(n == 40 || n == 32))
246
 
    return set_error (Parameter_Error, "invalid fingerprint");
 
463
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
247
464
  i = 0;
248
465
  if (n==32)
249
466
    {
258
475
    p++;
259
476
  flag = *p++;
260
477
  if ( (flag != 'S' && flag != 'P') || !spacep (p) )
261
 
    return set_error (Parameter_Error, "invalid flag - must be P or S");
 
478
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
262
479
  while (spacep (p))
263
480
    p++;
264
481
 
265
482
  rc = agent_marktrusted (ctrl, p, fpr, flag);
266
483
  if (rc)
267
484
    log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
268
 
  return map_to_assuan_status (rc);
 
485
  return rc;
269
486
}
270
487
 
271
488
 
275
492
  
276
493
   Return success when the secret key is available */
277
494
static int
278
 
cmd_havekey (ASSUAN_CONTEXT ctx, char *line)
 
495
cmd_havekey (assuan_context_t ctx, char *line)
279
496
{
280
497
  int rc;
281
498
  unsigned char buf[20];
285
502
    return rc;
286
503
 
287
504
  if (agent_key_available (buf))
288
 
    return ASSUAN_No_Secret_Key;
 
505
    return gpg_error (GPG_ERR_NO_SECKEY);
289
506
 
290
507
  return 0;
291
508
}
296
513
  
297
514
   Set the  key used for a sign or decrypt operation */
298
515
static int
299
 
cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
 
516
cmd_sigkey (assuan_context_t ctx, char *line)
300
517
{
301
518
  int rc;
302
519
  ctrl_t ctrl = assuan_get_pointer (ctx);
309
526
}
310
527
 
311
528
 
312
 
/* SETKEYDESC plus_percent_escaped_string:
 
529
/* SETKEYDESC plus_percent_escaped_string
313
530
 
314
531
   Set a description to be used for the next PKSIGN or PKDECRYPT
315
532
   operation if this operation requires the entry of a passphrase.  If
317
534
   this description implictly selects the label used for the entry
318
535
   box; if the string contains the string PIN (which in general will
319
536
   not be translated), "PIN" is used, otherwise the translation of
320
 
   'passphrase" is used.  The description string should not contain
 
537
   "passphrase" is used.  The description string should not contain
321
538
   blanks unless they are percent or '+' escaped.
322
539
 
323
540
   The description is only valid for the next PKSIGN or PKDECRYPT
337
554
    *p = 0; /* We ignore any garbage; we might late use it for other args. */
338
555
 
339
556
  if (!desc || !*desc)
340
 
    return set_error (Parameter_Error, "no description given");
 
557
    return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
341
558
 
342
559
  /* Note, that we only need to replace the + characters and should
343
560
     leave the other escaping in place because the escaped string is
348
565
  xfree (ctrl->server_local->keydesc);
349
566
  ctrl->server_local->keydesc = xtrystrdup (desc);
350
567
  if (!ctrl->server_local->keydesc)
351
 
    return map_to_assuan_status (gpg_error_from_errno (errno));
 
568
    return out_of_core ();
352
569
  return 0;
353
570
}
354
571
 
355
572
 
356
 
/* SETHASH <algonumber> <hexstring> 
 
573
/* SETHASH --hash=<name>|<algonumber> <hexstring> 
357
574
 
358
575
  The client can use this command to tell the server about the data
359
576
  (which usually is a hash) to be signed. */
360
577
static int
361
 
cmd_sethash (ASSUAN_CONTEXT ctx, char *line)
 
578
cmd_sethash (assuan_context_t ctx, char *line)
362
579
{
363
580
  int rc;
364
581
  size_t n;
368
585
  char *endp;
369
586
  int algo;
370
587
 
371
 
  /* parse the algo number and check it */
372
 
  algo = (int)strtoul (line, &endp, 10);
373
 
  for (line = endp; *line == ' ' || *line == '\t'; line++)
374
 
    ;
375
 
  if (!algo || gcry_md_test_algo (algo))
376
 
    return set_error (Unsupported_Algorithm, NULL);
 
588
  /* Parse the alternative hash options which may be used instead of
 
589
     the algo number.  */
 
590
  if (has_option_name (line, "--hash"))
 
591
    {
 
592
      if (has_option (line, "--hash=sha1"))
 
593
        algo = GCRY_MD_SHA1;
 
594
      else if (has_option (line, "--hash=sha256"))
 
595
        algo = GCRY_MD_SHA256;
 
596
      else if (has_option (line, "--hash=rmd160"))
 
597
        algo = GCRY_MD_RMD160;
 
598
      else if (has_option (line, "--hash=md5"))
 
599
        algo = GCRY_MD_MD5;
 
600
      else if (has_option (line, "--hash=tls-md5sha1"))
 
601
        algo = GCRY_MD_USER_TLS_MD5SHA1;
 
602
      else
 
603
        return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
 
604
    }
 
605
  else
 
606
    algo = 0;
 
607
 
 
608
  line = skip_options (line);
 
609
  
 
610
  if (!algo)
 
611
    {
 
612
      /* No hash option has been given: require an algo number instead  */
 
613
      algo = (int)strtoul (line, &endp, 10);
 
614
      for (line = endp; *line == ' ' || *line == '\t'; line++)
 
615
        ;
 
616
      if (!algo || gcry_md_test_algo (algo))
 
617
        return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
 
618
    }
377
619
  ctrl->digest.algo = algo;
378
620
 
379
 
  /* parse the hash value */
 
621
  /* Parse the hash value. */
380
622
  rc = parse_hexstring (ctx, line, &n);
381
623
  if (rc)
382
624
    return rc;
383
625
  n /= 2;
384
 
  if (n != 16 && n != 20 && n != 24 && n != 32)
385
 
    return set_error (Parameter_Error, "unsupported length of hash");
 
626
  if (algo == GCRY_MD_USER_TLS_MD5SHA1 && n == 36)
 
627
    ;
 
628
  else if (n != 16 && n != 20 && n != 24 && n != 32)
 
629
    return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
 
630
 
386
631
  if (n > MAX_DIGEST_LEN)
387
 
    return set_error (Parameter_Error, "hash value to long");
 
632
    return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
388
633
 
389
634
  buf = ctrl->digest.value;
390
635
  ctrl->digest.valuelen = n;
401
646
   Perform the actual sign operation. Neither input nor output are
402
647
   sensitive to eavesdropping. */
403
648
static int
404
 
cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
 
649
cmd_pksign (assuan_context_t ctx, char *line)
405
650
{
406
651
  int rc;
407
652
  cache_mode_t cache_mode = CACHE_MODE_NORMAL;
425
670
    log_error ("command pksign failed: %s\n", gpg_strerror (rc));
426
671
  xfree (ctrl->server_local->keydesc);
427
672
  ctrl->server_local->keydesc = NULL;
428
 
  return map_to_assuan_status (rc);
 
673
  return rc;
429
674
}
430
675
 
431
676
/* PKDECRYPT <options>
433
678
   Perform the actual decrypt operation.  Input is not 
434
679
   sensitive to eavesdropping */
435
680
static int
436
 
cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
 
681
cmd_pkdecrypt (assuan_context_t ctx, char *line)
437
682
{
438
683
  int rc;
439
684
  ctrl_t ctrl = assuan_get_pointer (ctx);
460
705
    log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
461
706
  xfree (ctrl->server_local->keydesc);
462
707
  ctrl->server_local->keydesc = NULL;
463
 
  return map_to_assuan_status (rc);
 
708
  return rc;
464
709
}
465
710
 
466
711
 
470
715
   part.  Here is an example transaction:
471
716
 
472
717
   C: GENKEY
473
 
   S: INQUIRE KEYPARM
 
718
   S: INQUIRE KEYPARAM
474
719
   C: D (genkey (rsa (nbits  1024)))
475
720
   C: END
476
721
   S: D (public-key
479
724
*/
480
725
 
481
726
static int
482
 
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
 
727
cmd_genkey (assuan_context_t ctx, char *line)
483
728
{
484
729
  ctrl_t ctrl = assuan_get_pointer (ctx);
485
730
  int rc;
502
747
    rc = write_and_clear_outbuf (ctx, &outbuf);
503
748
  if (rc)
504
749
    log_error ("command genkey failed: %s\n", gpg_strerror (rc));
505
 
  return map_to_assuan_status (rc);
 
750
  return rc;
506
751
}
507
752
 
508
753
 
533
778
      assert (len);
534
779
      buf = xtrymalloc (len);
535
780
      if (!buf)
536
 
        rc = gpg_error_from_errno (errno);
 
781
        rc = gpg_error_from_syserror ();
537
782
      else
538
783
        {
539
784
          len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
540
785
          assert (len);
541
786
          rc = assuan_send_data (ctx, buf, len);
542
 
          rc = map_assuan_err (rc);
543
787
          xfree (buf);
544
788
        }
545
789
      gcry_sexp_release (s_pkey);
547
791
 
548
792
  if (rc)
549
793
    log_error ("command readkey failed: %s\n", gpg_strerror (rc));
550
 
  return map_to_assuan_status (rc);
 
794
  return rc;
551
795
}
552
796
 
553
797
 
555
799
 
556
800
 
557
801
 
558
 
/* GET_PASSPHRASE <cache_id> [<error_message> <prompt> <description>]
 
802
static int
 
803
send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
 
804
{
 
805
  size_t n;
 
806
  int rc;
 
807
 
 
808
  assuan_begin_confidential (ctx);
 
809
  n = strlen (pw);
 
810
  if (via_data)
 
811
    rc = assuan_send_data (ctx, pw, n);
 
812
  else
 
813
    {
 
814
      char *p = xtrymalloc_secure (n*2+1);
 
815
      if (!p)
 
816
        rc = gpg_error_from_syserror ();
 
817
      else
 
818
        {
 
819
          bin2hex (pw, n, p);
 
820
          rc = assuan_set_okay_line (ctx, p);
 
821
          xfree (p);
 
822
        }
 
823
    }
 
824
  return rc;
 
825
}
 
826
 
 
827
 
 
828
/* GET_PASSPHRASE [--data] [--check] <cache_id>
 
829
                  [<error_message> <prompt> <description>]
559
830
 
560
831
   This function is usually used to ask for a passphrase to be used
561
832
   for conventional encryption, but may also be used by programs which
564
835
   agent either returns with an error or with a OK followed by the hex
565
836
   encoded passphrase.  Note that the length of the strings is
566
837
   implicitly limited by the maximum length of a command.
 
838
 
 
839
   If the option "--data" is used the passphrase is returned by usual
 
840
   data lines and not on the okay line.
 
841
 
 
842
   If the option "--check" is used the passphrase constraints checks as
 
843
   implemented by gpg-agent are applied.  A check is not done if the
 
844
   passphrase has been found in the cache.
567
845
*/
568
846
 
569
847
static int
570
 
cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
 
848
cmd_get_passphrase (assuan_context_t ctx, char *line)
571
849
{
572
850
  ctrl_t ctrl = assuan_get_pointer (ctx);
573
851
  int rc;
576
854
  char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
577
855
  char *p;
578
856
  void *cache_marker;
579
 
 
580
 
  /* parse the stuff */
581
 
  for (p=line; *p == ' '; p++)
582
 
    ;
583
 
  cacheid = p;
 
857
  int opt_data, opt_check;
 
858
 
 
859
  opt_data = has_option (line, "--data");
 
860
  opt_check = has_option (line, "--check");
 
861
  line = skip_options (line);
 
862
 
 
863
  cacheid = line;
584
864
  p = strchr (cacheid, ' ');
585
865
  if (p)
586
866
    {
604
884
              desc = p;
605
885
              p = strchr (desc, ' ');
606
886
              if (p)
607
 
                *p = 0; /* ignore garbage */
 
887
                *p = 0; /* Ignore trailing garbage. */
608
888
            }
609
889
        }
610
890
    }
611
891
  if (!cacheid || !*cacheid || strlen (cacheid) > 50)
612
 
    return set_error (Parameter_Error, "invalid length of cacheID");
 
892
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
613
893
  if (!desc)
614
 
    return set_error (Parameter_Error, "no description given");
 
894
    return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
615
895
 
616
896
  if (!strcmp (cacheid, "X"))
617
897
    cacheid = NULL;
622
902
  if (!strcmp (desc, "X"))
623
903
    desc = NULL;
624
904
 
625
 
  /* Note: we store the hexified versions in the cache. */
626
905
  pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
627
906
               : NULL;
628
907
  if (pw)
629
908
    {
630
 
      assuan_begin_confidential (ctx);
631
 
      rc = assuan_set_okay_line (ctx, pw);
 
909
      rc = send_back_passphrase (ctx, opt_data, pw);
632
910
      agent_unlock_cache_entry (&cache_marker);
633
911
    }
634
912
  else
644
922
      if (desc)
645
923
        plus_to_blank (desc);
646
924
 
647
 
      rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
 
925
      response = NULL;
 
926
      do
 
927
        {
 
928
          xfree (response);
 
929
          rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
 
930
        }
 
931
      while (!rc
 
932
             && opt_check
 
933
             && check_passphrase_constraints (ctrl, response, 0));
 
934
 
648
935
      if (!rc)
649
936
        {
650
937
          if (cacheid)
651
938
            agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
652
 
          assuan_begin_confidential (ctx);
653
 
          rc = assuan_set_okay_line (ctx, response);
 
939
          rc = send_back_passphrase (ctx, opt_data, response);
654
940
          xfree (response);
655
941
        }
656
942
    }
657
943
 
658
944
  if (rc)
659
945
    log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
660
 
  return map_to_assuan_status (rc);
 
946
  return rc;
661
947
}
662
948
 
663
949
 
668
954
*/
669
955
 
670
956
static int
671
 
cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line)
 
957
cmd_clear_passphrase (assuan_context_t ctx, char *line)
672
958
{
673
959
  char *cacheid = NULL;
674
960
  char *p;
681
967
  if (p)
682
968
    *p = 0; /* ignore garbage */
683
969
  if (!cacheid || !*cacheid || strlen (cacheid) > 50)
684
 
    return set_error (Parameter_Error, "invalid length of cacheID");
 
970
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
685
971
 
686
972
  agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
687
973
  return 0;
701
987
*/
702
988
 
703
989
static int
704
 
cmd_get_confirmation (ASSUAN_CONTEXT ctx, char *line)
 
990
cmd_get_confirmation (assuan_context_t ctx, char *line)
705
991
{
706
992
  ctrl_t ctrl = assuan_get_pointer (ctx);
707
993
  int rc;
717
1003
    *p = 0; /* We ignore any garbage -may be later used for other args. */
718
1004
 
719
1005
  if (!desc || !*desc)
720
 
    return set_error (Parameter_Error, "no description given");
 
1006
    return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
721
1007
 
722
1008
  if (!strcmp (desc, "X"))
723
1009
    desc = NULL;
732
1018
  rc = agent_get_confirmation (ctrl, desc, NULL, NULL);
733
1019
  if (rc)
734
1020
    log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
735
 
  return map_to_assuan_status (rc);
 
1021
  return rc;
736
1022
}
737
1023
 
738
1024
 
742
1028
   Learn something about the currently inserted smartcard.  With
743
1029
   --send the new certificates are send back.  */
744
1030
static int
745
 
cmd_learn (ASSUAN_CONTEXT ctx, char *line)
 
1031
cmd_learn (assuan_context_t ctx, char *line)
746
1032
{
747
1033
  ctrl_t ctrl = assuan_get_pointer (ctx);
748
1034
  int rc;
750
1036
  rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
751
1037
  if (rc)
752
1038
    log_error ("command learn failed: %s\n", gpg_strerror (rc));
753
 
  return map_to_assuan_status (rc);
 
1039
  return rc;
754
1040
}
755
1041
 
756
1042
 
759
1045
  
760
1046
   Change the passphrase/PID for the key identified by keygrip in LINE. */
761
1047
static int
762
 
cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
 
1048
cmd_passwd (assuan_context_t ctx, char *line)
763
1049
{
764
1050
  ctrl_t ctrl = assuan_get_pointer (ctx);
765
1051
  int rc;
769
1055
 
770
1056
  rc = parse_keygrip (ctx, line, grip);
771
1057
  if (rc)
772
 
    return rc; /* we can't jump to leave because this is already an
773
 
                  Assuan error code. */
 
1058
    goto leave;
774
1059
 
 
1060
  ctrl->in_passwd++;
775
1061
  rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
776
1062
                            grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey);
777
1063
  if (rc)
783
1069
    }
784
1070
  else
785
1071
    rc = agent_protect_and_store (ctrl, s_skey);
 
1072
  ctrl->in_passwd--;
786
1073
 
787
1074
  xfree (ctrl->server_local->keydesc);
788
1075
  ctrl->server_local->keydesc = NULL;
 
1076
 
 
1077
 leave:
789
1078
  gcry_sexp_release (s_skey);
790
1079
  xfree (shadow_info);
791
1080
  if (rc)
792
1081
    log_error ("command passwd failed: %s\n", gpg_strerror (rc));
793
 
  return map_to_assuan_status (rc);
 
1082
  return rc;
794
1083
}
795
1084
 
796
 
/* PRESET_PASSPHRASE <hexstring_with_keygrip> <timeout> <passwd>
 
1085
/* PRESET_PASSPHRASE <hexstring_with_keygrip> <timeout> <hexstring>
797
1086
  
798
1087
   Set the cached passphrase/PIN for the key identified by the keygrip
799
1088
   to passwd for the given time, where -1 means infinite and 0 means
801
1090
   to never expire it).  If passwd is not provided, ask for it via the
802
1091
   pinentry module.  */
803
1092
static int
804
 
cmd_preset_passphrase (ASSUAN_CONTEXT ctx, char *line)
 
1093
cmd_preset_passphrase (assuan_context_t ctx, char *line)
805
1094
{
806
1095
  int rc;
807
1096
  unsigned char grip[20];
808
1097
  char *grip_clear = NULL;
809
1098
  char *passphrase = NULL;
810
1099
  int ttl;
 
1100
  size_t len;
811
1101
 
812
1102
  if (!opt.allow_preset_passphrase)
813
1103
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
821
1111
  while (*line && (*line != ' ' && *line != '\t'))
822
1112
    line++;
823
1113
  if (!*line)
824
 
    return map_to_assuan_status (gpg_error (GPG_ERR_MISSING_VALUE));
 
1114
    return gpg_error (GPG_ERR_MISSING_VALUE);
825
1115
  *line = '\0';
826
1116
  line++;
827
1117
  while (*line && (*line == ' ' || *line == '\t'))
830
1120
  /* Currently, only infinite timeouts are allowed.  */
831
1121
  ttl = -1;
832
1122
  if (line[0] != '-' || line[1] != '1')
833
 
    return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED));
 
1123
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
834
1124
  line++;
835
1125
  line++;
836
1126
  while (!(*line != ' ' && *line != '\t'))
837
1127
    line++;
838
1128
 
 
1129
  /* Syntax check the hexstring.  */
 
1130
  rc = parse_hexstring (ctx, line, &len);
 
1131
  if (rc)
 
1132
    return rc;
 
1133
  line[len] = '\0';
 
1134
 
839
1135
  /* If there is a passphrase, use it.  Currently, a passphrase is
840
1136
     required.  */
841
1137
  if (*line)
842
1138
    passphrase = line;
843
1139
  else
844
 
    return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED));
 
1140
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
845
1141
 
846
1142
  rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
847
1143
 
848
1144
  if (rc)
849
1145
    log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc));
850
1146
 
851
 
  return map_to_assuan_status (rc);
 
1147
  return rc;
852
1148
}
853
1149
 
854
1150
 
857
1153
   This is a general quote command to redirect everything to the
858
1154
   SCDAEMON. */
859
1155
static int
860
 
cmd_scd (ASSUAN_CONTEXT ctx, char *line)
 
1156
cmd_scd (assuan_context_t ctx, char *line)
861
1157
{
862
1158
  ctrl_t ctrl = assuan_get_pointer (ctx);
863
1159
  int rc;
864
1160
 
865
1161
  rc = divert_generic_cmd (ctrl, line, ctx);
866
1162
 
867
 
  return map_to_assuan_status (rc);
868
 
}
 
1163
  return rc;
 
1164
}
 
1165
 
 
1166
 
 
1167
 
 
1168
/* GETVAL <key>
 
1169
 
 
1170
   Return the value for KEY from the special environment as created by
 
1171
   PUTVAL.
 
1172
 */
 
1173
static int
 
1174
cmd_getval (assuan_context_t ctx, char *line)
 
1175
{
 
1176
  int rc = 0;
 
1177
  char *key = NULL;
 
1178
  char *p;
 
1179
  struct putval_item_s *vl;
 
1180
 
 
1181
  for (p=line; *p == ' '; p++)
 
1182
    ;
 
1183
  key = p;
 
1184
  p = strchr (key, ' ');
 
1185
  if (p)
 
1186
    {
 
1187
      *p++ = 0; 
 
1188
      for (; *p == ' '; p++)
 
1189
        ;
 
1190
      if (*p)
 
1191
        return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
 
1192
    }
 
1193
  if (!key || !*key)
 
1194
    return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
 
1195
 
 
1196
 
 
1197
  for (vl=putval_list; vl; vl = vl->next)
 
1198
    if ( !strcmp (vl->d, key) )
 
1199
      break;
 
1200
 
 
1201
  if (vl) /* Got an entry. */
 
1202
    rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
 
1203
  else
 
1204
    return gpg_error (GPG_ERR_NO_DATA);
 
1205
 
 
1206
  if (rc)
 
1207
    log_error ("command getval failed: %s\n", gpg_strerror (rc));
 
1208
  return rc;
 
1209
}
 
1210
 
 
1211
 
 
1212
/* PUTVAL <key> [<percent_escaped_value>]
 
1213
 
 
1214
   The gpg-agent maintains a kind of environment which may be used to
 
1215
   store key/value pairs in it, so that they can be retrieved later.
 
1216
   This may be used by helper daemons to daemonize themself on
 
1217
   invocation and register them with gpg-agent.  Callers of the
 
1218
   daemon's service may now first try connect to get the information
 
1219
   for that service from gpg-agent through the GETVAL command and then
 
1220
   try to connect to that daemon.  Only if that fails they may start
 
1221
   an own instance of the service daemon. 
 
1222
 
 
1223
   KEY is an an arbitrary symbol with the same syntax rules as keys
 
1224
   for shell environment variables.  PERCENT_ESCAPED_VALUE is the
 
1225
   corresponsing value; they should be similar to the values of
 
1226
   envronment variables but gpg-agent does not enforce any
 
1227
   restrictions.  If that value is not given any value under that KEY
 
1228
   is removed from this special environment.
 
1229
*/
 
1230
static int
 
1231
cmd_putval (assuan_context_t ctx, char *line)
 
1232
{
 
1233
  int rc = 0;
 
1234
  char *key = NULL;
 
1235
  char *value = NULL;
 
1236
  size_t valuelen = 0;
 
1237
  char *p;
 
1238
  struct putval_item_s *vl, *vlprev;
 
1239
 
 
1240
  for (p=line; *p == ' '; p++)
 
1241
    ;
 
1242
  key = p;
 
1243
  p = strchr (key, ' ');
 
1244
  if (p)
 
1245
    {
 
1246
      *p++ = 0; 
 
1247
      for (; *p == ' '; p++)
 
1248
        ;
 
1249
      if (*p)
 
1250
        {
 
1251
          value = p;
 
1252
          p = strchr (value, ' ');
 
1253
          if (p)
 
1254
            *p = 0;
 
1255
          valuelen = percent_plus_unescape (value);
 
1256
        }
 
1257
    }
 
1258
  if (!key || !*key)
 
1259
    return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
 
1260
 
 
1261
 
 
1262
  for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
 
1263
    if ( !strcmp (vl->d, key) )
 
1264
      break;
 
1265
 
 
1266
  if (vl) /* Delete old entry. */
 
1267
    {
 
1268
      if (vlprev)
 
1269
        vlprev->next = vl->next;
 
1270
      else
 
1271
        putval_list = vl->next;
 
1272
      xfree (vl);
 
1273
    }
 
1274
 
 
1275
  if (valuelen) /* Add entry. */  
 
1276
    {
 
1277
      vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
 
1278
      if (!vl)
 
1279
        rc = gpg_error_from_syserror ();
 
1280
      else
 
1281
        {
 
1282
          vl->len = valuelen;
 
1283
          vl->off = strlen (key) + 1;
 
1284
          strcpy (vl->d, key);
 
1285
          memcpy (vl->d + vl->off, value, valuelen);
 
1286
          vl->next = putval_list;
 
1287
          putval_list = vl;
 
1288
        }
 
1289
    }
 
1290
 
 
1291
  if (rc)
 
1292
    log_error ("command putval failed: %s\n", gpg_strerror (rc));
 
1293
  return rc;
 
1294
}
 
1295
 
869
1296
 
870
1297
 
871
1298
 
885
1312
  xfree (opt.startup_ttytype); opt.startup_ttytype = NULL;
886
1313
  xfree (opt.startup_lc_ctype); opt.startup_lc_ctype = NULL;
887
1314
  xfree (opt.startup_lc_messages); opt.startup_lc_messages = NULL;
 
1315
  xfree (opt.startup_xauthority); opt.startup_xauthority = NULL;
888
1316
 
889
1317
  if (ctrl->display)
890
1318
    opt.startup_display = xtrystrdup (ctrl->display);
896
1324
    opt.startup_lc_ctype = xtrystrdup (ctrl->lc_ctype);
897
1325
  if (ctrl->lc_messages)
898
1326
    opt.startup_lc_messages = xtrystrdup (ctrl->lc_messages);
899
 
 
900
 
  return 0;
901
 
}
902
 
 
903
 
 
904
 
 
905
 
static int
906
 
option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
 
1327
  if (ctrl->xauthority)
 
1328
    opt.startup_xauthority = xtrystrdup (ctrl->xauthority);
 
1329
  if (ctrl->pinentry_user_data)
 
1330
    opt.startup_pinentry_user_data = xtrystrdup (ctrl->pinentry_user_data);
 
1331
 
 
1332
  return 0;
 
1333
}
 
1334
 
 
1335
 
 
1336
 
 
1337
#ifdef HAVE_W32_SYSTEM
 
1338
/* KILLAGENT
 
1339
 
 
1340
   Under Windows we start the agent on the fly.  Thus it also make
 
1341
   sense to allow a client to stop the agent. */
 
1342
static int
 
1343
cmd_killagent (assuan_context_t ctx, char *line)
 
1344
{
 
1345
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
1346
  ctrl->server_local->stopme = 1;
 
1347
  return 0;
 
1348
}
 
1349
 
 
1350
/* RELOADAGENT
 
1351
 
 
1352
   As signals are inconvenient under Windows, we provide this command
 
1353
   to allow reloading of the configuration.  */
 
1354
static int
 
1355
cmd_reloadagent (assuan_context_t ctx, char *line)
 
1356
{
 
1357
  agent_sighup_action ();
 
1358
  return 0;
 
1359
}
 
1360
#endif /*HAVE_W32_SYSTEM*/
 
1361
 
 
1362
 
 
1363
 
 
1364
/* GETINFO <what>
 
1365
 
 
1366
   Multipurpose function to return a variety of information.
 
1367
   Supported values for WHAT are:
 
1368
 
 
1369
     version     - Return the version of the program.
 
1370
     pid         - Return the process id of the server.
 
1371
     socket_name - Return the name of the socket.
 
1372
     ssh_socket_name - Return the name of the ssh socket.
 
1373
 
 
1374
 */
 
1375
static int
 
1376
cmd_getinfo (assuan_context_t ctx, char *line)
 
1377
{
 
1378
  int rc = 0;
 
1379
 
 
1380
  if (!strcmp (line, "version"))
 
1381
    {
 
1382
      const char *s = VERSION;
 
1383
      rc = assuan_send_data (ctx, s, strlen (s));
 
1384
    }
 
1385
  else if (!strcmp (line, "pid"))
 
1386
    {
 
1387
      char numbuf[50];
 
1388
 
 
1389
      snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
 
1390
      rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
 
1391
    }
 
1392
  else if (!strcmp (line, "socket_name"))
 
1393
    {
 
1394
      const char *s = get_agent_socket_name ();
 
1395
 
 
1396
      if (s)
 
1397
        rc = assuan_send_data (ctx, s, strlen (s));
 
1398
      else
 
1399
        rc = gpg_error (GPG_ERR_NO_DATA);
 
1400
    }
 
1401
  else if (!strcmp (line, "ssh_socket_name"))
 
1402
    {
 
1403
      const char *s = get_agent_ssh_socket_name ();
 
1404
 
 
1405
      if (s)
 
1406
        rc = assuan_send_data (ctx, s, strlen (s));
 
1407
      else
 
1408
        rc = gpg_error (GPG_ERR_NO_DATA);
 
1409
    }
 
1410
  else
 
1411
    rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
 
1412
  return rc;
 
1413
}
 
1414
 
 
1415
 
 
1416
 
 
1417
static int
 
1418
option_handler (assuan_context_t ctx, const char *key, const char *value)
907
1419
{
908
1420
  ctrl_t ctrl = assuan_get_pointer (ctx);
909
1421
 
913
1425
        free (ctrl->display);
914
1426
      ctrl->display = strdup (value);
915
1427
      if (!ctrl->display)
916
 
        return ASSUAN_Out_Of_Core;
 
1428
        return out_of_core ();
917
1429
    }
918
1430
  else if (!strcmp (key, "ttyname"))
919
1431
    {
923
1435
            free (ctrl->ttyname);
924
1436
          ctrl->ttyname = strdup (value);
925
1437
          if (!ctrl->ttyname)
926
 
            return ASSUAN_Out_Of_Core;
 
1438
            return out_of_core ();
927
1439
        }
928
1440
    }
929
1441
  else if (!strcmp (key, "ttytype"))
934
1446
            free (ctrl->ttytype);
935
1447
          ctrl->ttytype = strdup (value);
936
1448
          if (!ctrl->ttytype)
937
 
            return ASSUAN_Out_Of_Core;
 
1449
            return out_of_core ();
938
1450
        }
939
1451
    }
940
1452
  else if (!strcmp (key, "lc-ctype"))
943
1455
        free (ctrl->lc_ctype);
944
1456
      ctrl->lc_ctype = strdup (value);
945
1457
      if (!ctrl->lc_ctype)
946
 
        return ASSUAN_Out_Of_Core;
 
1458
        return out_of_core ();
947
1459
    }
948
1460
  else if (!strcmp (key, "lc-messages"))
949
1461
    {
951
1463
        free (ctrl->lc_messages);
952
1464
      ctrl->lc_messages = strdup (value);
953
1465
      if (!ctrl->lc_messages)
954
 
        return ASSUAN_Out_Of_Core;
 
1466
        return out_of_core ();
 
1467
    }
 
1468
  else if (!strcmp (key, "xauthority"))
 
1469
    {
 
1470
      if (ctrl->xauthority)
 
1471
        free (ctrl->xauthority);
 
1472
      ctrl->xauthority = strdup (value);
 
1473
      if (!ctrl->xauthority)
 
1474
        return out_of_core ();
 
1475
    }
 
1476
  else if (!strcmp (key, "pinentry-user-data"))
 
1477
    {
 
1478
      if (ctrl->pinentry_user_data)
 
1479
        free (ctrl->pinentry_user_data);
 
1480
      ctrl->pinentry_user_data = strdup (value);
 
1481
      if (!ctrl->pinentry_user_data)
 
1482
        return out_of_core ();
955
1483
    }
956
1484
  else if (!strcmp (key, "use-cache-for-signing"))
957
1485
    ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
 
1486
  else if (!strcmp (key, "allow-pinentry-notify"))
 
1487
    ctrl->server_local->allow_pinentry_notify = 1;
958
1488
  else
959
 
    return ASSUAN_Invalid_Option;
 
1489
    return gpg_error (GPG_ERR_UNKNOWN_OPTION);
960
1490
 
961
1491
  return 0;
962
1492
}
963
1493
 
 
1494
 
 
1495
 
964
1496
 
 
1497
/* Called by libassuan after all commands. ERR is the error from the
 
1498
   last assuan operation and not the one returned from the command. */
 
1499
static void
 
1500
post_cmd_notify (assuan_context_t ctx, int err)
 
1501
{
 
1502
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
1503
 
 
1504
  /* Switch off any I/O monitor controlled logging pausing. */
 
1505
  ctrl->server_local->pause_io_logging = 0;
 
1506
}
 
1507
 
 
1508
 
 
1509
/* This function is called by libassuan for all I/O.  We use it here
 
1510
   to disable logging for the GETEVENTCOUNTER commands.  This is so
 
1511
   that the debug output won't get cluttered by this primitive
 
1512
   command.  */
 
1513
static unsigned int
 
1514
io_monitor (assuan_context_t ctx, int direction,
 
1515
            const char *line, size_t linelen)
 
1516
{
 
1517
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
1518
 
 
1519
  /* Note that we only check for the uppercase name.  This allows to
 
1520
     see the logging for debugging if using a non-upercase command
 
1521
     name. */
 
1522
  if (ctx && !direction 
 
1523
      && linelen >= 15
 
1524
      && !strncmp (line, "GETEVENTCOUNTER", 15)
 
1525
      && (linelen == 15 || spacep (line+15)))
 
1526
    {
 
1527
      ctrl->server_local->pause_io_logging = 1;
 
1528
    }
 
1529
 
 
1530
  return ctrl->server_local->pause_io_logging? 1:0;
 
1531
}
 
1532
 
 
1533
 
965
1534
/* Tell the assuan library about our commands */
966
1535
static int
967
 
register_commands (ASSUAN_CONTEXT ctx)
 
1536
register_commands (assuan_context_t ctx)
968
1537
{
969
1538
  static struct {
970
1539
    const char *name;
971
 
    int (*handler)(ASSUAN_CONTEXT, char *line);
 
1540
    int (*handler)(assuan_context_t, char *line);
972
1541
  } table[] = {
 
1542
    { "GETEVENTCOUNTER",cmd_geteventcounter },
973
1543
    { "ISTRUSTED",      cmd_istrusted },
974
1544
    { "HAVEKEY",        cmd_havekey },
975
1545
    { "SIGKEY",         cmd_sigkey },
991
1561
    { "INPUT",          NULL }, 
992
1562
    { "OUTPUT",         NULL }, 
993
1563
    { "SCD",            cmd_scd },
 
1564
    { "GETVAL",         cmd_getval },
 
1565
    { "PUTVAL",         cmd_putval },
994
1566
    { "UPDATESTARTUPTTY",  cmd_updatestartuptty },
 
1567
#ifdef HAVE_W32_SYSTEM
 
1568
    { "KILLAGENT",      cmd_killagent },
 
1569
    { "RELOADAGENT",    cmd_reloadagent },
 
1570
#endif
 
1571
    { "GETINFO",        cmd_getinfo },
995
1572
    { NULL }
996
1573
  };
997
1574
  int i, rc;
1002
1579
      if (rc)
1003
1580
        return rc;
1004
1581
    } 
 
1582
#ifdef HAVE_ASSUAN_SET_IO_MONITOR
 
1583
  assuan_register_post_cmd_notify (ctx, post_cmd_notify);
 
1584
#endif
1005
1585
  assuan_register_reset_notify (ctx, reset_notify);
1006
1586
  assuan_register_option_handler (ctx, option_handler);
1007
1587
  return 0;
1008
1588
}
1009
1589
 
1010
1590
 
1011
 
/* Startup the server.  If LISTEN_FD and FD is given as -1, this is a simple
1012
 
   piper server, otherwise it is a regular server */
 
1591
/* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
 
1592
   simple piper server, otherwise it is a regular server.  CTRL is the
 
1593
   control structure for this connection; it has only the basic
 
1594
   intialization. */
1013
1595
void
1014
 
start_command_handler (int listen_fd, int fd)
 
1596
start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
1015
1597
{
1016
1598
  int rc;
1017
 
  ASSUAN_CONTEXT ctx;
1018
 
  struct server_control_s ctrl;
 
1599
  assuan_context_t ctx;
1019
1600
 
1020
 
  memset (&ctrl, 0, sizeof ctrl);
1021
 
  agent_init_default_ctrl (&ctrl);
1022
 
  
1023
 
  if (listen_fd == -1 && fd == -1)
 
1601
  if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
1024
1602
    {
1025
1603
      int filedes[2];
1026
1604
 
1028
1606
      filedes[1] = 1;
1029
1607
      rc = assuan_init_pipe_server (&ctx, filedes);
1030
1608
    }
1031
 
  else if (listen_fd != -1)
 
1609
  else if (listen_fd != GNUPG_INVALID_FD)
1032
1610
    {
1033
 
      rc = assuan_init_socket_server (&ctx, listen_fd);
 
1611
      rc = assuan_init_socket_server_ext (&ctx, listen_fd, 0);
1034
1612
    }
1035
1613
  else 
1036
1614
    {
1037
 
      rc = assuan_init_connected_socket_server (&ctx, fd);
1038
 
      ctrl.connection_fd = fd;
 
1615
      rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1039
1616
    }
1040
1617
  if (rc)
1041
1618
    {
1042
1619
      log_error ("failed to initialize the server: %s\n",
1043
 
                 assuan_strerror(rc));
 
1620
                 gpg_strerror(rc));
1044
1621
      agent_exit (2);
1045
1622
    }
1046
1623
  rc = register_commands (ctx);
1047
1624
  if (rc)
1048
1625
    {
1049
1626
      log_error ("failed to register commands with Assuan: %s\n",
1050
 
                 assuan_strerror(rc));
 
1627
                 gpg_strerror(rc));
1051
1628
      agent_exit (2);
1052
1629
    }
1053
1630
 
1054
 
  assuan_set_pointer (ctx, &ctrl);
1055
 
  ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
1056
 
  ctrl.server_local->assuan_ctx = ctx;
1057
 
  ctrl.server_local->message_fd = -1;
1058
 
  ctrl.server_local->use_cache_for_signing = 1;
1059
 
  ctrl.digest.raw_value = 0;
 
1631
  assuan_set_pointer (ctx, ctrl);
 
1632
  ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
 
1633
  ctrl->server_local->assuan_ctx = ctx;
 
1634
  ctrl->server_local->message_fd = -1;
 
1635
  ctrl->server_local->use_cache_for_signing = 1;
 
1636
  ctrl->digest.raw_value = 0;
1060
1637
 
1061
1638
  if (DBG_ASSUAN)
1062
1639
    assuan_set_log_stream (ctx, log_get_stream ());
1063
1640
 
 
1641
#ifdef HAVE_ASSUAN_SET_IO_MONITOR
 
1642
  assuan_set_io_monitor (ctx, io_monitor);
 
1643
#endif
 
1644
 
1064
1645
  for (;;)
1065
1646
    {
1066
1647
      rc = assuan_accept (ctx);
1070
1651
        }
1071
1652
      else if (rc)
1072
1653
        {
1073
 
          log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
 
1654
          log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1074
1655
          break;
1075
1656
        }
1076
1657
      
1077
1658
      rc = assuan_process (ctx);
1078
1659
      if (rc)
1079
1660
        {
1080
 
          log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
 
1661
          log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1081
1662
          continue;
1082
1663
        }
1083
1664
    }
1084
1665
 
1085
1666
  /* Reset the SCD if needed. */
1086
 
  agent_reset_scd (&ctrl);
 
1667
  agent_reset_scd (ctrl);
1087
1668
 
1088
1669
  /* Reset the pinentry (in case of popup messages). */
1089
 
  agent_reset_query (&ctrl);
 
1670
  agent_reset_query (ctrl);
1090
1671
 
 
1672
  /* Cleanup.  */
1091
1673
  assuan_deinit_server (ctx);
1092
 
  if (ctrl.display)
1093
 
    free (ctrl.display);
1094
 
  if (ctrl.ttyname)
1095
 
    free (ctrl.ttyname);
1096
 
  if (ctrl.ttytype)
1097
 
    free (ctrl.ttytype);
1098
 
  if (ctrl.lc_ctype)
1099
 
    free (ctrl.lc_ctype);
1100
 
  if (ctrl.lc_messages)
1101
 
    free (ctrl.lc_messages);
1102
 
  xfree (ctrl.server_local);
 
1674
#ifdef HAVE_W32_SYSTEM
 
1675
  if (ctrl->server_local->stopme)
 
1676
    agent_exit (0);
 
1677
#endif
 
1678
  xfree (ctrl->server_local);
 
1679
  ctrl->server_local = NULL;
1103
1680
}
1104
1681