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

« back to all changes in this revision

Viewing changes to sm/server.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
/* server.c - Server mode and main entry point 
2
 
 * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
 
3
 *               2007, 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
#include <config.h>
30
30
#include <assuan.h>
31
31
 
32
32
#include "gpgsm.h"
 
33
#include "sysutils.h"
33
34
 
34
 
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
 
35
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
35
36
 
36
37
 
37
38
/* The filepointer for status message used in non-server mode */
43
44
  int message_fd;
44
45
  int list_internal;
45
46
  int list_external;
 
47
  int list_to_output;           /* Write keylistings to the output fd. */
 
48
  int enable_audit_log;         /* Use an audit log.  */
46
49
  certlist_t recplist;
47
50
  certlist_t signerlist;
48
51
  certlist_t default_recplist; /* As set by main() - don't release. */
 
52
  int allow_pinentry_notify;   /* Set if pinentry notifications should
 
53
                                  be passed back to the client. */
49
54
};
50
55
 
51
56
 
52
 
 
 
57
/* Cookie definition for assuan data line output.  */
 
58
static ssize_t data_line_cookie_write (void *cookie,
 
59
                                       const void *buffer, size_t size);
 
60
static int data_line_cookie_close (void *cookie);
 
61
static es_cookie_io_functions_t data_line_cookie_functions =
 
62
  {
 
63
    NULL,
 
64
    data_line_cookie_write,
 
65
    NULL,
 
66
    data_line_cookie_close
 
67
  };
 
68
 
 
69
 
 
70
 
 
71
 
53
72
/* Note that it is sufficient to allocate the target string D as
54
73
   long as the source string S, i.e.: strlen(s)+1; */
55
74
static void
72
91
}
73
92
 
74
93
 
 
94
/* Skip over options.  
 
95
   Blanks after the options are also removed. */
 
96
static char *
 
97
skip_options (const char *line)
 
98
{
 
99
  while (spacep (line))
 
100
    line++;
 
101
  while ( *line == '-' && line[1] == '-' )
 
102
    {
 
103
      while (*line && !spacep (line))
 
104
        line++;
 
105
      while (spacep (line))
 
106
        line++;
 
107
    }
 
108
  return (char*)line;
 
109
}
75
110
 
76
111
 
77
112
/* Check whether the option NAME appears in LINE */
82
117
  int n = strlen (name);
83
118
 
84
119
  s = strstr (line, name);
 
120
  if (s && s >= skip_options (line))
 
121
    return 0;
85
122
  return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
86
123
}
87
124
 
88
125
 
 
126
/* A write handler used by es_fopencookie to write assuan data
 
127
   lines.  */
 
128
static ssize_t
 
129
data_line_cookie_write (void *cookie, const void *buffer, size_t size)
 
130
{
 
131
  assuan_context_t ctx = cookie;
 
132
 
 
133
  if (assuan_send_data (ctx, buffer, size))
 
134
    {
 
135
      errno = EIO;
 
136
      return -1;
 
137
    }
 
138
 
 
139
  return size;
 
140
}
 
141
 
 
142
static int
 
143
data_line_cookie_close (void *cookie)
 
144
{
 
145
  assuan_context_t ctx = cookie;
 
146
 
 
147
  if (assuan_send_data (ctx, NULL, 0))
 
148
    {
 
149
      errno = EIO;
 
150
      return -1;
 
151
    }
 
152
 
 
153
  return 0;
 
154
}
 
155
 
 
156
 
89
157
static void 
90
 
close_message_fd (CTRL ctrl)
 
