1 /* server.c - Server mode and main entry point
2 * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
33 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
36 /* The filepointer for status message used in non-server mode */
37 static FILE *statusfp
;
39 /* Data used to assuciate an Assuan context with local server data */
40 struct server_local_s
{
41 assuan_context_t assuan_ctx
;
45 int list_to_output
; /* Write keylistings to the output fd. */
47 certlist_t signerlist
;
48 certlist_t default_recplist
; /* As set by main() - don't release. */
52 /* Cookie definition for assuan data line output. */
53 static ssize_t
data_line_cookie_write (void *cookie
,
54 const void *buffer
, size_t size
);
55 static int data_line_cookie_close (void *cookie
);
56 static es_cookie_io_functions_t data_line_cookie_functions
=
59 data_line_cookie_write
,
61 data_line_cookie_close
67 /* Note that it is sufficient to allocate the target string D as
68 long as the source string S, i.e.: strlen(s)+1; */
70 strcpy_escaped_plus (char *d
, const char *s
)
74 if (*s
== '%' && s
[1] && s
[2])
90 Blanks after the options are also removed. */
92 skip_options (const char *line
)
96 while ( *line
== '-' && line
[1] == '-' )
98 while (*line
&& !spacep (line
))
100 while (spacep (line
))
107 /* Check whether the option NAME appears in LINE */
109 has_option (const char *line
, const char *name
)
112 int n
= strlen (name
);
114 s
= strstr (line
, name
);
115 if (s
&& s
>= skip_options (line
))
117 return (s
&& (s
== line
|| spacep (s
-1)) && (!s
[n
] || spacep (s
+n
)));
121 /* A write handler used by es_fopencookie to write assuan data
124 data_line_cookie_write (void *cookie
, const void *buffer
, size_t size
)
126 assuan_context_t ctx
= cookie
;
128 if (assuan_send_data (ctx
, buffer
, size
))
138 data_line_cookie_close (void *cookie
)
140 assuan_context_t ctx
= cookie
;
142 if (assuan_send_data (ctx
, NULL
, 0))
153 close_message_fd (ctrl_t ctrl
)
155 if (ctrl
->server_local
->message_fd
!= -1)
157 close (ctrl
->server_local
->message_fd
);
158 ctrl
->server_local
->message_fd
= -1;
164 option_handler (assuan_context_t ctx
, const char *key
, const char *value
)
166 ctrl_t ctrl
= assuan_get_pointer (ctx
);
168 if (!strcmp (key
, "include-certs"))
170 int i
= *value
? atoi (value
) : -1;
171 if (ctrl
->include_certs
< -2)
172 return gpg_error (GPG_ERR_ASS_PARAMETER
);
173 ctrl
->include_certs
= i
;
175 else if (!strcmp (key
, "display"))
179 opt
.display
= strdup (value
);
181 return out_of_core ();
183 else if (!strcmp (key
, "ttyname"))
187 opt
.ttyname
= strdup (value
);
189 return out_of_core ();
191 else if (!strcmp (key
, "ttytype"))
195 opt
.ttytype
= strdup (value
);
197 return out_of_core ();
199 else if (!strcmp (key
, "lc-ctype"))
203 opt
.lc_ctype
= strdup (value
);
205 return out_of_core ();
207 else if (!strcmp (key
, "lc-messages"))
210 free (opt
.lc_messages
);
211 opt
.lc_messages
= strdup (value
);
212 if (!opt
.lc_messages
)
213 return out_of_core ();
215 else if (!strcmp (key
, "list-mode"))
217 int i
= *value
? atoi (value
) : 0;
218 if (!i
|| i
== 1) /* default and mode 1 */
220 ctrl
->server_local
->list_internal
= 1;
221 ctrl
->server_local
->list_external
= 0;
225 ctrl
->server_local
->list_internal
= 0;
226 ctrl
->server_local
->list_external
= 1;
230 ctrl
->server_local
->list_internal
= 1;
231 ctrl
->server_local
->list_external
= 1;
234 return gpg_error (GPG_ERR_ASS_PARAMETER
);
236 else if (!strcmp (key
, "list-to-output"))
238 int i
= *value
? atoi (value
) : 0;
239 ctrl
->server_local
->list_to_output
= i
;
241 else if (!strcmp (key
, "with-validation"))
243 int i
= *value
? atoi (value
) : 0;
244 ctrl
->with_validation
= i
;
246 else if (!strcmp (key
, "with-key-data"))
248 opt
.with_key_data
= 1;
251 return gpg_error (GPG_ERR_UNKNOWN_OPTION
);
260 reset_notify (assuan_context_t ctx
)
262 ctrl_t ctrl
= assuan_get_pointer (ctx
);
264 gpgsm_release_certlist (ctrl
->server_local
->recplist
);
265 gpgsm_release_certlist (ctrl
->server_local
->signerlist
);
266 ctrl
->server_local
->recplist
= NULL
;
267 ctrl
->server_local
->signerlist
= NULL
;
268 close_message_fd (ctrl
);
269 assuan_close_input_fd (ctx
);
270 assuan_close_output_fd (ctx
);
275 input_notify (assuan_context_t ctx
, const char *line
)
277 ctrl_t ctrl
= assuan_get_pointer (ctx
);
279 ctrl
->autodetect_encoding
= 0;
282 if (strstr (line
, "--armor"))
284 else if (strstr (line
, "--base64"))
286 else if (strstr (line
, "--binary"))
289 ctrl
->autodetect_encoding
= 1;
293 output_notify (assuan_context_t ctx
, const char *line
)
295 ctrl_t ctrl
= assuan_get_pointer (ctx
);
297 ctrl
->create_pem
= 0;
298 ctrl
->create_base64
= 0;
299 if (strstr (line
, "--armor"))
300 ctrl
->create_pem
= 1;
301 else if (strstr (line
, "--base64"))
302 ctrl
->create_base64
= 1; /* just the raw output */
307 /* RECIPIENT <userID>
309 Set the recipient for the encryption. <userID> should be the
310 internal representation of the key; the server may accept any other
311 way of specification [we will support this]. If this is a valid and
312 trusted recipient the server does respond with OK, otherwise the
313 return is an ERR with the reason why the recipient can't be used,
314 the encryption will then not be done for this recipient. If the
315 policy is not to encrypt at all if not all recipients are valid, the
316 client has to take care of this. All RECIPIENT commands are
317 cumulative until a RESET or an successful ENCRYPT command. */
319 cmd_recipient (assuan_context_t ctx
, char *line
)
321 ctrl_t ctrl
= assuan_get_pointer (ctx
);
324 rc
= gpgsm_add_to_certlist (ctrl
, line
, 0, &ctrl
->server_local
->recplist
, 0);
327 gpg_err_code_t r
= gpg_err_code (rc
);
328 gpgsm_status2 (ctrl
, STATUS_INV_RECP
,
330 r
== GPG_ERR_NO_PUBKEY
? "1":
331 r
== GPG_ERR_AMBIGUOUS_NAME
? "2":
332 r
== GPG_ERR_WRONG_KEY_USAGE
? "3":
333 r
== GPG_ERR_CERT_REVOKED
? "4":
334 r
== GPG_ERR_CERT_EXPIRED
? "5":
335 r
== GPG_ERR_NO_CRL_KNOWN
? "6":
336 r
== GPG_ERR_CRL_TOO_OLD
? "7":
337 r
== GPG_ERR_NO_POLICY_MATCH
? "8":
347 Set the signer's keys for the signature creation. <userID> should
348 be the internal representation of the key; the server may accept any
349 other way of specification [we will support this]. If this is a
350 valid and usable signing key the server does respond with OK,
351 otherwise it returns an ERR with the reason why the key can't be
352 used, the signing will then not be done for this key. If the policy
353 is not to sign at all if not all signer keys are valid, the client
354 has to take care of this. All SIGNER commands are cumulative until
355 a RESET but they are *not* reset by an SIGN command becuase it can
356 be expected that set of signers are used for more than one sign
359 Note that this command returns an INV_RECP status which is a bit
360 strange, but they are very similar. */
362 cmd_signer (assuan_context_t ctx
, char *line
)
364 ctrl_t ctrl
= assuan_get_pointer (ctx
);
367 rc
= gpgsm_add_to_certlist (ctrl
, line
, 1,
368 &ctrl
->server_local
->signerlist
, 0);
371 gpg_err_code_t r
= gpg_err_code (rc
);
372 gpgsm_status2 (ctrl
, STATUS_INV_RECP
,
374 r
== GPG_ERR_NO_PUBKEY
? "1":
375 r
== GPG_ERR_AMBIGUOUS_NAME
? "2":
376 r
== GPG_ERR_WRONG_KEY_USAGE
? "3":
377 r
== GPG_ERR_CERT_REVOKED
? "4":
378 r
== GPG_ERR_CERT_EXPIRED
? "5":
379 r
== GPG_ERR_NO_CRL_KNOWN
? "6":
380 r
== GPG_ERR_CRL_TOO_OLD
? "7":
381 r
== GPG_ERR_NO_POLICY_MATCH
? "8":
382 r
== GPG_ERR_NO_SECKEY
? "9":
392 Do the actual encryption process. Takes the plaintext from the INPUT
393 command, writes to the ciphertext to the file descriptor set with
394 the OUTPUT command, take the recipients form all the recipients set
395 so far. If this command fails the clients should try to delete all
396 output currently done or otherwise mark it as invalid. GPGSM does
397 ensure that there won't be any security problem with leftover data
398 on the output in this case.
400 This command should in general not fail, as all necessary checks
401 have been done while setting the recipients. The input and output
404 cmd_encrypt (assuan_context_t ctx
, char *line
)
406 ctrl_t ctrl
= assuan_get_pointer (ctx
);
412 inp_fd
= assuan_get_input_fd (ctx
);
414 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
415 out_fd
= assuan_get_output_fd (ctx
);
417 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
419 out_fp
= fdopen ( dup(out_fd
), "w");
421 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
423 /* Now add all encrypt-to marked recipients from the default
426 if (!opt
.no_encrypt_to
)
428 for (cl
=ctrl
->server_local
->default_recplist
; !rc
&& cl
; cl
= cl
->next
)
429 if (cl
->is_encrypt_to
)
430 rc
= gpgsm_add_cert_to_certlist (ctrl
, cl
->cert
,
431 &ctrl
->server_local
->recplist
, 1);
434 rc
= gpgsm_encrypt (assuan_get_pointer (ctx
),
435 ctrl
->server_local
->recplist
,
439 gpgsm_release_certlist (ctrl
->server_local
->recplist
);
440 ctrl
->server_local
->recplist
= NULL
;
441 /* Close and reset the fd */
442 close_message_fd (ctrl
);
443 assuan_close_input_fd (ctx
);
444 assuan_close_output_fd (ctx
);
450 This performs the decrypt operation after doing some check on the
451 internal state. (e.g. that only needed data has been set). Because
452 it utilizes the GPG-Agent for the session key decryption, there is
453 no need to ask the client for a protecting passphrase - GpgAgent
454 does take care of this by requesting this from the user. */
456 cmd_decrypt (assuan_context_t ctx
, char *line
)
458 ctrl_t ctrl
= assuan_get_pointer (ctx
);
463 inp_fd
= assuan_get_input_fd (ctx
);
465 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
466 out_fd
= assuan_get_output_fd (ctx
);
468 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
470 out_fp
= fdopen ( dup(out_fd
), "w");
472 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
473 rc
= gpgsm_decrypt (ctrl
, inp_fd
, out_fp
);
476 /* close and reset the fd */
477 close_message_fd (ctrl
);
478 assuan_close_input_fd (ctx
);
479 assuan_close_output_fd (ctx
);
487 This does a verify operation on the message send to the input-FD.
488 The result is written out using status lines. If an output FD was
489 given, the signed text will be written to that.
491 If the signature is a detached one, the server will inquire about
492 the signed material and the client must provide it.
495 cmd_verify (assuan_context_t ctx
, char *line
)
498 ctrl_t ctrl
= assuan_get_pointer (ctx
);
499 int fd
= assuan_get_input_fd (ctx
);
500 int out_fd
= assuan_get_output_fd (ctx
);
504 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
508 out_fp
= fdopen ( dup(out_fd
), "w");
510 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
513 rc
= gpgsm_verify (assuan_get_pointer (ctx
), fd
,
514 ctrl
->server_local
->message_fd
, out_fp
);
518 /* close and reset the fd */
519 close_message_fd (ctrl
);
520 assuan_close_input_fd (ctx
);
521 assuan_close_output_fd (ctx
);
529 Sign the data set with the INPUT command and write it to the sink
530 set by OUTPUT. With "--detached" specified, a detached signature is
531 created (surprise). */
533 cmd_sign (assuan_context_t ctx
, char *line
)
535 ctrl_t ctrl
= assuan_get_pointer (ctx
);
541 inp_fd
= assuan_get_input_fd (ctx
);
543 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
544 out_fd
= assuan_get_output_fd (ctx
);
546 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
548 detached
= has_option (line
, "--detached");
550 out_fp
= fdopen ( dup(out_fd
), "w");
552 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
554 rc
= gpgsm_sign (assuan_get_pointer (ctx
), ctrl
->server_local
->signerlist
,
555 inp_fd
, detached
, out_fp
);
558 /* close and reset the fd */
559 close_message_fd (ctrl
);
560 assuan_close_input_fd (ctx
);
561 assuan_close_output_fd (ctx
);
569 Import the certificates read form the input-fd, return status
570 message for each imported one. The import checks the validity of
571 the certificate but not of the entire chain. It is possible to
572 import expired certificates. */
574 cmd_import (assuan_context_t ctx
, char *line
)
576 ctrl_t ctrl
= assuan_get_pointer (ctx
);
578 int fd
= assuan_get_input_fd (ctx
);
581 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
583 rc
= gpgsm_import (assuan_get_pointer (ctx
), fd
);
585 /* close and reset the fd */
586 close_message_fd (ctrl
);
587 assuan_close_input_fd (ctx
);
588 assuan_close_output_fd (ctx
);
594 /* EXPORT [--data [--armor|--base64]] [--] pattern
599 cmd_export (assuan_context_t ctx
, char *line
)
601 ctrl_t ctrl
= assuan_get_pointer (ctx
);
606 use_data
= has_option (line
, "--data");
610 /* We need to override any possible setting done by an OUTPUT command. */
611 ctrl
->create_pem
= has_option (line
, "--armor");
612 ctrl
->create_base64
= has_option (line
, "--base64");
615 line
= skip_options (line
);
617 /* Break the line down into an strlist_t. */
619 for (p
=line
; *p
; line
= p
)
621 while (*p
&& *p
!= ' ')
627 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
631 return out_of_core ();
634 strcpy_escaped_plus (sl
->d
, line
);
644 stream
= es_fopencookie (ctx
, "w", data_line_cookie_functions
);
648 return set_error (GPG_ERR_ASS_GENERAL
,
649 "error setting up a data stream");
651 gpgsm_export (ctrl
, list
, NULL
, stream
);
656 int fd
= assuan_get_output_fd (ctx
);
662 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
664 out_fp
= fdopen ( dup(fd
), "w");
668 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
671 gpgsm_export (ctrl
, list
, out_fp
, NULL
);
676 /* Close and reset the fds. */
677 close_message_fd (ctrl
);
678 assuan_close_input_fd (ctx
);
679 assuan_close_output_fd (ctx
);
685 cmd_delkeys (assuan_context_t ctx
, char *line
)
687 ctrl_t ctrl
= assuan_get_pointer (ctx
);
692 /* break the line down into an strlist_t */
694 for (p
=line
; *p
; line
= p
)
696 while (*p
&& *p
!= ' ')
702 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
706 return out_of_core ();
709 strcpy_escaped_plus (sl
->d
, line
);
715 rc
= gpgsm_delete (ctrl
, list
);
718 /* close and reset the fd */
719 close_message_fd (ctrl
);
720 assuan_close_input_fd (ctx
);
721 assuan_close_output_fd (ctx
);
730 Set the file descriptor to read a message which is used with
731 detached signatures */
733 cmd_message (assuan_context_t ctx
, char *line
)
737 ctrl_t ctrl
= assuan_get_pointer (ctx
);
739 rc
= assuan_command_parse_fd (ctx
, line
, &fd
);
743 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
744 ctrl
->server_local
->message_fd
= fd
;
748 /* LISTKEYS [<patterns>]
749 DUMPKEYS [<patterns>]
750 LISTSECRETKEYS [<patterns>]
751 DUMPSECRETKEYS [<patterns>]
754 do_listkeys (assuan_context_t ctx
, char *line
, int mode
)
756 ctrl_t ctrl
= assuan_get_pointer (ctx
);
760 unsigned int listmode
;
763 /* Break the line down into an strlist. */
765 for (p
=line
; *p
; line
= p
)
767 while (*p
&& *p
!= ' ')
773 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
777 return out_of_core ();
780 strcpy_escaped_plus (sl
->d
, line
);
786 if (ctrl
->server_local
->list_to_output
)
788 int outfd
= assuan_get_output_fd (ctx
);
791 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
792 fp
= es_fdopen ( dup (outfd
), "w");
794 return set_error (GPG_ERR_ASS_GENERAL
, "es_fdopen() failed");
798 fp
= es_fopencookie (ctx
, "w", data_line_cookie_functions
);
800 return set_error (GPG_ERR_ASS_GENERAL
,
801 "error setting up a data stream");
804 ctrl
->with_colons
= 1;
806 if (ctrl
->server_local
->list_internal
)
808 if (ctrl
->server_local
->list_external
)
810 err
= gpgsm_list_keys (assuan_get_pointer (ctx
), list
, fp
, listmode
);
813 if (ctrl
->server_local
->list_to_output
)
814 assuan_close_output_fd (ctx
);
819 cmd_listkeys (assuan_context_t ctx
, char *line
)
821 return do_listkeys (ctx
, line
, 3);
825 cmd_dumpkeys (assuan_context_t ctx
, char *line
)
827 return do_listkeys (ctx
, line
, 259);
831 cmd_listsecretkeys (assuan_context_t ctx
, char *line
)
833 return do_listkeys (ctx
, line
, 2);
837 cmd_dumpsecretkeys (assuan_context_t ctx
, char *line
)
839 return do_listkeys (ctx
, line
, 258);
845 Read the parameters in native format from the input fd and write a
846 certificate request to the output.
849 cmd_genkey (assuan_context_t ctx
, char *line
)
851 ctrl_t ctrl
= assuan_get_pointer (ctx
);
856 inp_fd
= assuan_get_input_fd (ctx
);
858 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
859 out_fd
= assuan_get_output_fd (ctx
);
861 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
863 out_fp
= fdopen ( dup(out_fd
), "w");
865 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
866 rc
= gpgsm_genkey (ctrl
, inp_fd
, NULL
, out_fp
);
869 /* close and reset the fds */
870 assuan_close_input_fd (ctx
);
871 assuan_close_output_fd (ctx
);
880 /* Tell the assuan library about our commands */
882 register_commands (assuan_context_t ctx
)
886 int (*handler
)(assuan_context_t
, char *line
);
888 { "RECIPIENT", cmd_recipient
},
889 { "SIGNER", cmd_signer
},
890 { "ENCRYPT", cmd_encrypt
},
891 { "DECRYPT", cmd_decrypt
},
892 { "VERIFY", cmd_verify
},
893 { "SIGN", cmd_sign
},
894 { "IMPORT", cmd_import
},
895 { "EXPORT", cmd_export
},
898 { "MESSAGE", cmd_message
},
899 { "LISTKEYS", cmd_listkeys
},
900 { "DUMPKEYS", cmd_dumpkeys
},
901 { "LISTSECRETKEYS",cmd_listsecretkeys
},
902 { "DUMPSECRETKEYS",cmd_dumpsecretkeys
},
903 { "GENKEY", cmd_genkey
},
904 { "DELKEYS", cmd_delkeys
},
909 for (i
=0; table
[i
].name
; i
++)
911 rc
= assuan_register_command (ctx
, table
[i
].name
, table
[i
].handler
);
918 /* Startup the server. DEFAULT_RECPLIST is the list of recipients as
919 set from the command line or config file. We only require those
920 marked as encrypt-to. */
922 gpgsm_server (certlist_t default_recplist
)
926 assuan_context_t ctx
;
927 struct server_control_s ctrl
;
928 static const char hello
[] = ("GNU Privacy Guard's S/M server "
931 memset (&ctrl
, 0, sizeof ctrl
);
932 gpgsm_init_default_ctrl (&ctrl
);
934 /* We use a pipe based server so that we can work from scripts.
935 assuan_init_pipe_server will automagically detect when we are
936 called with a socketpair and ignore FIELDES in this case. */
939 rc
= assuan_init_pipe_server (&ctx
, filedes
);
942 log_error ("failed to initialize the server: %s\n",
946 rc
= register_commands (ctx
);
949 log_error ("failed to the register commands with Assuan: %s\n",
953 if (opt
.verbose
|| opt
.debug
)
956 const char *s1
= getenv ("GPG_AGENT_INFO");
957 const char *s2
= getenv ("DIRMNGR_INFO");
971 assuan_set_hello_line (ctx
, tmp
);
976 assuan_set_hello_line (ctx
, hello
);
978 assuan_register_reset_notify (ctx
, reset_notify
);
979 assuan_register_input_notify (ctx
, input_notify
);
980 assuan_register_output_notify (ctx
, output_notify
);
981 assuan_register_option_handler (ctx
, option_handler
);
983 assuan_set_pointer (ctx
, &ctrl
);
984 ctrl
.server_local
= xcalloc (1, sizeof *ctrl
.server_local
);
985 ctrl
.server_local
->assuan_ctx
= ctx
;
986 ctrl
.server_local
->message_fd
= -1;
987 ctrl
.server_local
->list_internal
= 1;
988 ctrl
.server_local
->list_external
= 0;
989 ctrl
.server_local
->default_recplist
= default_recplist
;
992 assuan_set_log_stream (ctx
, log_get_stream ());
996 rc
= assuan_accept (ctx
);
1003 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc
));
1007 rc
= assuan_process (ctx
);
1010 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc
));
1015 gpgsm_release_certlist (ctrl
.server_local
->recplist
);
1016 ctrl
.server_local
->recplist
= NULL
;
1017 gpgsm_release_certlist (ctrl
.server_local
->signerlist
);
1018 ctrl
.server_local
->signerlist
= NULL
;
1019 xfree (ctrl
.server_local
);
1021 assuan_deinit_server (ctx
);
1026 get_status_string ( int no
)
1032 case STATUS_ENTER
: s
= "ENTER"; break;
1033 case STATUS_LEAVE
: s
= "LEAVE"; break;
1034 case STATUS_ABORT
: s
= "ABORT"; break;
1035 case STATUS_NEWSIG
: s
= "NEWSIG"; break;
1036 case STATUS_GOODSIG
: s
= "GOODSIG"; break;
1037 case STATUS_SIGEXPIRED
: s
= "SIGEXPIRED"; break;
1038 case STATUS_KEYREVOKED
: s
= "KEYREVOKED"; break;
1039 case STATUS_BADSIG
: s
= "BADSIG"; break;
1040 case STATUS_ERRSIG
: s
= "ERRSIG"; break;
1041 case STATUS_BADARMOR
: s
= "BADARMOR"; break;
1042 case STATUS_RSA_OR_IDEA
: s
= "RSA_OR_IDEA"; break;
1043 case STATUS_TRUST_UNDEFINED
: s
= "TRUST_UNDEFINED"; break;
1044 case STATUS_TRUST_NEVER
: s
= "TRUST_NEVER"; break;
1045 case STATUS_TRUST_MARGINAL
: s
= "TRUST_MARGINAL"; break;
1046 case STATUS_TRUST_FULLY
: s
= "TRUST_FULLY"; break;
1047 case STATUS_TRUST_ULTIMATE
: s
= "TRUST_ULTIMATE"; break;
1048 case STATUS_GET_BOOL
: s
= "GET_BOOL"; break;
1049 case STATUS_GET_LINE
: s
= "GET_LINE"; break;
1050 case STATUS_GET_HIDDEN
: s
= "GET_HIDDEN"; break;
1051 case STATUS_GOT_IT
: s
= "GOT_IT"; break;
1052 case STATUS_SHM_INFO
: s
= "SHM_INFO"; break;
1053 case STATUS_SHM_GET
: s
= "SHM_GET"; break;
1054 case STATUS_SHM_GET_BOOL
: s
= "SHM_GET_BOOL"; break;
1055 case STATUS_SHM_GET_HIDDEN
: s
= "SHM_GET_HIDDEN"; break;
1056 case STATUS_NEED_PASSPHRASE
: s
= "NEED_PASSPHRASE"; break;
1057 case STATUS_VALIDSIG
: s
= "VALIDSIG"; break;
1058 case STATUS_SIG_ID
: s
= "SIG_ID"; break;
1059 case STATUS_ENC_TO
: s
= "ENC_TO"; break;
1060 case STATUS_NODATA
: s
= "NODATA"; break;
1061 case STATUS_BAD_PASSPHRASE
: s
= "BAD_PASSPHRASE"; break;
1062 case STATUS_NO_PUBKEY
: s
= "NO_PUBKEY"; break;
1063 case STATUS_NO_SECKEY
: s
= "NO_SECKEY"; break;
1064 case STATUS_NEED_PASSPHRASE_SYM
: s
= "NEED_PASSPHRASE_SYM"; break;
1065 case STATUS_DECRYPTION_FAILED
: s
= "DECRYPTION_FAILED"; break;
1066 case STATUS_DECRYPTION_OKAY
: s
= "DECRYPTION_OKAY"; break;
1067 case STATUS_MISSING_PASSPHRASE
: s
= "MISSING_PASSPHRASE"; break;
1068 case STATUS_GOOD_PASSPHRASE
: s
= "GOOD_PASSPHRASE"; break;
1069 case STATUS_GOODMDC
: s
= "GOODMDC"; break;
1070 case STATUS_BADMDC
: s
= "BADMDC"; break;
1071 case STATUS_ERRMDC
: s
= "ERRMDC"; break;
1072 case STATUS_IMPORTED
: s
= "IMPORTED"; break;
1073 case STATUS_IMPORT_OK
: s
= "IMPORT_OK"; break;
1074 case STATUS_IMPORT_RES
: s
= "IMPORT_RES"; break;
1075 case STATUS_FILE_START
: s
= "FILE_START"; break;
1076 case STATUS_FILE_DONE
: s
= "FILE_DONE"; break;
1077 case STATUS_FILE_ERROR
: s
= "FILE_ERROR"; break;
1078 case STATUS_BEGIN_DECRYPTION
:s
= "BEGIN_DECRYPTION"; break;
1079 case STATUS_END_DECRYPTION
: s
= "END_DECRYPTION"; break;
1080 case STATUS_BEGIN_ENCRYPTION
:s
= "BEGIN_ENCRYPTION"; break;
1081 case STATUS_END_ENCRYPTION
: s
= "END_ENCRYPTION"; break;
1082 case STATUS_DELETE_PROBLEM
: s
= "DELETE_PROBLEM"; break;
1083 case STATUS_PROGRESS
: s
= "PROGRESS"; break;
1084 case STATUS_SIG_CREATED
: s
= "SIG_CREATED"; break;
1085 case STATUS_SESSION_KEY
: s
= "SESSION_KEY"; break;
1086 case STATUS_NOTATION_NAME
: s
= "NOTATION_NAME" ; break;
1087 case STATUS_NOTATION_DATA
: s
= "NOTATION_DATA" ; break;
1088 case STATUS_POLICY_URL
: s
= "POLICY_URL" ; break;
1089 case STATUS_BEGIN_STREAM
: s
= "BEGIN_STREAM"; break;
1090 case STATUS_END_STREAM
: s
= "END_STREAM"; break;
1091 case STATUS_KEY_CREATED
: s
= "KEY_CREATED"; break;
1092 case STATUS_UNEXPECTED
: s
= "UNEXPECTED"; break;
1093 case STATUS_INV_RECP
: s
= "INV_RECP"; break;
1094 case STATUS_NO_RECP
: s
= "NO_RECP"; break;
1095 case STATUS_ALREADY_SIGNED
: s
= "ALREADY_SIGNED"; break;
1096 case STATUS_EXPSIG
: s
= "EXPSIG"; break;
1097 case STATUS_EXPKEYSIG
: s
= "EXPKEYSIG"; break;
1098 case STATUS_TRUNCATED
: s
= "TRUNCATED"; break;
1099 case STATUS_ERROR
: s
= "ERROR"; break;
1100 case STATUS_IMPORT_PROBLEM
: s
= "IMPORT_PROBLEM"; break;
1101 default: s
= "?"; break;
1108 gpgsm_status2 (ctrl_t ctrl
, int no
, ...)
1110 gpg_error_t err
= 0;
1114 va_start (arg_ptr
, no
);
1116 if (ctrl
->no_server
&& ctrl
->status_fd
== -1)
1117 ; /* No status wanted. */
1118 else if (ctrl
->no_server
)
1122 if (ctrl
->status_fd
== 1)
1124 else if (ctrl
->status_fd
== 2)
1127 statusfp
= fdopen (ctrl
->status_fd
, "w");
1131 log_fatal ("can't open fd %d for status output: %s\n",
1132 ctrl
->status_fd
, strerror(errno
));
1136 fputs ("[GNUPG:] ", statusfp
);
1137 fputs (get_status_string (no
), statusfp
);
1139 while ( (text
= va_arg (arg_ptr
, const char*) ))
1141 putc ( ' ', statusfp
);
1142 for (; *text
; text
++)
1145 fputs ( "\\n", statusfp
);
1146 else if (*text
== '\r')
1147 fputs ( "\\r", statusfp
);
1149 putc ( *(const byte
*)text
, statusfp
);
1152 putc ('\n', statusfp
);
1157 assuan_context_t ctx
= ctrl
->server_local
->assuan_ctx
;
1163 while ( (text
= va_arg (arg_ptr
, const char *)) )
1170 for ( ; *text
&& n
< DIM (buf
)-2; n
++)
1174 err
= assuan_write_status (ctx
, get_status_string (no
), buf
);
1182 gpgsm_status (ctrl_t ctrl
, int no
, const char *text
)
1184 return gpgsm_status2 (ctrl
, no
, text
, NULL
);
1188 gpgsm_status_with_err_code (ctrl_t ctrl
, int no
, const char *text
,
1193 sprintf (buf
, "%u", (unsigned int)ec
);
1195 return gpgsm_status2 (ctrl
, no
, text
, buf
, NULL
);
1197 return gpgsm_status2 (ctrl
, no
, buf
, NULL
);