158
close_message_fd (ctrl_t ctrl)
91
159
{
92
160
  if (ctrl->server_local->message_fd != -1)
93
161
    {
97
165
}
98
166
 
99
167
 
 
168
/* Start a new audit session if this has been enabled.  */
 
169
static gpg_error_t
 
170
start_audit_session (ctrl_t ctrl)
 
171
{
 
172
  audit_release (ctrl->audit);
 
173
  ctrl->audit = NULL;
 
174
  if (ctrl->server_local->enable_audit_log && !(ctrl->audit = audit_new ()) )
 
175
    return gpg_error_from_syserror ();
 
176
  
 
177
  return 0;
 
178
}
 
179
 
 
180
 
100
181
static int
101
 
option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
 
182
option_handler (assuan_context_t ctx, const char *key, const char *value)
102
183
{
103
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
184
  ctrl_t ctrl = assuan_get_pointer (ctx);
104
185
 
105
186
  if (!strcmp (key, "include-certs"))
106
187
    {
107
188
      int i = *value? atoi (value) : -1;
108
189
      if (ctrl->include_certs < -2)
109
 
        return ASSUAN_Parameter_Error;
 
190
        return gpg_error (GPG_ERR_ASS_PARAMETER);
110
191
      ctrl->include_certs = i;
111
192
    }
112
 
  else   if (!strcmp (key, "display"))
 
193
  else if (!strcmp (key, "display"))
113
194
    {
114
195
      if (opt.display)
115
196
        free (opt.display);
116
197
      opt.display = strdup (value);
117
198
      if (!opt.display)
118
 
        return ASSUAN_Out_Of_Core;
 
199
        return out_of_core ();
119
200
    }
120
201
  else if (!strcmp (key, "ttyname"))
121
202
    {
123
204
        free (opt.ttyname);
124
205
      opt.ttyname = strdup (value);
125
206
      if (!opt.ttyname)
126
 
        return ASSUAN_Out_Of_Core;
 
207
        return out_of_core ();
127
208
    }
128
209
  else if (!strcmp (key, "ttytype"))
129
210
    {
131
212
        free (opt.ttytype);
132
213
      opt.ttytype = strdup (value);
133
214
      if (!opt.ttytype)
134
 
        return ASSUAN_Out_Of_Core;
 
215
        return out_of_core ();
135
216
    }
136
217
  else if (!strcmp (key, "lc-ctype"))
137
218
    {
139
220
        free (opt.lc_ctype);
140
221
      opt.lc_ctype = strdup (value);
141
222
      if (!opt.lc_ctype)
142
 
        return ASSUAN_Out_Of_Core;
 
223
        return out_of_core ();
143
224
    }
144
225
  else if (!strcmp (key, "lc-messages"))
145
226
    {
147
228
        free (opt.lc_messages);
148
229
      opt.lc_messages = strdup (value);
149
230
      if (!opt.lc_messages)
150
 
        return ASSUAN_Out_Of_Core;
 
231
        return out_of_core ();
 
232
    }
 
233
  else if (!strcmp (key, "xauthority"))
 
234
    {
 
235
      if (opt.xauthority)
 
236
        free (opt.xauthority);
 
237
      opt.xauthority = strdup (value);
 
238
      if (!opt.xauthority)
 
239
        return out_of_core ();
 
240
    }
 
241
  else if (!strcmp (key, "pinentry-user-data"))
 
242
    {
 
243
      if (opt.pinentry_user_data)
 
244
        free (opt.pinentry_user_data);
 
245
      opt.pinentry_user_data = strdup (value);
 
246
      if (!opt.pinentry_user_data)
 
247
        return out_of_core ();
151
248
    }
152
249
  else if (!strcmp (key, "list-mode"))
153
250
    {
168
265
          ctrl->server_local->list_external = 1;
169
266
        }
170
267
      else
171
 
        return ASSUAN_Parameter_Error;
 
268
        return gpg_error (GPG_ERR_ASS_PARAMETER);
 
269
    }
 
270
  else if (!strcmp (key, "list-to-output"))
 
271
    {
 
272
      int i = *value? atoi (value) : 0;
 
273
      ctrl->server_local->list_to_output = i;
172
274
    }
173
275
  else if (!strcmp (key, "with-validation"))
174
276
    {
175
277
      int i = *value? atoi (value) : 0;
176
278
      ctrl->with_validation = i;
177
279
    }
 
280
  else if (!strcmp (key, "validation-model"))
 
281
    {
 
282
      int i = gpgsm_parse_validation_model (value);
 
283
      if ( i >= 0 && i <= 1 )
 
284
        ctrl->validation_model = i;
 
285
      else
 
286
        return gpg_error (GPG_ERR_ASS_PARAMETER);
 
287
    }
 
288
  else if (!strcmp (key, "with-key-data"))
 
289
    {
 
290
      opt.with_key_data = 1;
 
291
    }
 
292
  else if (!strcmp (key, "enable-audit-log"))
 
293
    {
 
294
      int i = *value? atoi (value) : 0;
 
295
      ctrl->server_local->enable_audit_log = i;
 
296
    }
 
297
  else if (!strcmp (key, "allow-pinentry-notify"))
 
298
    ctrl->server_local->allow_pinentry_notify = 1;
178
299
  else
179
 
    return ASSUAN_Invalid_Option;
 
300
    return gpg_error (GPG_ERR_UNKNOWN_OPTION);
180
301
 
181
302
  return 0;
182
303
}
183
304
 
184
305
 
185
 
 
186
 
 
187
306
static void
188
 
reset_notify (ASSUAN_CONTEXT ctx)
 
307
reset_notify (assuan_context_t ctx)
189
308
{
190
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
309
  ctrl_t ctrl = assuan_get_pointer (ctx);
191
310
 
192
311
  gpgsm_release_certlist (ctrl->server_local->recplist);
193
312
  gpgsm_release_certlist (ctrl->server_local->signerlist);
200
319
 
201
320
 
202
321
static void
203
 
input_notify (ASSUAN_CONTEXT ctx, const char *line)
 
322
input_notify (assuan_context_t ctx, const char *line)
204
323
{
205
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
324
  ctrl_t ctrl = assuan_get_pointer (ctx);
206
325
 
207
326
  ctrl->autodetect_encoding = 0;
208
327
  ctrl->is_pem = 0;
218
337
}
219
338
 
220
339
static void
221
 
output_notify (ASSUAN_CONTEXT ctx, const char *line)
 
340
output_notify (assuan_context_t ctx, const char *line)
222
341
{
223
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
342
  ctrl_t ctrl = assuan_get_pointer (ctx);
224
343
 
225
344
  ctrl->create_pem = 0;
226
345
  ctrl->create_base64 = 0;
244
363
  client has to take care of this.  All RECIPIENT commands are
245
364
  cumulative until a RESET or an successful ENCRYPT command.  */
246
365
static int 
247
 
cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
 
366
cmd_recipient (assuan_context_t ctx, char *line)
248
367
{
249
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
368
  ctrl_t ctrl = assuan_get_pointer (ctx);
250
369
  int rc;
251
370
 
252
 
  rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0);
 
371
  if (!ctrl->audit)
 
372
    rc = start_audit_session (ctrl);
 
373
  else
 
374
    rc = 0;
 
375
 
 
376
  if (!rc)
 
377
    rc = gpgsm_add_to_certlist (ctrl, line, 0,
 
378
                                &ctrl->server_local->recplist, 0);
253
379
  if (rc)
254
380
    {
255
381
      gpg_err_code_t r = gpg_err_code (rc);
263
389
                   r == GPG_ERR_NO_CRL_KNOWN?    "6":
264
390
                   r == GPG_ERR_CRL_TOO_OLD?     "7":
265
391
                   r == GPG_ERR_NO_POLICY_MATCH? "8":
 
392
                   r == GPG_ERR_MISSING_CERT?   "11":
266
393
                   "0",
267
394
                   line, NULL);
268
395
    }
269
396
 
270
 
  return map_to_assuan_status (rc);
 
397
  return rc;
271
398
}
272
399
 
273
400
/*  SIGNER <userID>
287
414
  Note that this command returns an INV_RECP status which is a bit
288
415
  strange, but they are very similar.  */
289
416
static int 
290
 
cmd_signer (ASSUAN_CONTEXT ctx, char *line)
 
417
cmd_signer (assuan_context_t ctx, char *line)
291
418
{
292
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
419
  ctrl_t ctrl = assuan_get_pointer (ctx);
293
420
  int rc;
294
421
 
295
422
  rc = gpgsm_add_to_certlist (ctrl, line, 1,
308
435
                   r == GPG_ERR_CRL_TOO_OLD?         "7":
309
436
                   r == GPG_ERR_NO_POLICY_MATCH?     "8":
310
437
                   r == GPG_ERR_NO_SECKEY?           "9":
 
438
                   r == GPG_ERR_MISSING_CERT?       "11":
311
439
                   "0",
312
440
                  line, NULL);
313
441
    }
314
 
  return map_to_assuan_status (rc);
 
442
  return rc;
315
443
}
316
444
 
317
445
 
329
457
  have been done while setting the recipients.  The input and output
330
458
  pipes are closed. */
331
459
static int 
332
 
cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
 
460
cmd_encrypt (assuan_context_t ctx, char *line)
333
461
{
334
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
462
  ctrl_t ctrl = assuan_get_pointer (ctx);
335
463
  certlist_t cl;
336
464
  int inp_fd, out_fd;
337
465
  FILE *out_fp;
338
466
  int rc;
339
467
 
340
 
  inp_fd = assuan_get_input_fd (ctx);
 
468
  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
341
469
  if (inp_fd == -1)
342
 
    return set_error (No_Input, NULL);
343
 
  out_fd = assuan_get_output_fd (ctx);
 
470
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
 
471
  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
344
472
  if (out_fd == -1)
345
 
    return set_error (No_Output, NULL);
 
473
    return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
346
474
 
347
 
  out_fp = fdopen ( dup(out_fd), "w");
 
475
  out_fp = fdopen (dup (out_fd), "w");
348
476
  if (!out_fp)
349
 
    return set_error (General_Error, "fdopen() failed");
 
477
    return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
350
478
  
351
479
  /* Now add all encrypt-to marked recipients from the default
352
480
     list. */
359
487
                                           &ctrl->server_local->recplist, 1);
360
488
    }
361
489
  if (!rc)
 
490
    rc = ctrl->audit? 0 : start_audit_session (ctrl);
 
491
  if (!rc)
362
492
    rc = gpgsm_encrypt (assuan_get_pointer (ctx),
363
493
                        ctrl->server_local->recplist,
364
494
                        inp_fd, out_fp);
370
500
  close_message_fd (ctrl);
371
501
  assuan_close_input_fd (ctx);
372
502
  assuan_close_output_fd (ctx);
373
 
  return map_to_assuan_status (rc);
 
503
  return rc;
374
504
}
375
505
 
 
506
 
376
507
/* DECRYPT
377
508
 
378
509
  This performs the decrypt operation after doing some check on the
381
512
  no need to ask the client for a protecting passphrase - GpgAgent
382
513
  does take care of this by requesting this from the user. */
383
514
static int 
384
 
cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
 
515
cmd_decrypt (assuan_context_t ctx, char *line)
385
516
{
386
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
517
  ctrl_t ctrl = assuan_get_pointer (ctx);
387
518
  int inp_fd, out_fd;
388
519
  FILE *out_fp;
389
520
  int rc;
390
521
 
391
 
  inp_fd = assuan_get_input_fd (ctx);
 
522
  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
392
523
  if (inp_fd == -1)
393
 
    return set_error (No_Input, NULL);
394
 
  out_fd = assuan_get_output_fd (ctx);
 
524
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
 
525
  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
395
526
  if (out_fd == -1)
396
 
    return set_error (No_Output, NULL);
 
527
    return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
397
528
 
398
 
  out_fp = fdopen ( dup(out_fd), "w");
 
529
  out_fp = fdopen (dup(out_fd), "w");
399
530
  if (!out_fp)
400
 
    return set_error (General_Error, "fdopen() failed");
401
 
  rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); 
 
531
    return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
 
532
 
 
533
  rc = start_audit_session (ctrl);
 
534
  if (!rc)
 
535
    rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); 
402
536
  fclose (out_fp);
403
537
 
404
538
  /* close and reset the fd */
406
540
  assuan_close_input_fd (ctx);
407
541
  assuan_close_output_fd (ctx);
408
542
 
409
 
  return map_to_assuan_status (rc);
 
543
  return rc;
410
544
}
411
545
 
412
546
 
420
554
  the signed material and the client must provide it.
421
555
  */
422
556
static int 
423
 
cmd_verify (ASSUAN_CONTEXT ctx, char *line)
 
557
cmd_verify (assuan_context_t ctx, char *line)
424
558
{
425
559
  int rc;
426
 
  CTRL ctrl = assuan_get_pointer (ctx);
427
 
  int fd = assuan_get_input_fd (ctx);
428
 
  int out_fd = assuan_get_output_fd (ctx);
 
560
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
561
  int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
 
562
  int out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
429
563
  FILE *out_fp = NULL;
430
564
 
431
565
  if (fd == -1)
432
 
    return set_error (No_Input, NULL);
 
566
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
433
567
 
434
568
  if (out_fd != -1)
435
569
    {
436
570
      out_fp = fdopen ( dup(out_fd), "w");
437
571
      if (!out_fp)
438
 
        return set_error (General_Error, "fdopen() failed");
 
572
        return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
439
573
    }
440
574
 
441
 
  rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
442
 
                     ctrl->server_local->message_fd, out_fp);
 
575
  rc = start_audit_session (ctrl);
 
576
  if (!rc)
 
577
    rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
 
578
                       ctrl->server_local->message_fd, out_fp);
443
579
  if (out_fp)
444
580
    fclose (out_fp);
445
581
 
448
584
  assuan_close_input_fd (ctx);
449
585
  assuan_close_output_fd (ctx);
450
586
 
451
 
  return map_to_assuan_status (rc);
 
587
  return rc;
452
588
}
453
589
 
454
590
 
458
594
  set by OUTPUT.  With "--detached" specified, a detached signature is
459
595
  created (surprise).  */
460
596
static int 
461
 
cmd_sign (ASSUAN_CONTEXT ctx, char *line)
 
597
cmd_sign (assuan_context_t ctx, char *line)
462
598
{
463
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
599
  ctrl_t ctrl = assuan_get_pointer (ctx);
464
600
  int inp_fd, out_fd;
465
601
  FILE *out_fp;
466
602
  int detached;
467
603
  int rc;
468
604
 
469
 
  inp_fd = assuan_get_input_fd (ctx);
 
605
  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
470
606
  if (inp_fd == -1)
471
 
    return set_error (No_Input, NULL);
472
 
  out_fd = assuan_get_output_fd (ctx);
 
607
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
 
608
  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
473
609
  if (out_fd == -1)
474
 
    return set_error (No_Output, NULL);
 
610
    return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
475
611
 
476
612
  detached = has_option (line, "--detached"); 
477
613
 
478
614
  out_fp = fdopen ( dup(out_fd), "w");
479
615
  if (!out_fp)
480
 
    return set_error (General_Error, "fdopen() failed");
 
616
    return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
481
617
 
482
 
  rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
483
 
                   inp_fd, detached, out_fp);
 
618
  rc = start_audit_session (ctrl);
 
619
  if (!rc)
 
620
    rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
 
621
                     inp_fd, detached, out_fp);
484
622
  fclose (out_fp);
485
623
 
486
624
  /* close and reset the fd */
488
626
  assuan_close_input_fd (ctx);
489
627
  assuan_close_output_fd (ctx);
490
628
 
491
 
  return map_to_assuan_status (rc);
 
629
  return rc;
492
630
}
493
631
 
494
632
 
499
637
  the certificate but not of the entire chain.  It is possible to
500
638
  import expired certificates.  */
501
639
static int 
502
 
cmd_import (ASSUAN_CONTEXT ctx, char *line)
 
640
cmd_import (assuan_context_t ctx, char *line)
503
641
{
504
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
642
  ctrl_t ctrl = assuan_get_pointer (ctx);
505
643
  int rc;
506
 
  int fd = assuan_get_input_fd (ctx);
 
644
  int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
507
645
 
508
646
  if (fd == -1)
509
 
    return set_error (No_Input, NULL);
 
647
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
510
648
 
511
649
  rc = gpgsm_import (assuan_get_pointer (ctx), fd);
512
650
 
515
653
  assuan_close_input_fd (ctx);
516
654
  assuan_close_output_fd (ctx);
517
655
 
518
 
  return map_to_assuan_status (rc);
 
656
  return rc;
519
657
}
520
658
 
521
659
 
 
660
/* EXPORT [--data [--armor|--base64]] [--] pattern
 
661
 
 
662
 */
 
663
 
522
664
static int 
523
 
cmd_export (ASSUAN_CONTEXT ctx, char *line)
 
665
cmd_export (assuan_context_t ctx, char *line)
524
666
{
525
 
  CTRL ctrl = assuan_get_pointer (ctx);
526
 
  int fd = assuan_get_output_fd (ctx);
527
 
  FILE *out_fp;
 
667
  ctrl_t ctrl = assuan_get_pointer (ctx);
528
668
  char *p;
529
 
  STRLIST list, sl;
530
 
 
531
 
  if (fd == -1)
532
 
    return set_error (No_Output, NULL);
 
669
  strlist_t list, sl;
 
670
  int use_data;
533
671
  
534
 
  /* break the line down into an STRLIST */
 
672
  use_data = has_option (line, "--data");
 
673
 
 
674
  if (use_data)
 
675
    {
 
676
      /* We need to override any possible setting done by an OUTPUT command. */
 
677
      ctrl->create_pem = has_option (line, "--armor");
 
678
      ctrl->create_base64 = has_option (line, "--base64");
 
679
    }
 
680
 
 
681
  line = skip_options (line);
 
682
 
 
683
  /* Break the line down into an strlist_t. */
535
684
  list = NULL;
536
685
  for (p=line; *p; line = p)
537
686
    {
545
694
          if (!sl)
546
695
            {
547
696
              free_strlist (list);
548
 
              return ASSUAN_Out_Of_Core;
 
697
              return out_of_core ();
549
698
            }
550
699
          sl->flags = 0;
551
700
          strcpy_escaped_plus (sl->d, line);
554
703
        }
555
704
    }
556
705
 
557
 
  out_fp = fdopen ( dup(fd), "w");
558
 
  if (!out_fp)
559
 
    {
560
 
      free_strlist (list);
561
 
      return set_error (General_Error, "fdopen() failed");
562
 
    }
563
 
 
564
 
  gpgsm_export (ctrl, list, out_fp);
565
 
  fclose (out_fp);
 
706
  if (use_data)
 
707
    {
 
708
      estream_t stream;
 
709
 
 
710
      stream = es_fopencookie (ctx, "w", data_line_cookie_functions);
 
711
      if (!stream)
 
712
        {
 
713
          free_strlist (list);
 
714
          return set_error (GPG_ERR_ASS_GENERAL, 
 
715
                            "error setting up a data stream");
 
716
        }
 
717
      gpgsm_export (ctrl, list, NULL, stream);
 
718
      es_fclose (stream);
 
719
    }
 
720
  else
 
721
    {
 
722
      int fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
 
723
      FILE *out_fp;
 
724
 
 
725
      if (fd == -1)
 
726
        {
 
727
          free_strlist (list);
 
728
          return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
729
        }
 
730
      out_fp = fdopen ( dup(fd), "w");
 
731
      if (!out_fp)
 
732
        {
 
733
          free_strlist (list);
 
734
          return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
 
735
        }
 
736
      
 
737
      gpgsm_export (ctrl, list, out_fp, NULL);
 
738
      fclose (out_fp);
 
739
    }
 
740
 
566
741
  free_strlist (list);
567
 
  /* close and reset the fd */
 
742
  /* Close and reset the fds. */
568
743
  close_message_fd (ctrl);
569
744
  assuan_close_input_fd (ctx);
570
745
  assuan_close_output_fd (ctx);
573
748
 
574
749
 
575
750
static int 
576
 
cmd_delkeys (ASSUAN_CONTEXT ctx, char *line)
 
751
cmd_delkeys (assuan_context_t ctx, char *line)
577
752
{
578
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
753
  ctrl_t ctrl = assuan_get_pointer (ctx);
579
754
  char *p;
580
 
  STRLIST list, sl;
 
755
  strlist_t list, sl;
581
756
  int rc;
582
757
 
583
 
  /* break the line down into an STRLIST */
 
758
  /* break the line down into an strlist_t */
584
759
  list = NULL;
585
760
  for (p=line; *p; line = p)
586
761
    {
594
769
          if (!sl)
595
770
            {
596
771
              free_strlist (list);
597
 
              return ASSUAN_Out_Of_Core;
 
772
              return out_of_core ();
598
773
            }
599
774
          sl->flags = 0;
600
775
          strcpy_escaped_plus (sl->d, line);
611
786
  assuan_close_input_fd (ctx);
612
787
  assuan_close_output_fd (ctx);
613
788
 
614
 
  return map_to_assuan_status (rc);
 
789
  return rc;
615
790
}
616
791
 
617
792
 
621
796
   Set the file descriptor to read a message which is used with
622
797
   detached signatures */
623
798
static int 
624
 
cmd_message (ASSUAN_CONTEXT ctx, char *line)
 
799
cmd_message (assuan_context_t ctx, char *line)
625
800
{
626
 
  char *endp;
 
801
  int rc;
 
802
  gnupg_fd_t sysfd;
627
803
  int fd;
628
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
804
  ctrl_t ctrl = assuan_get_pointer (ctx);
629
805
 
630
 
  if (strncmp (line, "FD=", 3))
631
 
    return set_error (Syntax_Error, "FD=<n> expected");
632
 
  line += 3;
633
 
  if (!digitp (line))
634
 
    return set_error (Syntax_Error, "number required");
635
 
  fd = strtoul (line, &endp, 10);
636
 
  if (*endp)
637
 
    return set_error (Syntax_Error, "garbage found");
 
806
  rc = assuan_command_parse_fd (ctx, line, &sysfd);
 
807
  if (rc)
 
808
    return rc;
 
809
  fd = translate_sys2libc_fd (sysfd, 0);
638
810
  if (fd == -1)
639
 
    return set_error (No_Input, NULL);
640
 
 
 
811
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
641
812
  ctrl->server_local->message_fd = fd;
642
813
  return 0;
643
814
}
644
815
 
645
 
 
 
816
/* LISTKEYS [<patterns>]
 
817
   DUMPKEYS [<patterns>]
 
818
   LISTSECRETKEYS [<patterns>]
 
819
   DUMPSECRETKEYS [<patterns>]
 
820
*/
646
821
static int 
647
 
do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode)
 
822
do_listkeys (assuan_context_t ctx, char *line, int mode)
648
823
{
649
 
  CTRL ctrl = assuan_get_pointer (ctx);
650
 
  FILE *fp = assuan_get_data_fp (ctx);
 
824
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
825
  estream_t fp;
651
826
  char *p;
652
 
  STRLIST list, sl;
 
827
  strlist_t list, sl;
653
828
  unsigned int listmode;
654
829
  gpg_error_t err;
655
830
 
656
 
  if (!fp)
657
 
    return set_error (General_Error, "no data stream");
658
 
  
659
 
  /* break the line down into an STRLIST */
 
831
  /* Break the line down into an strlist. */
660
832
  list = NULL;
661
833
  for (p=line; *p; line = p)
662
834
    {
670
842
          if (!sl)
671
843
            {
672
844
              free_strlist (list);
673
 
              return ASSUAN_Out_Of_Core;
 
845
              return out_of_core ();
674
846
            }
675
847
          sl->flags = 0;
676
848
          strcpy_escaped_plus (sl->d, line);
679
851
        }
680
852
    }
681
853
 
 
854
  if (ctrl->server_local->list_to_output)
 
855
    {
 
856
      int outfd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
 
857
 
 
858
      if ( outfd == -1 )
 
859
        return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
860
      fp = es_fdopen ( dup (outfd), "w");
 
861
      if (!fp)
 
862
        return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen() failed");
 
863
    }
 
864
  else
 
865
    {
 
866
      fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
 
867
      if (!fp)
 
868
        return set_error (GPG_ERR_ASS_GENERAL, 
 
869
                          "error setting up a data stream");
 
870
    }
 
871
  
682
872
  ctrl->with_colons = 1;
683
873
  listmode = mode; 
684
874
  if (ctrl->server_local->list_internal)
687
877
    listmode |= (1<<7);
688
878
  err = gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode);
689
879
  free_strlist (list);
690
 
  return map_to_assuan_status (err);
 
880
  es_fclose (fp);
 
881
  if (ctrl->server_local->list_to_output)
 
882
    assuan_close_output_fd (ctx);
 
883
  return err;
691
884
}
692
885
 
693
886
static int 
694
 
cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
 
887
cmd_listkeys (assuan_context_t ctx, char *line)
695
888
{
696
889
  return do_listkeys (ctx, line, 3);
697
890
}
698
891
 
699
892
static int 
700
 
cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line)
 
893
cmd_dumpkeys (assuan_context_t ctx, char *line)
 
894
{
 
895
  return do_listkeys (ctx, line, 259);
 
896
}
 
897
 
 
898
static int 
 
899
cmd_listsecretkeys (assuan_context_t ctx, char *line)
701
900
{
702
901
  return do_listkeys (ctx, line, 2);
703
902
}
704
903
 
 
904
static int 
 
905
cmd_dumpsecretkeys (assuan_context_t ctx, char *line)
 
906
{
 
907
  return do_listkeys (ctx, line, 258);
 
908
}
 
909
 
705
910
 
706
911
/* GENKEY
707
912
 
709
914
   certificate request to the output.
710
915
 */
711
916
static int 
712
 
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
 
917
cmd_genkey (assuan_context_t ctx, char *line)
713
918
{
714
 
  CTRL ctrl = assuan_get_pointer (ctx);
 
919
  ctrl_t ctrl = assuan_get_pointer (ctx);
715
920
  int inp_fd, out_fd;
716
921
  FILE *out_fp;
717
922
  int rc;
 
923
  estream_t in_stream;
718
924
 
719
 
  inp_fd = assuan_get_input_fd (ctx);
 
925
  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
720
926
  if (inp_fd == -1)
721
 
    return set_error (No_Input, NULL);
722
 
  out_fd = assuan_get_output_fd (ctx);
 
927
    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
 
928
  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
723
929
  if (out_fd == -1)
724
 
    return set_error (No_Output, NULL);
 
930
    return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
931
 
 
932
  in_stream = es_fdopen_nc (inp_fd, "r");
 
933
  if (!in_stream)
 
934
    return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen failed");
725
935
 
726
936
  out_fp = fdopen ( dup(out_fd), "w");
727
937
  if (!out_fp)
728
 
    return set_error (General_Error, "fdopen() failed");
729
 
  rc = gpgsm_genkey (ctrl, inp_fd, out_fp);
 
938
    {
 
939
      es_fclose (in_stream);
 
940
      return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
 
941
    }
 
942
  rc = gpgsm_genkey (ctrl, in_stream, out_fp);
730
943
  fclose (out_fp);
731
944
 
732
945
  /* close and reset the fds */
733
946
  assuan_close_input_fd (ctx);
734
947
  assuan_close_output_fd (ctx);
735
948
 
736
 
  return map_to_assuan_status (rc);
737
 
}
738
 
 
739
 
 
 
949
  return rc;
 
950
}
 
951
 
 
952
 
 
953
 
 
954
/* GETAUDITLOG [--data] [--html]
 
955
 
 
956
   !!!WORK in PROGRESS!!!
 
957
 
 
958
   If --data is used, the output is send using D-lines and not to the
 
959
   source given by an OUTPUT command.
 
960
 
 
961
   If --html is used the output is formated as an XHTML block. This is
 
962
   designed to be incorporated into a HTML document.
 
963
 */
 
964
static int 
 
965
cmd_getauditlog (assuan_context_t ctx, char *line)
 
966
{
 
967
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
968
  int  out_fd;
 
969
  estream_t out_stream;
 
970
  int opt_data, opt_html;
 
971
  int rc;
 
972
 
 
973
  opt_data = has_option (line, "--data"); 
 
974
  opt_html = has_option (line, "--html"); 
 
975
  line = skip_options (line);
 
976
 
 
977
  if (!ctrl->audit)
 
978
    return gpg_error (GPG_ERR_NO_DATA);
 
979
 
 
980
  if (opt_data)
 
981
    {
 
982
      out_stream = es_fopencookie (ctx, "w", data_line_cookie_functions);
 
983
      if (!out_stream)
 
984
        return set_error (GPG_ERR_ASS_GENERAL, 
 
985
                          "error setting up a data stream");
 
986
    }
 
987
  else
 
988
    {
 
989
      out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
 
990
      if (out_fd == -1)
 
991
        return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
992
      
 
993
      out_stream = es_fdopen_nc ( dup (out_fd), "w");
 
994
      if (!out_stream)
 
995
        {
 
996
          return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen() failed");
 
997
        }
 
998
    }
 
999
 
 
1000
  audit_print_result (ctrl->audit, out_stream, opt_html);
 
1001
  rc = 0;
 
1002
 
 
1003
  es_fclose (out_stream);
 
1004
 
 
1005
  /* Close and reset the fd. */
 
1006
  if (!opt_data)
 
1007
    assuan_close_output_fd (ctx);
 
1008
  return rc;
 
1009
}
 
1010
 
 
1011
 
 
1012
/* GETINFO <what>
 
1013
 
 
1014
   Multipurpose function to return a variety of information.
 
1015
   Supported values for WHAT are:
 
1016
 
 
1017
     version     - Return the version of the program.
 
1018
     pid         - Return the process id of the server.
 
1019
 
 
1020
 */
 
1021
static int
 
1022
cmd_getinfo (assuan_context_t ctx, char *line)
 
1023
{
 
1024
  int rc;
 
1025
 
 
1026
  if (!strcmp (line, "version"))
 
1027
    {
 
1028
      const char *s = VERSION;
 
1029
      rc = assuan_send_data (ctx, s, strlen (s));
 
1030
    }
 
1031
  else if (!strcmp (line, "pid"))
 
1032
    {
 
1033
      char numbuf[50];
 
1034
 
 
1035
      snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
 
1036
      rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
 
1037
    }
 
1038
  else
 
1039
    rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
 
1040
  return rc;
 
1041
}
740
1042
 
741
1043
 
742
1044
 
743
1045
/* Tell the assuan library about our commands */
744
1046
static int
745
 
register_commands (ASSUAN_CONTEXT ctx)
 
1047
register_commands (assuan_context_t ctx)
746
1048
{
747
1049
  static struct {
748
1050
    const char *name;
749
 
    int (*handler)(ASSUAN_CONTEXT, char *line);
 
1051
    int (*handler)(assuan_context_t, char *line);
750
1052
  } table[] = {
751
1053
    { "RECIPIENT",     cmd_recipient },
752
1054
    { "SIGNER",        cmd_signer },
760
1062
    { "OUTPUT",        NULL }, 
761
1063
    { "MESSAGE",       cmd_message },
762
1064
    { "LISTKEYS",      cmd_listkeys },
 
1065
    { "DUMPKEYS",      cmd_dumpkeys },
763
1066
    { "LISTSECRETKEYS",cmd_listsecretkeys },
 
1067
    { "DUMPSECRETKEYS",cmd_dumpsecretkeys },
764
1068
    { "GENKEY",        cmd_genkey },
765
1069
    { "DELKEYS",       cmd_delkeys },
 
1070
    { "GETAUDITLOG",   cmd_getauditlog },
 
1071
    { "GETINFO",       cmd_getinfo },
766
1072
    { NULL }
767
1073
  };
768
1074
  int i, rc;
784
1090
{
785
1091
  int rc;
786
1092
  int filedes[2];
787
 
  ASSUAN_CONTEXT ctx;
 
1093
  assuan_context_t ctx;
788
1094
  struct server_control_s ctrl;
789
1095
  static const char hello[] = ("GNU Privacy Guard's S/M server "
790
1096
                               VERSION " ready");
792
1098
  memset (&ctrl, 0, sizeof ctrl);
793
1099
  gpgsm_init_default_ctrl (&ctrl);
794
1100
 
795
 
  /* For now we use a simple pipe based server so that we can work
796
 
     from scripts.  We will later add options to run as a daemon and
797
 
     wait for requests on a Unix domain socket */
 
1101
  /* We use a pipe based server so that we can work from scripts.
 
1102
     assuan_init_pipe_server will automagically detect when we are
 
1103
     called with a socketpair and ignore FIELDES in this case. */
798
1104
  filedes[0] = 0;
799
1105
  filedes[1] = 1;
800
1106
  rc = assuan_init_pipe_server (&ctx, filedes);
801
1107
  if (rc)
802
1108
    {
803
1109
      log_error ("failed to initialize the server: %s\n",
804
 
                 assuan_strerror(rc));
 
1110
                 gpg_strerror (rc));
805
1111
      gpgsm_exit (2);
806
1112
    }
807
1113
  rc = register_commands (ctx);
808
1114
  if (rc)
809
1115
    {
810
1116
      log_error ("failed to the register commands with Assuan: %s\n",
811
 
                 assuan_strerror(rc));
 
1117
                 gpg_strerror(rc));
812
1118
      gpgsm_exit (2);
813
1119
    }
814
1120
  if (opt.verbose || opt.debug)
861
1167
        }
862
1168
      else if (rc)
863
1169
        {
864
 
          log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
 
1170
          log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
865
1171
          break;
866
1172
        }
867
1173
      
868
1174
      rc = assuan_process (ctx);
869
1175
      if (rc)
870
1176
        {
871
 
          log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
 
1177
          log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
872
1178
          continue;
873
1179
        }
874
1180
    }
877
1183
  ctrl.server_local->recplist = NULL;
878
1184
  gpgsm_release_certlist (ctrl.server_local->signerlist);
879
1185
  ctrl.server_local->signerlist = NULL;
 
1186
  xfree (ctrl.server_local);
 
1187
 
 
1188
  audit_release (ctrl.audit);
 
1189
  ctrl.audit = NULL;
880
1190
 
881
1191
  assuan_deinit_server (ctx);
882
1192
}
883
1193
 
884
1194
 
885
 
static const char *
886
 
get_status_string ( int no ) 
887
 
{
888
 
  const char *s;
889
 
 
890
 
  switch (no)
891
 
    {
892
 
    case STATUS_ENTER  : s = "ENTER"; break;
893
 
    case STATUS_LEAVE  : s = "LEAVE"; break;
894
 
    case STATUS_ABORT  : s = "ABORT"; break;
895
 
    case STATUS_NEWSIG : s = "NEWSIG"; break;
896
 
    case STATUS_GOODSIG: s = "GOODSIG"; break;
897
 
    case STATUS_SIGEXPIRED: s = "SIGEXPIRED"; break;
898
 
    case STATUS_KEYREVOKED: s = "KEYREVOKED"; break;
899
 
    case STATUS_BADSIG : s = "BADSIG"; break;
900
 
    case STATUS_ERRSIG : s = "ERRSIG"; break;
901
 
    case STATUS_BADARMOR : s = "BADARMOR"; break;
902
 
    case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break;
903
 
    case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break;
904
 
    case STATUS_TRUST_NEVER      : s = "TRUST_NEVER"; break;
905
 
    case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break;
906
 
    case STATUS_TRUST_FULLY      : s = "TRUST_FULLY"; break;
907
 
    case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break;
908
 
    case STATUS_GET_BOOL         : s = "GET_BOOL"; break;
909
 
    case STATUS_GET_LINE         : s = "GET_LINE"; break;
910
 
    case STATUS_GET_HIDDEN       : s = "GET_HIDDEN"; break;
911
 
    case STATUS_GOT_IT   : s = "GOT_IT"; break;
912
 
    case STATUS_SHM_INFO         : s = "SHM_INFO"; break;
913
 
    case STATUS_SHM_GET  : s = "SHM_GET"; break;
914
 
    case STATUS_SHM_GET_BOOL     : s = "SHM_GET_BOOL"; break;
915
 
    case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break;
916
 
    case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break;
917
 
    case STATUS_VALIDSIG         : s = "VALIDSIG"; break;
918
 
    case STATUS_SIG_ID   : s = "SIG_ID"; break;
919
 
    case STATUS_ENC_TO   : s = "ENC_TO"; break;
920
 
    case STATUS_NODATA   : s = "NODATA"; break;
921
 
    case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break;
922
 
    case STATUS_NO_PUBKEY        : s = "NO_PUBKEY"; break;
923
 
    case STATUS_NO_SECKEY        : s = "NO_SECKEY"; break;
924
 
    case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break;
925
 
    case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break;
926
 
    case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break;
927
 
    case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break;
928
 
    case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break;
929
 
    case STATUS_GOODMDC  : s = "GOODMDC"; break;
930
 
    case STATUS_BADMDC   : s = "BADMDC"; break;
931
 
    case STATUS_ERRMDC   : s = "ERRMDC"; break;
932
 
    case STATUS_IMPORTED         : s = "IMPORTED"; break;
933
 
    case STATUS_IMPORT_OK        : s = "IMPORT_OK"; break;
934
 
    case STATUS_IMPORT_RES       : s = "IMPORT_RES"; break;
935
 
    case STATUS_FILE_START       : s = "FILE_START"; break;
936
 
    case STATUS_FILE_DONE        : s = "FILE_DONE"; break;
937
 
    case STATUS_FILE_ERROR       : s = "FILE_ERROR"; break;
938
 
    case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break;
939
 
    case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break;
940
 
    case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break;
941
 
    case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break;
942
 
    case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break;
943
 
    case STATUS_PROGRESS         : s = "PROGRESS"; break;
944
 
    case STATUS_SIG_CREATED      : s = "SIG_CREATED"; break;
945
 
    case STATUS_SESSION_KEY      : s = "SESSION_KEY"; break;
946
 
    case STATUS_NOTATION_NAME  : s = "NOTATION_NAME" ; break;
947
 
    case STATUS_NOTATION_DATA  : s = "NOTATION_DATA" ; break;
948
 
    case STATUS_POLICY_URL     : s = "POLICY_URL" ; break;
949
 
    case STATUS_BEGIN_STREAM   : s = "BEGIN_STREAM"; break;
950
 
    case STATUS_END_STREAM     : s = "END_STREAM"; break;
951
 
    case STATUS_KEY_CREATED    : s = "KEY_CREATED"; break;
952
 
    case STATUS_UNEXPECTED     : s = "UNEXPECTED"; break;
953
 
    case STATUS_INV_RECP       : s = "INV_RECP"; break;
954
 
    case STATUS_NO_RECP        : s = "NO_RECP"; break;
955
 
    case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
956
 
    case STATUS_EXPSIG         : s = "EXPSIG"; break;
957
 
    case STATUS_EXPKEYSIG      : s = "EXPKEYSIG"; break;
958
 
    case STATUS_TRUNCATED      : s = "TRUNCATED"; break;
959
 
    case STATUS_ERROR          : s = "ERROR"; break;
960
 
    case STATUS_IMPORT_PROBLEM : s = "IMPORT_PROBLEM"; break;
961
 
    default: s = "?"; break;
962
 
    }
963
 
  return s;
964
 
}
965
 
 
966
1195
 
967
1196
gpg_error_t
968
 
gpgsm_status2 (CTRL ctrl, int no, ...)
 
1197
gpgsm_status2 (ctrl_t ctrl, int no, ...)
969
1198
{
970
1199
  gpg_error_t err = 0;
971
1200
  va_list arg_ptr;
1014
1243
    }
1015
1244
  else 
1016
1245
    {
1017
 
      ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
 
1246
      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1018
1247
      char buf[950], *p;
1019
1248
      size_t n;
1020
1249
 
1031
1260
            *p++ = *text++;
1032
1261
        }
1033
1262
      *p = 0;
1034
 
      err = map_assuan_err (assuan_write_status (ctx,
1035
 
                                                 get_status_string (no), buf));
 
1263
      err = assuan_write_status (ctx, get_status_string (no), buf);
1036
1264
    }
1037
1265
 
1038
1266
  va_end (arg_ptr);
1040
1268
}
1041
1269
 
1042
1270
gpg_error_t
1043
 
gpgsm_status (CTRL ctrl, int no, const char *text)
 
1271
gpgsm_status (ctrl_t ctrl, int no, const char *text)
1044
1272
{
1045
1273
  return gpgsm_status2 (ctrl, no, text, NULL);
1046
1274
}
1047
1275
 
1048
1276
gpg_error_t
1049
 
gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
 
1277
gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
1050
1278
                            gpg_err_code_t ec)
1051
1279
{
1052
1280
  char buf[30];
1058
1286
    return gpgsm_status2 (ctrl, no, buf, NULL);
1059
1287
}
1060
1288
 
1061
 
#if 0
1062
 
/*
1063
 
 * Write a status line with a buffer using %XX escapes.  If WRAP is >
1064
 
 * 0 wrap the line after this length.  If STRING is not NULL it will
1065
 
 * be prepended to the buffer, no escaping is done for string.
1066
 
 * A wrap of -1 forces spaces not to be encoded as %20.
1067
 
 */
1068
 
void
1069
 
write_status_text_and_buffer ( int no, const char *string,
1070
 
                               const char *buffer, size_t len, int wrap )
 
1289
 
 
1290
/* Helper to notify the client about Pinentry events.  Because that
 
1291
   might disturb some older clients, this is only done when enabled
 
1292
   via an option.  Returns an gpg error code. */
 
1293
gpg_error_t
 
1294
gpgsm_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
1071
1295
{
1072
 
    const char *s, *text;
1073
 
    int esc, first;
1074
 
    int lower_limit = ' ';
1075
 
    size_t n, count, dowrap;
1076
 
 
1077
 
    if( !statusfp )
1078
 
        return;  /* not enabled */
1079
 
    
1080
 
    if (wrap == -1) {
1081
 
        lower_limit--;
1082
 
        wrap = 0;
1083
 
    }
1084
 
 
1085
 
    text = get_status_string (no);
1086
 
    count = dowrap = first = 1;
1087
 
    do {
1088
 
        if (dowrap) {
1089
 
            fprintf (statusfp, "[GNUPG:] %s ", text );
1090
 
            count = dowrap = 0;
1091
 
            if (first && string) {
1092
 
                fputs (string, statusfp);
1093
 
                count += strlen (string);
1094
 
            }
1095
 
            first = 0;
1096
 
        }
1097
 
        for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) {
1098
 
            if ( *s == '%' || *(const byte*)s <= lower_limit 
1099
 
                           || *(const byte*)s == 127 ) 
1100
 
                esc = 1;
1101
 
            if ( wrap && ++count > wrap ) {
1102
 
                dowrap=1;
1103
 
                break;
1104
 
            }
1105
 
        }
1106
 
        if (esc) {
1107
 
            s--; n++;
1108
 
        }
1109
 
        if (s != buffer) 
1110
 
            fwrite (buffer, s-buffer, 1, statusfp );
1111
 
        if ( esc ) {
1112
 
            fprintf (statusfp, "%%%02X", *(const unsigned char*)s );
1113
 
            s++; n--;
1114
 
        }
1115
 
        buffer = s;
1116
 
        len = n;
1117
 
        if ( dowrap && len )
1118
 
            putc ( '\n', statusfp );
1119
 
    } while ( len );
1120
 
 
1121
 
    putc ('\n',statusfp);
1122
 
    fflush (statusfp);
 
1296
  if (!ctrl || !ctrl->server_local 
 
1297
      || !ctrl->server_local->allow_pinentry_notify)
 
1298
    return 0;
 
1299
  return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
1123
1300
}
1124
 
#endif
 
1301
 
 
1302
 
 
1303